devacpi.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "io.h"
  15. #include "../port/error.h"
  16. #include "mp.h"
  17. #include "acpi.h"
  18. /*
  19. * ACPI 4.0 Support.
  20. * Still WIP.
  21. *
  22. * This driver locates tables and parses only the FADT
  23. * and the XSDT. All other tables are mapped and kept there
  24. * for the user-level interpreter.
  25. */
  26. #define l16get(p) (((p)[1]<<8)|(p)[0])
  27. #define l32get(p) (((uint32_t)l16get(p+2)<<16)|l16get(p))
  28. static Atable* acpifadt(uint8_t*, int);
  29. static Atable* acpitable(uint8_t*, int);
  30. static Atable* acpimadt(uint8_t*, int);
  31. static Atable* acpimsct(uint8_t*, int);
  32. static Atable* acpisrat(uint8_t*, int);
  33. static Atable* acpislit(uint8_t*, int);
  34. #pragma varargck type "G" Gas*
  35. static Cmdtab ctls[] =
  36. {
  37. {CMregion, "region", 6},
  38. {CMgpe, "gpe", 3},
  39. };
  40. static Dirtab acpidir[]={
  41. ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
  42. "acpictl", {Qctl}, 0, 0666,
  43. "acpitbl", {Qtbl}, 0, 0444,
  44. "acpiregio", {Qio}, 0, 0666,
  45. };
  46. /*
  47. * The DSDT is always given to the user interpreter.
  48. * Tables listed here are also loaded from the XSDT:
  49. * MSCT, MADT, and FADT are processed by us, because they are
  50. * required to do early initialization before we have user processes.
  51. * Other tables are given to the user level interpreter for
  52. * execution.
  53. */
  54. static Parse ptables[] =
  55. {
  56. "FACP", acpifadt,
  57. "APIC", acpimadt,
  58. "SRAT", acpisrat,
  59. "SLIT", acpislit,
  60. "MSCT", acpimsct,
  61. "SSDT", acpitable,
  62. };
  63. static Facs* facs; /* Firmware ACPI control structure */
  64. static Fadt fadt; /* Fixed ACPI description. To reach ACPI registers */
  65. static Xsdt* xsdt; /* XSDT table */
  66. static Atable* tfirst; /* loaded DSDT/SSDT/... tables */
  67. static Atable* tlast; /* pointer to last table */
  68. static Madt* apics; /* APIC info */
  69. static Srat* srat; /* System resource affinity, used by physalloc */
  70. static Slit* slit; /* System locality information table used by the scheduler */
  71. static Msct* msct; /* Maximum system characteristics table */
  72. static Reg* reg; /* region used for I/O */
  73. static Gpe* gpes; /* General purpose events */
  74. static int ngpes;
  75. static char* regnames[] = {
  76. "mem", "io", "pcicfg", "embed",
  77. "smb", "cmos", "pcibar",
  78. };
  79. static char*
  80. acpiregstr(int id)
  81. {
  82. static char buf[20]; /* BUG */
  83. if(id >= 0 && id < nelem(regnames))
  84. return regnames[id];
  85. seprint(buf, buf+sizeof(buf), "spc:%#x", id);
  86. return buf;
  87. }
  88. static int
  89. acpiregid(char *s)
  90. {
  91. int i;
  92. for(i = 0; i < nelem(regnames); i++)
  93. if(strcmp(regnames[i], s) == 0)
  94. return i;
  95. return -1;
  96. }
  97. static uint64_t
  98. l64get(uint8_t* p)
  99. {
  100. /*
  101. * Doing this as a define
  102. * #define l64get(p) (((u64int)l32get(p+4)<<32)|l32get(p))
  103. * causes 8c to abort with "out of fixed registers" in
  104. * rsdlink() below.
  105. */
  106. return (((uint64_t)l32get(p+4)<<32)|l32get(p));
  107. }
  108. static uint8_t
  109. mget8(uintptr_t p, void *j)
  110. {
  111. uint8_t *cp = (uint8_t*)p;
  112. return *cp;
  113. }
  114. static void
  115. mset8(uintptr_t p, uint8_t v, void *j)
  116. {
  117. uint8_t *cp = (uint8_t*)p;
  118. *cp = v;
  119. }
  120. static uint16_t
  121. mget16(uintptr_t p, void *j)
  122. {
  123. uint16_t *cp = (uint16_t*)p;
  124. return *cp;
  125. }
  126. static void
  127. mset16(uintptr_t p, uint16_t v, void *j)
  128. {
  129. uint16_t *cp = (uint16_t*)p;
  130. *cp = v;
  131. }
  132. static uint32_t
  133. mget32(uintptr_t p, void *j)
  134. {
  135. uint32_t *cp = (uint32_t*)p;
  136. return *cp;
  137. }
  138. static void
  139. mset32(uintptr_t p, uint32_t v, void *j)
  140. {
  141. uint32_t *cp = (uint32_t*)p;
  142. *cp = v;
  143. }
  144. static uint64_t
  145. mget64(uintptr_t p, void *j)
  146. {
  147. uint64_t *cp = (uint64_t*)p;
  148. return *cp;
  149. }
  150. static void
  151. mset64(uintptr_t p, uint64_t v, void *j)
  152. {
  153. uint64_t *cp = (uint64_t*)p;
  154. *cp = v;
  155. }
  156. static uint8_t
  157. ioget8(uintptr_t p, void *j)
  158. {
  159. return inb(p);
  160. }
  161. static void
  162. ioset8(uintptr_t p, uint8_t v, void *j)
  163. {
  164. outb(p, v);
  165. }
  166. static uint16_t
  167. ioget16(uintptr_t p, void *j)
  168. {
  169. return ins(p);
  170. }
  171. static void
  172. ioset16(uintptr_t p, uint16_t v, void *j)
  173. {
  174. outs(p, v);
  175. }
  176. static uint32_t
  177. ioget32(uintptr_t p, void *j)
  178. {
  179. return inl(p);
  180. }
  181. static void
  182. ioset32(uintptr_t p, uint32_t v, void *j)
  183. {
  184. outl(p, v);
  185. }
  186. static uint8_t
  187. cfgget8(uintptr_t p, void* r)
  188. {
  189. Reg *ro = r;
  190. Pcidev d;
  191. d.tbdf = ro->tbdf;
  192. return pcicfgr8(&d, p);
  193. }
  194. static void
  195. cfgset8(uintptr_t p, uint8_t v, void* r)
  196. {
  197. Reg *ro = r;
  198. Pcidev d;
  199. d.tbdf = ro->tbdf;
  200. pcicfgw8(&d, p, v);
  201. }
  202. static uint16_t
  203. cfgget16(uintptr_t p, void* r)
  204. {
  205. Reg *ro = r;
  206. Pcidev d;
  207. d.tbdf = ro->tbdf;
  208. return pcicfgr16(&d, p);
  209. }
  210. static void
  211. cfgset16(uintptr_t p, uint16_t v, void* r)
  212. {
  213. Reg *ro = r;
  214. Pcidev d;
  215. d.tbdf = ro->tbdf;
  216. pcicfgw16(&d, p, v);
  217. }
  218. static uint32_t
  219. cfgget32(uintptr_t p, void* r)
  220. {
  221. Reg *ro = r;
  222. Pcidev d;
  223. d.tbdf = ro->tbdf;
  224. return pcicfgr32(&d, p);
  225. }
  226. static void
  227. cfgset32(uintptr_t p, uint32_t v, void* r)
  228. {
  229. Reg *ro = r;
  230. Pcidev d;
  231. d.tbdf = ro->tbdf;
  232. pcicfgw32(&d, p, v);
  233. }
  234. static Regio memio =
  235. {
  236. nil,
  237. mget8, mset8, mget16, mset16,
  238. mget32, mset32, mget64, mset64
  239. };
  240. static Regio ioio =
  241. {
  242. nil,
  243. ioget8, ioset8, ioget16, ioset16,
  244. ioget32, ioset32, nil, nil
  245. };
  246. static Regio cfgio =
  247. {
  248. nil,
  249. cfgget8, cfgset8, cfgget16, cfgset16,
  250. cfgget32, cfgset32, nil, nil
  251. };
  252. /*
  253. * Copy memory, 1/2/4/8-bytes at a time, to/from a region.
  254. */
  255. static int32_t
  256. regcpy(Regio *dio, uintptr_t da, Regio *sio, uintptr_t sa, int32_t len,
  257. int align)
  258. {
  259. int n, i;
  260. DBG("regcpy %#ullx %#ullx %#ulx %#ux\n", da, sa, len, align);
  261. if((len%align) != 0)
  262. print("regcpy: bug: copy not aligned. truncated\n");
  263. n = len/align;
  264. for(i = 0; i < n; i++){
  265. switch(align){
  266. case 1:
  267. DBG("cpy8 %#p %#p\n", da, sa);
  268. dio->set8(da, sio->get8(sa, sio->arg), dio->arg);
  269. break;
  270. case 2:
  271. DBG("cpy16 %#p %#p\n", da, sa);
  272. dio->set16(da, sio->get16(sa, sio->arg), dio->arg);
  273. break;
  274. case 4:
  275. DBG("cpy32 %#p %#p\n", da, sa);
  276. dio->set32(da, sio->get32(sa, sio->arg), dio->arg);
  277. break;
  278. case 8:
  279. DBG("cpy64 %#p %#p\n", da, sa);
  280. // dio->set64(da, sio->get64(sa, sio->arg), dio->arg);
  281. break;
  282. default:
  283. panic("regcpy: align bug");
  284. }
  285. da += align;
  286. sa += align;
  287. }
  288. return n*align;
  289. }
  290. /*
  291. * Perform I/O within region in access units of accsz bytes.
  292. * All units in bytes.
  293. */
  294. static int32_t
  295. regio(Reg *r, void *p, uint32_t len, uintptr_t off, int iswr)
  296. {
  297. Regio rio;
  298. uintptr_t rp;
  299. DBG("reg%s %s %#p %#ullx %#lx sz=%d\n",
  300. iswr ? "out" : "in", r->name, p, off, len, r->accsz);
  301. rp = 0;
  302. if(off + len > r->len){
  303. print("regio: access outside limits");
  304. len = r->len - off;
  305. }
  306. if(len <= 0){
  307. print("regio: zero len\n");
  308. return 0;
  309. }
  310. switch(r->spc){
  311. case Rsysmem:
  312. // XXX should map only what we are going to use
  313. // A region might be too large.
  314. if(r->p == nil)
  315. r->p = vmap(r->base, len);
  316. if(r->p == nil)
  317. error("regio: vmap failed");
  318. rp = (uintptr_t)r->p + off;
  319. rio = memio;
  320. break;
  321. case Rsysio:
  322. rp = r->base + off;
  323. rio = ioio;
  324. break;
  325. case Rpcicfg:
  326. rp = r->base + off;
  327. rio = cfgio;
  328. rio.arg = r;
  329. break;
  330. case Rpcibar:
  331. case Rembed:
  332. case Rsmbus:
  333. case Rcmos:
  334. case Ripmi:
  335. case Rfixedhw:
  336. print("regio: reg %s not supported\n", acpiregstr(r->spc));
  337. error("region not supported");
  338. }
  339. if(iswr)
  340. regcpy(&rio, rp, &memio, (uintptr_t)p, len, r->accsz);
  341. else
  342. regcpy(&memio, (uintptr_t)p, &rio, rp, len, r->accsz);
  343. return len;
  344. }
  345. static Atable*
  346. newtable(uint8_t *p)
  347. {
  348. Atable *t;
  349. Sdthdr *h;
  350. t = malloc(sizeof(Atable));
  351. if(t == nil)
  352. panic("no memory for more aml tables");
  353. t->tbl = p;
  354. h = (Sdthdr*)t->tbl;
  355. t->is64 = h->rev >= 2;
  356. t->dlen = l32get(h->length) - Sdthdrsz;
  357. memmove(t->sig, h->sig, sizeof(h->sig));
  358. t->sig[sizeof(t->sig)-1] = 0;
  359. memmove(t->oemid, h->oemid, sizeof(h->oemid));
  360. t->oemtblid[sizeof(t->oemtblid)-1] = 0;
  361. memmove(t->oemtblid, h->oemtblid, sizeof(h->oemtblid));
  362. t->oemtblid[sizeof(t->oemtblid)-1] = 0;
  363. t->next = nil;
  364. if(tfirst == nil)
  365. tfirst = tlast = t;
  366. else{
  367. tlast->next = t;
  368. tlast = t;
  369. }
  370. return t;
  371. }
  372. static void*
  373. sdtchecksum(void* addr, int len)
  374. {
  375. uint8_t *p, sum;
  376. sum = 0;
  377. for(p = addr; len-- > 0; p++)
  378. sum += *p;
  379. if(sum == 0)
  380. return addr;
  381. return nil;
  382. }
  383. static void *
  384. sdtmap(uintptr_t pa, int *n, int cksum)
  385. {
  386. Sdthdr* sdt;
  387. sdt = vmap(pa, sizeof(Sdthdr));
  388. if(sdt == nil){
  389. DBG("acpi: vmap1: nil\n");
  390. return nil;
  391. }
  392. *n = l32get(sdt->length);
  393. vunmap(sdt, sizeof(Sdthdr));
  394. if((sdt = vmap(pa, *n)) == nil){
  395. DBG("acpi: nil vmap\n");
  396. return nil;
  397. }
  398. if(cksum != 0 && sdtchecksum(sdt, *n) == nil){
  399. DBG("acpi: SDT: bad checksum\n");
  400. vunmap(sdt, sizeof(Sdthdr));
  401. return nil;
  402. }
  403. return sdt;
  404. }
  405. static int
  406. loadfacs(uintptr_t pa)
  407. {
  408. int n;
  409. facs = sdtmap(pa, &n, 0);
  410. if(facs == nil)
  411. return -1;
  412. if(memcmp(facs, "FACS", 4) != 0){
  413. vunmap(facs, n);
  414. facs = nil;
  415. return -1;
  416. }
  417. /* no unmap */
  418. DBG("acpi: facs: hwsig: %#ux\n", facs->hwsig);
  419. DBG("acpi: facs: wakingv: %#ux\n", facs->wakingv);
  420. DBG("acpi: facs: flags: %#ux\n", facs->flags);
  421. DBG("acpi: facs: glock: %#ux\n", facs->glock);
  422. DBG("acpi: facs: xwakingv: %#llux\n", facs->xwakingv);
  423. DBG("acpi: facs: vers: %#ux\n", facs->vers);
  424. DBG("acpi: facs: ospmflags: %#ux\n", facs->ospmflags);
  425. return 0;
  426. }
  427. static void
  428. loaddsdt(uintptr_t pa)
  429. {
  430. int n;
  431. uint8_t *dsdtp;
  432. dsdtp = sdtmap(pa, &n, 1);
  433. if(dsdtp == nil)
  434. return;
  435. if(acpitable(dsdtp, n) == nil)
  436. vunmap(dsdtp, n);
  437. }
  438. static void
  439. gasget(Gas *gas, uint8_t *p)
  440. {
  441. gas->spc = p[0];
  442. gas->len = p[1];
  443. gas->off = p[2];
  444. gas->accsz = p[3];
  445. gas->addr = l64get(p+4);
  446. }
  447. static void
  448. dumpfadt(Fadt *fp)
  449. {
  450. if(DBGFLG == 0)
  451. return;
  452. DBG("acpi: fadt: facs: %#ux\n", fp->facs);
  453. DBG("acpi: fadt: dsdt: %#ux\n", fp->dsdt);
  454. DBG("acpi: fadt: pmprofile: %#ux\n", fp->pmprofile);
  455. DBG("acpi: fadt: sciint: %#ux\n", fp->sciint);
  456. DBG("acpi: fadt: smicmd: %#ux\n", fp->smicmd);
  457. DBG("acpi: fadt: acpienable: %#ux\n", fp->acpienable);
  458. DBG("acpi: fadt: acpidisable: %#ux\n", fp->acpidisable);
  459. DBG("acpi: fadt: s4biosreq: %#ux\n", fp->s4biosreq);
  460. DBG("acpi: fadt: pstatecnt: %#ux\n", fp->pstatecnt);
  461. DBG("acpi: fadt: pm1aevtblk: %#ux\n", fp->pm1aevtblk);
  462. DBG("acpi: fadt: pm1bevtblk: %#ux\n", fp->pm1bevtblk);
  463. DBG("acpi: fadt: pm1acntblk: %#ux\n", fp->pm1acntblk);
  464. DBG("acpi: fadt: pm1bcntblk: %#ux\n", fp->pm1bcntblk);
  465. DBG("acpi: fadt: pm2cntblk: %#ux\n", fp->pm2cntblk);
  466. DBG("acpi: fadt: pmtmrblk: %#ux\n", fp->pmtmrblk);
  467. DBG("acpi: fadt: gpe0blk: %#ux\n", fp->gpe0blk);
  468. DBG("acpi: fadt: gpe1blk: %#ux\n", fp->gpe1blk);
  469. DBG("acpi: fadt: pm1evtlen: %#ux\n", fp->pm1evtlen);
  470. DBG("acpi: fadt: pm1cntlen: %#ux\n", fp->pm1cntlen);
  471. DBG("acpi: fadt: pm2cntlen: %#ux\n", fp->pm2cntlen);
  472. DBG("acpi: fadt: pmtmrlen: %#ux\n", fp->pmtmrlen);
  473. DBG("acpi: fadt: gpe0blklen: %#ux\n", fp->gpe0blklen);
  474. DBG("acpi: fadt: gpe1blklen: %#ux\n", fp->gpe1blklen);
  475. DBG("acpi: fadt: gp1base: %#ux\n", fp->gp1base);
  476. DBG("acpi: fadt: cstcnt: %#ux\n", fp->cstcnt);
  477. DBG("acpi: fadt: plvl2lat: %#ux\n", fp->plvl2lat);
  478. DBG("acpi: fadt: plvl3lat: %#ux\n", fp->plvl3lat);
  479. DBG("acpi: fadt: flushsz: %#ux\n", fp->flushsz);
  480. DBG("acpi: fadt: flushstride: %#ux\n", fp->flushstride);
  481. DBG("acpi: fadt: dutyoff: %#ux\n", fp->dutyoff);
  482. DBG("acpi: fadt: dutywidth: %#ux\n", fp->dutywidth);
  483. DBG("acpi: fadt: dayalrm: %#ux\n", fp->dayalrm);
  484. DBG("acpi: fadt: monalrm: %#ux\n", fp->monalrm);
  485. DBG("acpi: fadt: century: %#ux\n", fp->century);
  486. DBG("acpi: fadt: iapcbootarch: %#ux\n", fp->iapcbootarch);
  487. DBG("acpi: fadt: flags: %#ux\n", fp->flags);
  488. DBG("acpi: fadt: resetreg: %G\n", &fp->resetreg);
  489. DBG("acpi: fadt: resetval: %#ux\n", fp->resetval);
  490. DBG("acpi: fadt: xfacs: %#llux\n", fp->xfacs);
  491. DBG("acpi: fadt: xdsdt: %#llux\n", fp->xdsdt);
  492. DBG("acpi: fadt: xpm1aevtblk: %G\n", &fp->xpm1aevtblk);
  493. DBG("acpi: fadt: xpm1bevtblk: %G\n", &fp->xpm1bevtblk);
  494. DBG("acpi: fadt: xpm1acntblk: %G\n", &fp->xpm1acntblk);
  495. DBG("acpi: fadt: xpm1bcntblk: %G\n", &fp->xpm1bcntblk);
  496. DBG("acpi: fadt: xpm2cntblk: %G\n", &fp->xpm2cntblk);
  497. DBG("acpi: fadt: xpmtmrblk: %G\n", &fp->xpmtmrblk);
  498. DBG("acpi: fadt: xgpe0blk: %G\n", &fp->xgpe0blk);
  499. DBG("acpi: fadt: xgpe1blk: %G\n", &fp->xgpe1blk);
  500. }
  501. static Atable*
  502. acpifadt(uint8_t *p, int i)
  503. {
  504. Fadt *fp;
  505. fp = &fadt;
  506. fp->facs = l32get(p + 36);
  507. fp->dsdt = l32get(p + 40);
  508. fp->pmprofile = p[45];
  509. fp->sciint = l16get(p+46);
  510. fp->smicmd = l32get(p+48);
  511. fp->acpienable = p[52];
  512. fp->acpidisable = p[53];
  513. fp->s4biosreq = p[54];
  514. fp->pstatecnt = p[55];
  515. fp->pm1aevtblk = l32get(p+56);
  516. fp->pm1bevtblk = l32get(p+60);
  517. fp->pm1acntblk = l32get(p+64);
  518. fp->pm1bcntblk = l32get(p+68);
  519. fp->pm2cntblk = l32get(p+72);
  520. fp->pmtmrblk = l32get(p+76);
  521. fp->gpe0blk = l32get(p+80);
  522. fp->gpe1blk = l32get(p+84);
  523. fp->pm1evtlen = p[88];
  524. fp->pm1cntlen = p[89];
  525. fp->pm2cntlen = p[90];
  526. fp->pmtmrlen = p[91];
  527. fp->gpe0blklen = p[92];
  528. fp->gpe1blklen = p[93];
  529. fp->gp1base = p[94];
  530. fp->cstcnt = p[95];
  531. fp->plvl2lat = l16get(p+96);
  532. fp->plvl3lat = l16get(p+98);
  533. fp->flushsz = l16get(p+100);
  534. fp->flushstride = l16get(p+102);
  535. fp->dutyoff = p[104];
  536. fp->dutywidth = p[105];
  537. fp->dayalrm = p[106];
  538. fp->monalrm = p[107];
  539. fp->century = p[108];
  540. fp->iapcbootarch = l16get(p+109);
  541. fp->flags = l32get(p+112);
  542. gasget(&fp->resetreg, p+116);
  543. fp->resetval = p[128];
  544. fp->xfacs = l64get(p+132);
  545. fp->xdsdt = l64get(p+140);
  546. gasget(&fp->xpm1aevtblk, p+148);
  547. gasget(&fp->xpm1bevtblk, p+160);
  548. gasget(&fp->xpm1acntblk, p+172);
  549. gasget(&fp->xpm1bcntblk, p+184);
  550. gasget(&fp->xpm2cntblk, p+196);
  551. gasget(&fp->xpmtmrblk, p+208);
  552. gasget(&fp->xgpe0blk, p+220);
  553. gasget(&fp->xgpe1blk, p+232);
  554. dumpfadt(fp);
  555. if(fp->xfacs != 0)
  556. loadfacs(fp->xfacs);
  557. else
  558. loadfacs(fp->facs);
  559. if(fp->xdsdt == ((uint64_t)fp->dsdt)) /* acpica */
  560. loaddsdt(fp->xdsdt);
  561. else
  562. loaddsdt(fp->dsdt);
  563. return nil; /* can be unmapped once parsed */
  564. }
  565. static void
  566. dumpmsct(Msct *msct)
  567. {
  568. Mdom *st;
  569. DBG("acpi: msct: %d doms %d clkdoms %#ullx maxpa\n",
  570. msct->ndoms, msct->nclkdoms, msct->maxpa);
  571. for(st = msct->dom; st != nil; st = st->next)
  572. DBG("\t[%d:%d] %d maxproc %#ullx maxmmem\n",
  573. st->start, st->end, st->maxproc, st->maxmem);
  574. DBG("\n");
  575. }
  576. /*
  577. * XXX: should perhaps update our idea of available memory.
  578. * Else we should remove this code.
  579. */
  580. static Atable*
  581. acpimsct(uint8_t *p, int len)
  582. {
  583. uint8_t *pe;
  584. Mdom **stl, *st;
  585. int off;
  586. msct = mallocz(sizeof(Msct), 1);
  587. msct->ndoms = l32get(p+40) + 1;
  588. msct->nclkdoms = l32get(p+44) + 1;
  589. msct->maxpa = l64get(p+48);
  590. msct->dom = nil;
  591. stl = &msct->dom;
  592. pe = p + len;
  593. off = l32get(p+36);
  594. for(p += off; p < pe; p += 22){
  595. st = mallocz(sizeof(Mdom), 1);
  596. st->next = nil;
  597. st->start = l32get(p+2);
  598. st->end = l32get(p+6);
  599. st->maxproc = l32get(p+10);
  600. st->maxmem = l64get(p+14);
  601. *stl = st;
  602. stl = &st->next;
  603. }
  604. dumpmsct(msct);
  605. return nil; /* can be unmapped once parsed */
  606. }
  607. static void
  608. dumpsrat(Srat *st)
  609. {
  610. DBG("acpi: srat:\n");
  611. for(; st != nil; st = st->next)
  612. switch(st->type){
  613. case SRlapic:
  614. DBG("\tlapic: dom %d apic %d sapic %d clk %d\n",
  615. st->lapic.dom, st->lapic.apic,
  616. st->lapic.sapic, st->lapic.clkdom);
  617. break;
  618. case SRmem:
  619. DBG("\tmem: dom %d %#ullx %#ullx %c%c\n",
  620. st->mem.dom, st->mem.addr, st->mem.len,
  621. st->mem.hplug?'h':'-',
  622. st->mem.nvram?'n':'-');
  623. break;
  624. case SRlx2apic:
  625. DBG("\tlx2apic: dom %d apic %d clk %d\n",
  626. st->lx2apic.dom, st->lx2apic.apic,
  627. st->lx2apic.clkdom);
  628. break;
  629. default:
  630. DBG("\t<unknown srat entry>\n");
  631. }
  632. DBG("\n");
  633. }
  634. static Atable*
  635. acpisrat(uint8_t *p, int len)
  636. {
  637. Srat **stl, *st;
  638. uint8_t *pe;
  639. int stlen, flags;
  640. if(srat != nil){
  641. print("acpi: two SRATs?\n");
  642. return nil;
  643. }
  644. stl = &srat;
  645. pe = p + len;
  646. for(p += 48; p < pe; p += stlen){
  647. st = mallocz(sizeof(Srat), 1);
  648. st->type = p[0];
  649. st->next = nil;
  650. stlen = p[1];
  651. switch(st->type){
  652. case SRlapic:
  653. st->lapic.dom = p[2] | p[9]<<24| p[10]<<16 | p[11]<<8;
  654. st->lapic.apic = p[3];
  655. st->lapic.sapic = p[8];
  656. st->lapic.clkdom = l32get(p+12);
  657. if(l32get(p+4) == 0){
  658. free(st);
  659. st = nil;
  660. }
  661. break;
  662. case SRmem:
  663. st->mem.dom = l32get(p+2);
  664. st->mem.addr = l64get(p+8);
  665. st->mem.len = l64get(p+16);
  666. flags = l32get(p+28);
  667. if((flags&1) == 0){ /* not enabled */
  668. free(st);
  669. st = nil;
  670. }else{
  671. st->mem.hplug = flags & 2;
  672. st->mem.nvram = flags & 4;
  673. }
  674. break;
  675. case SRlx2apic:
  676. st->lx2apic.dom = l32get(p+4);
  677. st->lx2apic.apic = l32get(p+8);
  678. st->lx2apic.clkdom = l32get(p+16);
  679. if(l32get(p+12) == 0){
  680. free(st);
  681. st = nil;
  682. }
  683. break;
  684. default:
  685. print("unknown SRAT structure\n");
  686. free(st);
  687. st = nil;
  688. }
  689. if(st != nil){
  690. *stl = st;
  691. stl = &st->next;
  692. }
  693. }
  694. dumpsrat(srat);
  695. return nil; /* can be unmapped once parsed */
  696. }
  697. static void
  698. dumpslit(Slit *sl)
  699. {
  700. int i;
  701. DBG("acpi slit:\n");
  702. for(i = 0; i < sl->rowlen*sl->rowlen; i++){
  703. DBG("slit: %ux\n", sl->e[i/sl->rowlen][i%sl->rowlen].dist);
  704. }
  705. }
  706. static int
  707. cmpslitent(const void* v1, const void* v2)
  708. {
  709. SlEntry *se1, *se2;
  710. se1 = v1;
  711. se2 = v2;
  712. return se1->dist - se2->dist;
  713. }
  714. static Atable*
  715. acpislit(uint8_t *p, int len)
  716. {
  717. uint8_t *pe;
  718. int i, j, k;
  719. SlEntry *se;
  720. pe = p + len;
  721. slit = malloc(sizeof(*slit));
  722. slit->rowlen = l64get(p+36);
  723. slit->e = malloc(slit->rowlen*sizeof(SlEntry*));
  724. for(i = 0; i < slit->rowlen; i++)
  725. slit->e[i] = malloc(sizeof(SlEntry)*slit->rowlen);
  726. i = 0;
  727. for(p += 44; p < pe; p++, i++){
  728. j = i/slit->rowlen;
  729. k = i%slit->rowlen;
  730. se = &slit->e[j][k];
  731. se->dom = k;
  732. se->dist = *p;
  733. }
  734. dumpslit(slit);
  735. for(i = 0; i < slit->rowlen; i++)
  736. qsort(slit->e[i], slit->rowlen, sizeof(slit->e[0][0]), cmpslitent);
  737. dumpslit(slit);
  738. return nil; /* can be unmapped once parsed */
  739. }
  740. uintmem
  741. acpimblocksize(uintmem addr, int *dom)
  742. {
  743. Srat *sl;
  744. for(sl = srat; sl != nil; sl = sl->next)
  745. if(sl->type == SRmem)
  746. if(sl->mem.addr <= addr && sl->mem.addr + sl->mem.len > addr){
  747. *dom = sl->mem.dom;
  748. return sl->mem.len - (addr - sl->mem.addr);
  749. }
  750. return 0;
  751. }
  752. /*
  753. * we use mp->machno (or index in Mach array) as the identifier,
  754. * but ACPI relies on the apic identifier.
  755. */
  756. int
  757. corecolor(int core)
  758. {
  759. Proc *up = machp()->externup;
  760. Srat *sl;
  761. static int colors[32];
  762. if(core < 0 || core >= MACHMAX)
  763. return -1;
  764. m = sys->machptr[core];
  765. if(m == nil)
  766. return -1;
  767. if(core >= 0 && core < nelem(colors) && colors[core] != 0)
  768. return colors[core] - 1;
  769. for(sl = srat; sl != nil; sl = sl->next)
  770. if(sl->type == SRlapic && sl->lapic.apic == m->apicno){
  771. if(core >= 0 && core < nelem(colors))
  772. colors[core] = 1 + sl->lapic.dom;
  773. return sl->lapic.dom;
  774. }
  775. return -1;
  776. }
  777. int
  778. pickcore(int mycolor, int index)
  779. {
  780. int color;
  781. int ncorepercol;
  782. if(slit == nil)
  783. return 0;
  784. ncorepercol = MACHMAX/slit->rowlen;
  785. color = slit->e[mycolor][index/ncorepercol].dom;
  786. return color * ncorepercol + index % ncorepercol;
  787. }
  788. static void
  789. dumpmadt(Madt *apics)
  790. {
  791. Apicst *st;
  792. DBG("acpi: madt lapic paddr %llux pcat %d:\n", apics->lapicpa, apics->pcat);
  793. for(st = apics->st; st != nil; st = st->next)
  794. switch(st->type){
  795. case ASlapic:
  796. DBG("\tlapic pid %d id %d\n", st->lapic.pid, st->lapic.id);
  797. break;
  798. case ASioapic:
  799. case ASiosapic:
  800. DBG("\tioapic id %d addr %#llux ibase %d\n",
  801. st->ioapic.id, st->ioapic.addr, st->ioapic.ibase);
  802. break;
  803. case ASintovr:
  804. DBG("\tintovr irq %d intr %d flags %#ux\n",
  805. st->intovr.irq, st->intovr.intr,st->intovr.flags);
  806. break;
  807. case ASnmi:
  808. DBG("\tnmi intr %d flags %#ux\n",
  809. st->nmi.intr, st->nmi.flags);
  810. break;
  811. case ASlnmi:
  812. DBG("\tlnmi pid %d lint %d flags %#ux\n",
  813. st->lnmi.pid, st->lnmi.lint, st->lnmi.flags);
  814. break;
  815. case ASlsapic:
  816. DBG("\tlsapic pid %d id %d eid %d puid %d puids %s\n",
  817. st->lsapic.pid, st->lsapic.id,
  818. st->lsapic.eid, st->lsapic.puid,
  819. st->lsapic.puids);
  820. break;
  821. case ASintsrc:
  822. DBG("\tintr type %d pid %d peid %d iosv %d intr %d %#x\n",
  823. st->type, st->intsrc.pid,
  824. st->intsrc.peid, st->intsrc.iosv,
  825. st->intsrc.intr, st->intsrc.flags);
  826. break;
  827. case ASlx2apic:
  828. DBG("\tlx2apic puid %d id %d\n", st->lx2apic.puid, st->lx2apic.id);
  829. break;
  830. case ASlx2nmi:
  831. DBG("\tlx2nmi puid %d intr %d flags %#ux\n",
  832. st->lx2nmi.puid, st->lx2nmi.intr, st->lx2nmi.flags);
  833. break;
  834. default:
  835. DBG("\t<unknown madt entry>\n");
  836. }
  837. DBG("\n");
  838. }
  839. static Atable*
  840. acpimadt(uint8_t *p, int len)
  841. {
  842. uint8_t *pe;
  843. Apicst *st, *l, **stl;
  844. int stlen, id;
  845. apics = mallocz(sizeof(Madt), 1);
  846. apics->lapicpa = l32get(p+36);
  847. apics->pcat = l32get(p+40);
  848. apics->st = nil;
  849. stl = &apics->st;
  850. pe = p + len;
  851. for(p += 44; p < pe; p += stlen){
  852. st = mallocz(sizeof(Apicst), 1);
  853. st->type = p[0];
  854. st->next = nil;
  855. stlen = p[1];
  856. switch(st->type){
  857. case ASlapic:
  858. st->lapic.pid = p[2];
  859. st->lapic.id = p[3];
  860. if(l32get(p+4) == 0){
  861. free(st);
  862. st = nil;
  863. }
  864. break;
  865. case ASioapic:
  866. st->ioapic.id = id = p[2];
  867. st->ioapic.addr = l32get(p+4);
  868. st->ioapic.ibase = l32get(p+8);
  869. /* iosapic overrides any ioapic entry for the same id */
  870. for(l = apics->st; l != nil; l = l->next)
  871. if(l->type == ASiosapic && l->iosapic.id == id){
  872. st->ioapic = l->iosapic;
  873. /* we leave it linked; could be removed */
  874. break;
  875. }
  876. break;
  877. case ASintovr:
  878. st->intovr.irq = p[3];
  879. st->intovr.intr = l32get(p+4);
  880. st->intovr.flags = l16get(p+8);
  881. break;
  882. case ASnmi:
  883. st->nmi.flags = l16get(p+2);
  884. st->nmi.intr = l32get(p+4);
  885. break;
  886. case ASlnmi:
  887. st->lnmi.pid = p[2];
  888. st->lnmi.flags = l16get(p+3);
  889. st->lnmi.lint = p[5];
  890. break;
  891. case ASladdr:
  892. /* This is for 64 bits, perhaps we should not
  893. * honor it on 32 bits.
  894. */
  895. apics->lapicpa = l64get(p+8);
  896. break;
  897. case ASiosapic:
  898. id = st->iosapic.id = p[2];
  899. st->iosapic.ibase = l32get(p+4);
  900. st->iosapic.addr = l64get(p+8);
  901. /* iosapic overrides any ioapic entry for the same id */
  902. for(l = apics->st; l != nil; l = l->next)
  903. if(l->type == ASioapic && l->ioapic.id == id){
  904. l->ioapic = st->iosapic;
  905. free(st);
  906. st = nil;
  907. break;
  908. }
  909. break;
  910. case ASlsapic:
  911. st->lsapic.pid = p[2];
  912. st->lsapic.id = p[3];
  913. st->lsapic.eid = p[4];
  914. st->lsapic.puid = l32get(p+12);
  915. if(l32get(p+8) == 0){
  916. free(st);
  917. st = nil;
  918. }else
  919. kstrdup(&st->lsapic.puids, (char*)p+16);
  920. break;
  921. case ASintsrc:
  922. st->intsrc.flags = l16get(p+2);
  923. st->type = p[4];
  924. st->intsrc.pid = p[5];
  925. st->intsrc.peid = p[6];
  926. st->intsrc.iosv = p[7];
  927. st->intsrc.intr = l32get(p+8);
  928. st->intsrc.any = l32get(p+12);
  929. break;
  930. case ASlx2apic:
  931. st->lx2apic.id = l32get(p+4);
  932. st->lx2apic.puid = l32get(p+12);
  933. if(l32get(p+8) == 0){
  934. free(st);
  935. st = nil;
  936. }
  937. break;
  938. case ASlx2nmi:
  939. st->lx2nmi.flags = l16get(p+2);
  940. st->lx2nmi.puid = l32get(p+4);
  941. st->lx2nmi.intr = p[8];
  942. break;
  943. default:
  944. print("unknown APIC structure\n");
  945. free(st);
  946. st = nil;
  947. }
  948. if(st != nil){
  949. *stl = st;
  950. stl = &st->next;
  951. }
  952. }
  953. dumpmadt(apics);
  954. return nil; /* can be unmapped once parsed */
  955. }
  956. /*
  957. * Map the table and keep it there.
  958. */
  959. static Atable*
  960. acpitable(uint8_t *p, int len)
  961. {
  962. if(len < Sdthdrsz)
  963. return nil;
  964. return newtable(p);
  965. }
  966. static void
  967. dumptable(char *sig, uint8_t *p, int l)
  968. {
  969. int n, i;
  970. if(DBGFLG > 1){
  971. DBG("%s @ %#p\n", sig, p);
  972. if(DBGFLG > 2)
  973. n = l;
  974. else
  975. n = 256;
  976. for(i = 0; i < n; i++){
  977. if((i % 16) == 0)
  978. DBG("%x: ", i);
  979. DBG(" %2.2ux", p[i]);
  980. if((i % 16) == 15)
  981. DBG("\n");
  982. }
  983. DBG("\n");
  984. DBG("\n");
  985. }
  986. }
  987. static char*
  988. seprinttable(char *s, char *e, Atable *t)
  989. {
  990. uint8_t *p;
  991. int i, n;
  992. p = (uint8_t*)t->tbl; /* include header */
  993. n = Sdthdrsz + t->dlen;
  994. s = seprint(s, e, "%s @ %#p\n", t->sig, p);
  995. for(i = 0; i < n; i++){
  996. if((i % 16) == 0)
  997. s = seprint(s, e, "%x: ", i);
  998. s = seprint(s, e, " %2.2ux", p[i]);
  999. if((i % 16) == 15)
  1000. s = seprint(s, e, "\n");
  1001. }
  1002. return seprint(s, e, "\n\n");
  1003. }
  1004. /*
  1005. * process xsdt table and load tables with sig, or all if nil.
  1006. * (XXX: should be able to search for sig, oemid, oemtblid)
  1007. */
  1008. static int
  1009. acpixsdtload(char *sig)
  1010. {
  1011. int i, l, t, unmap, found;
  1012. uintptr_t dhpa;
  1013. uint8_t *sdt;
  1014. char tsig[5];
  1015. found = 0;
  1016. for(i = 0; i < xsdt->len; i += xsdt->asize){
  1017. if(xsdt->asize == 8)
  1018. dhpa = l64get(xsdt->p+i);
  1019. else
  1020. dhpa = l32get(xsdt->p+i);
  1021. if((sdt = sdtmap(dhpa, &l, 1)) == nil)
  1022. continue;
  1023. unmap = 1;
  1024. memmove(tsig, sdt, 4);
  1025. tsig[4] = 0;
  1026. if(sig == nil || strcmp(sig, tsig) == 0){
  1027. DBG("acpi: %s addr %#p\n", tsig, sdt);
  1028. for(t = 0; t < nelem(ptables); t++)
  1029. if(strcmp(tsig, ptables[t].sig) == 0){
  1030. dumptable(tsig, sdt, l);
  1031. unmap = ptables[t].f(sdt, l) == nil;
  1032. found = 1;
  1033. break;
  1034. }
  1035. }
  1036. if(unmap)
  1037. vunmap(sdt, l);
  1038. }
  1039. return found;
  1040. }
  1041. static void*
  1042. rsdscan(uint8_t* addr, int len, char* signature)
  1043. {
  1044. int sl;
  1045. uint8_t *e, *p;
  1046. e = addr+len;
  1047. sl = strlen(signature);
  1048. for(p = addr; p+sl < e; p += 16){
  1049. if(memcmp(p, signature, sl))
  1050. continue;
  1051. return p;
  1052. }
  1053. return nil;
  1054. }
  1055. static void*
  1056. rsdsearch(char* signature)
  1057. {
  1058. uintptr_t p;
  1059. uint8_t *bda;
  1060. void *rsd;
  1061. /*
  1062. * Search for the data structure signature:
  1063. * 1) in the first KB of the EBDA;
  1064. * 2) in the BIOS ROM between 0xE0000 and 0xFFFFF.
  1065. */
  1066. if(strncmp((char*)KADDR(0xFFFD9), "EISA", 4) == 0){
  1067. bda = BIOSSEG(0x40);
  1068. if((p = (bda[0x0F]<<8)|bda[0x0E])){
  1069. if(rsd = rsdscan(KADDR(p), 1024, signature))
  1070. return rsd;
  1071. }
  1072. }
  1073. return rsdscan(BIOSSEG(0xE000), 0x20000, signature);
  1074. }
  1075. static void
  1076. acpirsdptr(void)
  1077. {
  1078. Rsdp *rsd;
  1079. int asize;
  1080. uintptr_t sdtpa;
  1081. if((rsd = rsdsearch("RSD PTR ")) == nil)
  1082. return;
  1083. assert(sizeof(Sdthdr) == 36);
  1084. DBG("acpi: RSD PTR@ %#p, physaddr %#ux length %ud %#llux rev %d\n",
  1085. rsd, l32get(rsd->raddr), l32get(rsd->length),
  1086. l64get(rsd->xaddr), rsd->revision);
  1087. if(rsd->revision >= 2){
  1088. if(sdtchecksum(rsd, 36) == nil){
  1089. DBG("acpi: RSD: bad checksum\n");
  1090. return;
  1091. }
  1092. sdtpa = l64get(rsd->xaddr);
  1093. asize = 8;
  1094. }
  1095. else{
  1096. if(sdtchecksum(rsd, 20) == nil){
  1097. DBG("acpi: RSD: bad checksum\n");
  1098. return;
  1099. }
  1100. sdtpa = l32get(rsd->raddr);
  1101. asize = 4;
  1102. }
  1103. /*
  1104. * process the RSDT or XSDT table.
  1105. */
  1106. xsdt = malloc(sizeof(Xsdt));
  1107. if(xsdt == nil){
  1108. DBG("acpi: malloc failed\n");
  1109. return;
  1110. }
  1111. if((xsdt->p = sdtmap(sdtpa, &xsdt->len, 1)) == nil){
  1112. DBG("acpi: sdtmap failed\n");
  1113. return;
  1114. }
  1115. if((xsdt->p[0] != 'R' && xsdt->p[0] != 'X') || memcmp(xsdt->p+1, "SDT", 3) != 0){
  1116. DBG("acpi: xsdt sig: %c%c%c%c\n",
  1117. xsdt->p[0], xsdt->p[1], xsdt->p[2], xsdt->p[3]);
  1118. free(xsdt);
  1119. xsdt = nil;
  1120. vunmap(xsdt, xsdt->len);
  1121. return;
  1122. }
  1123. xsdt->p += sizeof(Sdthdr);
  1124. xsdt->len -= sizeof(Sdthdr);
  1125. xsdt->asize = asize;
  1126. DBG("acpi: XSDT %#p\n", xsdt);
  1127. acpixsdtload(nil);
  1128. /* xsdt is kept and not unmapped */
  1129. }
  1130. static int
  1131. acpigen(Chan *c, char* d, Dirtab *tab, int ntab, int i, Dir *dp)
  1132. {
  1133. Qid qid;
  1134. if(i == DEVDOTDOT){
  1135. mkqid(&qid, Qdir, 0, QTDIR);
  1136. devdir(c, qid, ".", 0, eve, 0555, dp);
  1137. return 1;
  1138. }
  1139. i++; /* skip first element for . itself */
  1140. if(tab==0 || i>=ntab)
  1141. return -1;
  1142. tab += i;
  1143. qid = tab->qid;
  1144. qid.path &= ~Qdir;
  1145. qid.vers = 0;
  1146. devdir(c, qid, tab->name, tab->length, eve, tab->perm, dp);
  1147. return 1;
  1148. }
  1149. static int
  1150. Gfmt(Fmt* f)
  1151. {
  1152. static char* rnames[] = {
  1153. "mem", "io", "pcicfg", "embed",
  1154. "smb", "cmos", "pcibar", "ipmi"};
  1155. Gas *g;
  1156. g = va_arg(f->args, Gas*);
  1157. switch(g->spc){
  1158. case Rsysmem:
  1159. case Rsysio:
  1160. case Rembed:
  1161. case Rsmbus:
  1162. case Rcmos:
  1163. case Rpcibar:
  1164. case Ripmi:
  1165. fmtprint(f, "[%s ", rnames[g->spc]);
  1166. break;
  1167. case Rpcicfg:
  1168. fmtprint(f, "[pci ");
  1169. fmtprint(f, "dev %#ulx ", (uint32_t)(g->addr >> 32) & 0xFFFF);
  1170. fmtprint(f, "fn %#ulx ",
  1171. (uint32_t)(g->addr & 0xFFFF0000) >> 16);
  1172. fmtprint(f, "adr %#ulx ", (uint32_t)(g->addr &0xFFFF));
  1173. break;
  1174. case Rfixedhw:
  1175. fmtprint(f, "[hw ");
  1176. break;
  1177. default:
  1178. fmtprint(f, "[spc=%#ux ", g->spc);
  1179. }
  1180. return fmtprint(f, "off %d len %d addr %#ullx sz%d]",
  1181. g->off, g->len, g->addr, g->accsz);
  1182. }
  1183. static uint
  1184. getbanked(uintptr_t ra, uintptr_t rb, int sz)
  1185. {
  1186. uint r;
  1187. r = 0;
  1188. switch(sz){
  1189. case 1:
  1190. if(ra != 0)
  1191. r |= inb(ra);
  1192. if(rb != 0)
  1193. r |= inb(rb);
  1194. break;
  1195. case 2:
  1196. if(ra != 0)
  1197. r |= ins(ra);
  1198. if(rb != 0)
  1199. r |= ins(rb);
  1200. break;
  1201. case 4:
  1202. if(ra != 0)
  1203. r |= inl(ra);
  1204. if(rb != 0)
  1205. r |= inl(rb);
  1206. break;
  1207. default:
  1208. print("getbanked: wrong size\n");
  1209. }
  1210. return r;
  1211. }
  1212. static uint
  1213. setbanked(uintptr_t ra, uintptr_t rb, int sz, int v)
  1214. {
  1215. uint r;
  1216. r = -1;
  1217. switch(sz){
  1218. case 1:
  1219. if(ra != 0)
  1220. outb(ra, v);
  1221. if(rb != 0)
  1222. outb(rb, v);
  1223. break;
  1224. case 2:
  1225. if(ra != 0)
  1226. outs(ra, v);
  1227. if(rb != 0)
  1228. outs(rb, v);
  1229. break;
  1230. case 4:
  1231. if(ra != 0)
  1232. outl(ra, v);
  1233. if(rb != 0)
  1234. outl(rb, v);
  1235. break;
  1236. default:
  1237. print("setbanked: wrong size\n");
  1238. }
  1239. return r;
  1240. }
  1241. static uint
  1242. getpm1ctl(void)
  1243. {
  1244. return getbanked(fadt.pm1acntblk, fadt.pm1bcntblk, fadt.pm1cntlen);
  1245. }
  1246. static void
  1247. setpm1sts(uint v)
  1248. {
  1249. DBG("acpi: setpm1sts %#ux\n", v);
  1250. setbanked(fadt.pm1aevtblk, fadt.pm1bevtblk, fadt.pm1evtlen/2, v);
  1251. }
  1252. static uint
  1253. getpm1sts(void)
  1254. {
  1255. return getbanked(fadt.pm1aevtblk, fadt.pm1bevtblk, fadt.pm1evtlen/2);
  1256. }
  1257. static uint
  1258. getpm1en(void)
  1259. {
  1260. int sz;
  1261. sz = fadt.pm1evtlen/2;
  1262. return getbanked(fadt.pm1aevtblk+sz, fadt.pm1bevtblk+sz, sz);
  1263. }
  1264. static int
  1265. getgpeen(int n)
  1266. {
  1267. return inb(gpes[n].enio) & 1<<gpes[n].enbit;
  1268. }
  1269. static void
  1270. setgpeen(int n, uint v)
  1271. {
  1272. int old;
  1273. DBG("acpi: setgpe %d %d\n", n, v);
  1274. old = inb(gpes[n].enio);
  1275. if(v)
  1276. outb(gpes[n].enio, old | 1<<gpes[n].enbit);
  1277. else
  1278. outb(gpes[n].enio, old & ~(1<<gpes[n].enbit));
  1279. }
  1280. static void
  1281. clrgpests(int n)
  1282. {
  1283. outb(gpes[n].stsio, 1<<gpes[n].stsbit);
  1284. }
  1285. static uint
  1286. getgpests(int n)
  1287. {
  1288. return inb(gpes[n].stsio) & 1<<gpes[n].stsbit;
  1289. }
  1290. static void
  1291. acpiintr(Ureg* ureg, void *j)
  1292. {
  1293. int i;
  1294. uint sts, en;
  1295. print("acpi: intr\n");
  1296. for(i = 0; i < ngpes; i++)
  1297. if(getgpests(i)){
  1298. print("gpe %d on\n", i);
  1299. en = getgpeen(i);
  1300. setgpeen(i, 0);
  1301. clrgpests(i);
  1302. if(en != 0)
  1303. print("acpiitr: calling gpe %d\n", i);
  1304. // queue gpe for calling gpe->ho in the
  1305. // aml process.
  1306. // enable it again when it returns.
  1307. }
  1308. sts = getpm1sts();
  1309. en = getpm1en();
  1310. print("acpiitr: pm1sts %#ux pm1en %#ux\n", sts, en);
  1311. if(sts&en)
  1312. print("have enabled events\n");
  1313. if(sts&1)
  1314. print("power button\n");
  1315. // XXX serve other interrupts here.
  1316. setpm1sts(sts);
  1317. }
  1318. static void
  1319. initgpes(void)
  1320. {
  1321. int i, n0, n1;
  1322. n0 = fadt.gpe0blklen/2;
  1323. n1 = fadt.gpe1blklen/2;
  1324. ngpes = n0 + n1;
  1325. gpes = mallocz(sizeof(Gpe) * ngpes, 1);
  1326. for(i = 0; i < n0; i++){
  1327. gpes[i].nb = i;
  1328. gpes[i].stsbit = i&7;
  1329. gpes[i].stsio = fadt.gpe0blk + (i>>3);
  1330. gpes[i].enbit = (n0 + i)&7;
  1331. gpes[i].enio = fadt.gpe0blk + ((n0 + i)>>3);
  1332. }
  1333. for(i = 0; i + n0 < ngpes; i++){
  1334. gpes[i + n0].nb = fadt.gp1base + i;
  1335. gpes[i + n0].stsbit = i&7;
  1336. gpes[i + n0].stsio = fadt.gpe1blk + (i>>3);
  1337. gpes[i + n0].enbit = (n1 + i)&7;
  1338. gpes[i + n0].enio = fadt.gpe1blk + ((n1 + i)>>3);
  1339. }
  1340. for(i = 0; i < ngpes; i++){
  1341. setgpeen(i, 0);
  1342. clrgpests(i);
  1343. }
  1344. }
  1345. static void
  1346. acpiioalloc(uint addr, int len)
  1347. {
  1348. if(addr != 0)
  1349. ioalloc(addr, len, 0, "acpi");
  1350. }
  1351. int
  1352. acpiinit(void)
  1353. {
  1354. if(fadt.smicmd == 0){
  1355. fmtinstall('G', Gfmt);
  1356. acpirsdptr();
  1357. if(fadt.smicmd == 0)
  1358. return -1;
  1359. }
  1360. return 0;
  1361. }
  1362. static Chan*
  1363. acpiattach(char *spec)
  1364. {
  1365. int i;
  1366. /*
  1367. * This was written for the stock kernel.
  1368. * This code must use 64 registers to be acpi ready in nix.
  1369. */
  1370. if(1 || acpiinit() < 0)
  1371. error("no acpi");
  1372. /*
  1373. * should use fadt->xpm* and fadt->xgpe* registers for 64 bits.
  1374. * We are not ready in this kernel for that.
  1375. */
  1376. DBG("acpi io alloc\n");
  1377. acpiioalloc(fadt.smicmd, 1);
  1378. acpiioalloc(fadt.pm1aevtblk, fadt.pm1evtlen);
  1379. acpiioalloc(fadt.pm1bevtblk, fadt.pm1evtlen );
  1380. acpiioalloc(fadt.pm1acntblk, fadt.pm1cntlen);
  1381. acpiioalloc(fadt.pm1bcntblk, fadt.pm1cntlen);
  1382. acpiioalloc(fadt.pm2cntblk, fadt.pm2cntlen);
  1383. acpiioalloc(fadt.pmtmrblk, fadt.pmtmrlen);
  1384. acpiioalloc(fadt.gpe0blk, fadt.gpe0blklen);
  1385. acpiioalloc(fadt.gpe1blk, fadt.gpe1blklen);
  1386. DBG("acpi init gpes\n");
  1387. initgpes();
  1388. /*
  1389. * This starts ACPI, which may require we handle
  1390. * power mgmt events ourselves. Use with care.
  1391. */
  1392. DBG("acpi starting\n");
  1393. outb(fadt.smicmd, fadt.acpienable);
  1394. for(i = 0; i < 10; i++)
  1395. if(getpm1ctl() & Pm1SciEn)
  1396. break;
  1397. if(i == 10)
  1398. error("acpi: failed to enable\n");
  1399. if(fadt.sciint != 0)
  1400. intrenable(fadt.sciint, acpiintr, 0, BUSUNKNOWN, "acpi");
  1401. return devattach(L'α', spec);
  1402. }
  1403. static Walkqid*
  1404. acpiwalk(Chan *c, Chan *nc, char **name, int nname)
  1405. {
  1406. return devwalk(c, nc, name, nname, acpidir, nelem(acpidir), acpigen);
  1407. }
  1408. static int32_t
  1409. acpistat(Chan *c, uint8_t *dp, int32_t n)
  1410. {
  1411. return devstat(c, dp, n, acpidir, nelem(acpidir), acpigen);
  1412. }
  1413. static Chan*
  1414. acpiopen(Chan *c, int omode)
  1415. {
  1416. return devopen(c, omode, acpidir, nelem(acpidir), acpigen);
  1417. }
  1418. static void
  1419. acpiclose(Chan *c)
  1420. {
  1421. }
  1422. static char*ttext;
  1423. static int tlen;
  1424. static int32_t
  1425. acpiread(Chan *c, void *a, int32_t n, int64_t off)
  1426. {
  1427. int32_t q;
  1428. Atable *t;
  1429. char *ns, *s, *e, *ntext;
  1430. q = c->qid.path;
  1431. switch(q){
  1432. case Qdir:
  1433. return devdirread(c, a, n, acpidir, nelem(acpidir), acpigen);
  1434. case Qtbl:
  1435. if(ttext == nil){
  1436. tlen = 1024;
  1437. ttext = malloc(tlen);
  1438. if(ttext == nil){
  1439. print("acpi: no memory\n");
  1440. return 0;
  1441. }
  1442. s = ttext;
  1443. e = ttext + tlen;
  1444. strcpy(s, "no tables\n");
  1445. for(t = tfirst; t != nil; t = t->next){
  1446. ns = seprinttable(s, e, t);
  1447. while(ns == e - 1){
  1448. DBG("acpiread: allocated %d\n", tlen*2);
  1449. ntext = realloc(ttext, tlen*2);
  1450. if(ntext == nil)
  1451. panic("acpi: no memory\n");
  1452. s = ntext + (ttext - s);
  1453. ttext = ntext;
  1454. tlen *= 2;
  1455. e = ttext + tlen;
  1456. ns = seprinttable(s, e, t);
  1457. }
  1458. s = ns;
  1459. }
  1460. }
  1461. return readstr(off, a, n, ttext);
  1462. case Qio:
  1463. if(reg == nil)
  1464. error("region not configured");
  1465. return regio(reg, a, n, off, 0);
  1466. }
  1467. error(Eperm);
  1468. return -1;
  1469. }
  1470. static int32_t
  1471. acpiwrite(Chan *c, void *a, int32_t n, int64_t off)
  1472. {
  1473. Proc *up = machp()->externup;
  1474. Cmdtab *ct;
  1475. Cmdbuf *cb;
  1476. Reg *r;
  1477. uint rno, fun, dev, bus, i;
  1478. if(c->qid.path == Qio){
  1479. if(reg == nil)
  1480. error("region not configured");
  1481. return regio(reg, a, n, off, 1);
  1482. }
  1483. if(c->qid.path != Qctl)
  1484. error(Eperm);
  1485. cb = parsecmd(a, n);
  1486. if(waserror()){
  1487. free(cb);
  1488. nexterror();
  1489. }
  1490. ct = lookupcmd(cb, ctls, nelem(ctls));
  1491. DBG("acpi ctl %s\n", cb->f[0]);
  1492. switch(ct->index){
  1493. case CMregion:
  1494. r = reg;
  1495. if(r == nil){
  1496. r = smalloc(sizeof(Reg));
  1497. r->name = nil;
  1498. }
  1499. kstrdup(&r->name, cb->f[1]);
  1500. r->spc = acpiregid(cb->f[2]);
  1501. if(r->spc < 0){
  1502. free(r);
  1503. reg = nil;
  1504. error("bad region type");
  1505. }
  1506. if(r->spc == Rpcicfg || r->spc == Rpcibar){
  1507. rno = r->base>>Rpciregshift & Rpciregmask;
  1508. fun = r->base>>Rpcifunshift & Rpcifunmask;
  1509. dev = r->base>>Rpcidevshift & Rpcidevmask;
  1510. bus = r->base>>Rpcibusshift & Rpcibusmask;
  1511. r->tbdf = MKBUS(BusPCI, bus, dev, fun);
  1512. r->base = rno; /* register ~ our base addr */
  1513. }
  1514. r->base = strtoull(cb->f[3], nil, 0);
  1515. r->len = strtoull(cb->f[4], nil, 0);
  1516. r->accsz = strtoul(cb->f[5], nil, 0);
  1517. if(r->accsz < 1 || r->accsz > 4){
  1518. free(r);
  1519. reg = nil;
  1520. error("bad region access size");
  1521. }
  1522. reg = r;
  1523. DBG("region %s %s %llux %llux sz%d",
  1524. r->name, acpiregstr(r->spc), r->base, r->len, r->accsz);
  1525. break;
  1526. case CMgpe:
  1527. i = strtoul(cb->f[1], nil, 0);
  1528. if(i >= ngpes)
  1529. error("gpe out of range");
  1530. kstrdup(&gpes[i].obj, cb->f[2]);
  1531. DBG("gpe %d %s\n", i, gpes[i].obj);
  1532. setgpeen(i, 1);
  1533. break;
  1534. default:
  1535. panic("acpi: unknown ctl");
  1536. }
  1537. poperror();
  1538. free(cb);
  1539. return n;
  1540. }
  1541. Dev acpidevtab = {
  1542. L'α',
  1543. "acpi",
  1544. devreset,
  1545. devinit,
  1546. devshutdown,
  1547. acpiattach,
  1548. acpiwalk,
  1549. acpistat,
  1550. acpiopen,
  1551. devcreate,
  1552. acpiclose,
  1553. acpiread,
  1554. devbread,
  1555. acpiwrite,
  1556. devbwrite,
  1557. devremove,
  1558. devwstat,
  1559. };