devacpi.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  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 "apic.h"
  17. #include "mp.h"
  18. #include <acpi/acpica/acpi.h>
  19. enum
  20. {
  21. Sdthdrsz = 36, /* size of SDT header */
  22. Qdir = 0,
  23. Qctl,
  24. Qtbl,
  25. Qio,
  26. };
  27. #if 0
  28. static Cmdtab ctls[] =
  29. {
  30. {CMregion, "region", 6},
  31. {CMgpe, "gpe", 3},
  32. };
  33. #endif
  34. /*
  35. * This is the array of eyesores.
  36. * An Eyesore is an Interrupt Source Over Ride, which maps from
  37. * what they want to what it needs to be. You are not expected
  38. * to understand this.
  39. */
  40. static ACPI_MADT_INTERRUPT_OVERRIDE *eyesore;
  41. static int numeyesore;
  42. static Dirtab acpidir[]={
  43. ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
  44. "acpictl", {Qctl}, 0, 0666,
  45. "acpitbl", {Qtbl}, 0, 0444,
  46. "acpiregio", {Qio}, 0, 0666,
  47. };
  48. #if 0
  49. static char* regnames[] = {
  50. "mem", "io", "pcicfg", "embed",
  51. "smb", "cmos", "pcibar",
  52. };
  53. #endif
  54. static void *rsd;
  55. /*
  56. * we use mp->machno (or index in Mach array) as the identifier,
  57. * but ACPI relies on the apic identifier.
  58. */
  59. int
  60. corecolor(int core)
  61. {
  62. Mach *m;
  63. static int colors[32];
  64. if(core < 0 || core >= MACHMAX)
  65. return -1;
  66. m = sys->machptr[core];
  67. if(m == nil)
  68. return -1;
  69. if(core >= 0 && core < nelem(colors) && colors[core] != 0)
  70. return colors[core] - 1;
  71. return -1;
  72. }
  73. int
  74. pickcore(int mycolor, int index)
  75. {
  76. return 0;
  77. }
  78. static void*
  79. rsdscan(uint8_t* addr, int len, char* signature)
  80. {
  81. int sl;
  82. uint8_t *e, *p;
  83. e = addr+len;
  84. sl = strlen(signature);
  85. for(p = addr; p+sl < e; p += 16){
  86. if(memcmp(p, signature, sl))
  87. continue;
  88. return p;
  89. }
  90. return nil;
  91. }
  92. static void*
  93. rsdsearch(char* signature)
  94. {
  95. uintptr_t p;
  96. uint8_t *bda;
  97. void *rsd;
  98. /*
  99. * Search for the data structure signature:
  100. * 1) in the first KB of the EBDA;
  101. * 2) in the BIOS ROM between 0xE0000 and 0xFFFFF.
  102. */
  103. if(strncmp((char*)KADDR(0xFFFD9), "EISA", 4) == 0){
  104. bda = BIOSSEG(0x40);
  105. if((p = (bda[0x0F]<<8)|bda[0x0E])){
  106. if(rsd = rsdscan(KADDR(p), 1024, signature))
  107. return rsd;
  108. }
  109. }
  110. return rsdscan(BIOSSEG(0xE000), 0x20000, signature);
  111. }
  112. static void
  113. acpirsdptr(void)
  114. {
  115. rsd = rsdsearch("RSD PTR ");
  116. if (rsd == nil) {
  117. print("NO RSD PTR found\n");
  118. return;
  119. }
  120. print("Found RST PTR ta %p\n", rsd);
  121. #if 0
  122. assert(sizeof(Sdthdr) == 36);
  123. DBG("acpi: RSD PTR@ %#p, physaddr %#x length %u %#llux rev %d\n",
  124. rsd, l32get(rsd->raddr), l32get(rsd->length),
  125. l64get(rsd->xaddr), rsd->revision);
  126. if(rsd->revision >= 2){
  127. if(sdtchecksum(rsd, 36) == nil){
  128. DBG("acpi: RSD: bad checksum\n");
  129. return;
  130. }
  131. sdtpa = l64get(rsd->xaddr);
  132. asize = 8;
  133. }
  134. else{
  135. if(sdtchecksum(rsd, 20) == nil){
  136. DBG("acpi: RSD: bad checksum\n");
  137. return;
  138. }
  139. sdtpa = l32get(rsd->raddr);
  140. asize = 4;
  141. }
  142. /*
  143. * process the RSDT or XSDT table.
  144. */
  145. xsdt = malloc(sizeof(Xsdt));
  146. if(xsdt == nil){
  147. DBG("acpi: malloc failed\n");
  148. return;
  149. }
  150. if((xsdt->p = sdtmap(sdtpa, &xsdt->len, 1)) == nil){
  151. DBG("acpi: sdtmap failed\n");
  152. return;
  153. }
  154. if((xsdt->p[0] != 'R' && xsdt->p[0] != 'X') || memcmp(xsdt->p+1, "SDT", 3) != 0){
  155. DBG("acpi: xsdt sig: %c%c%c%c\n",
  156. xsdt->p[0], xsdt->p[1], xsdt->p[2], xsdt->p[3]);
  157. free(xsdt);
  158. xsdt = nil;
  159. vunmap(xsdt, xsdt->len);
  160. return;
  161. }
  162. xsdt->p += sizeof(Sdthdr);
  163. xsdt->len -= sizeof(Sdthdr);
  164. xsdt->asize = asize;
  165. DBG("acpi: XSDT %#p\n", xsdt);
  166. acpixsdtload(nil);
  167. /* xsdt is kept and not unmapped */
  168. #endif
  169. }
  170. static int
  171. acpigen(Chan *c, char* d, Dirtab *tab, int ntab, int i, Dir *dp)
  172. {
  173. Qid qid;
  174. if(i == DEVDOTDOT){
  175. mkqid(&qid, Qdir, 0, QTDIR);
  176. devdir(c, qid, ".", 0, eve, 0555, dp);
  177. return 1;
  178. }
  179. i++; /* skip first element for . itself */
  180. if(tab==0 || i>=ntab)
  181. return -1;
  182. tab += i;
  183. qid = tab->qid;
  184. qid.path &= ~Qdir;
  185. qid.vers = 0;
  186. devdir(c, qid, tab->name, tab->length, eve, tab->perm, dp);
  187. return 1;
  188. }
  189. ACPI_STATUS
  190. AcpiOsInitialize(void)
  191. {
  192. print("%s\n", __func__);
  193. acpirsdptr();
  194. return AE_OK;
  195. }
  196. ACPI_STATUS
  197. AcpiOsTerminate (
  198. void)
  199. {
  200. print("%s\n", __func__);
  201. return AE_OK;
  202. }
  203. /* run AML with one integer arg. */
  204. static int
  205. run_aml_arg(char *name, int val)
  206. {
  207. ACPI_OBJECT arg1;
  208. ACPI_OBJECT_LIST args;
  209. ACPI_STATUS as;
  210. arg1.Type = ACPI_TYPE_INTEGER;
  211. arg1.Integer.Value = 1;
  212. args.Count = 1;
  213. args.Pointer = &arg1;
  214. /* This does not work. Just leaving it here in case someone
  215. * else thinks it will.
  216. ACPI_STATUS as;
  217. ACPI_OBJECT arg[] = {
  218. {
  219. .Type = ACPI_TYPE_INTEGER,
  220. .Integer.Value = val
  221. }
  222. };
  223. ACPI_OBJECT_LIST args = {
  224. .Count = 1,
  225. .Pointer = arg
  226. };
  227. */
  228. as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, name, &args, NULL);
  229. print("run_aml_arg(%s, %d) returns %d\n", name, val, as);
  230. return ACPI_SUCCESS(as);
  231. }
  232. static int
  233. set_machine_mode(void)
  234. {
  235. /* we always enable the APIC. */
  236. return run_aml_arg("_PIC", 1);
  237. }
  238. void pi(int indent)
  239. {
  240. int i;
  241. for(i = 0; i < indent; i++)
  242. print(" ");
  243. }
  244. /* walk the whatever. Limited, right now. */
  245. static void
  246. objwalk(ACPI_OBJECT *p)
  247. {
  248. static int indent;
  249. int cnt;
  250. ACPI_OBJECT *e;
  251. pi(indent);
  252. switch(p->Type) {
  253. case 4: // ACPI_DESC_TYPE_STATE_PACKAGE:
  254. print("Package:\n");
  255. indent += 2;
  256. e = p->Package.Elements;
  257. for(cnt = 0; cnt < p->Package.Count; cnt++, e++){
  258. objwalk(e);
  259. }
  260. indent -= 2;
  261. print("\n");
  262. break;
  263. case 1:
  264. print("Integer:0x%llx", p->Integer.Value);
  265. break;
  266. default:
  267. print("Can't handle type %d\n", p->Type);
  268. break;
  269. }
  270. }
  271. static ACPI_STATUS
  272. resource(ACPI_RESOURCE *r, void *Context)
  273. {
  274. ACPI_RESOURCE_IRQ *i = &r->Data.Irq;
  275. print("\tACPI_RESOURCE_TYPE_%d: Length %d\n", r->Type, r->Length);
  276. if (r->Type != ACPI_RESOURCE_TYPE_IRQ)
  277. return 0;
  278. print("\t\tIRQ Triggering %d Polarity %d Sharable %d InterruptCount %d: ",
  279. i->Triggering, i->Polarity, i->Sharable, i->InterruptCount);
  280. for(int j = 0; j < i->InterruptCount; j++)
  281. print("%d,", i->Interrupts[j]);
  282. print("\n");
  283. /* assumptions: we assume apic 0 for now. This will need to be fixed.
  284. * We also just take the first interrupt.
  285. */
  286. uint32_t low = Im;
  287. switch (i->Polarity){
  288. case ACPI_ACTIVE_HIGH:
  289. low |= IPhigh;
  290. break;
  291. case ACPI_ACTIVE_LOW:
  292. low |= IPlow;
  293. break;
  294. case ACPI_ACTIVE_BOTH:
  295. low |= IPlow | IPhigh;
  296. break;
  297. default:
  298. print("BOTCH! i->Polarity is 0x%x and I don't do that\n", i->Polarity);
  299. break;
  300. }
  301. switch (i->Triggering) {
  302. case ACPI_LEVEL_SENSITIVE:
  303. low |= TMlevel;
  304. break;
  305. case ACPI_EDGE_SENSITIVE:
  306. low |= TMedge;
  307. break;
  308. default:
  309. print("BOTCH! i->Triggering is 0x%x and I don't do that\n", i->Triggering);
  310. break;
  311. }
  312. print("ACPICODE: ioapicintrinit(0xff, 0x%x, 0x%x, 0x%x, 0x%x\n", 1, i->Interrupts[0], i->Interrupts[0]<<2, low);
  313. return 0;
  314. }
  315. ACPI_STATUS
  316. device(ACPI_HANDLE Object,
  317. UINT32 NestingLevel,
  318. void *Context,
  319. void **ReturnValue)
  320. {
  321. ACPI_STATUS as;
  322. ACPI_DEVICE_INFO *info;
  323. as = AcpiGetObjectInfo(Object, &info);
  324. print("as is %d\n", as);
  325. if (!ACPI_SUCCESS(as))
  326. return 0;
  327. ACPI_BUFFER out;
  328. out.Length = ACPI_ALLOCATE_BUFFER;
  329. out.Pointer = nil;
  330. char n[5];
  331. memmove(n, &info->Name, sizeof(info->Name));
  332. n[4] = 0;
  333. print("%s\n", n);
  334. as = AcpiGetIrqRoutingTable(Object, &out);
  335. print("get the PRT: %d\n", as);
  336. print("Length is %u ptr is %p\n", out.Length, out.Pointer);
  337. if (ACPI_SUCCESS(as)) {
  338. void *p = (void *)out.Pointer;
  339. while(((ACPI_PCI_ROUTING_TABLE*)p)->Length > 0) {
  340. ACPI_PCI_ROUTING_TABLE *t = p;
  341. print("%s: ", t->Source);
  342. print("Pin 0x%x, Address 0x%llx, SourceIndex 0x%x\n",
  343. t->Address, t->SourceIndex);
  344. p += t->Length;
  345. }
  346. }
  347. as = AcpiWalkResources(Object, "_CRS", resource, nil);
  348. print("Walk resources: as is %d\n", as);
  349. #if 0
  350. out.Length = ACPI_ALLOCATE_BUFFER;
  351. out.Pointer = nil;
  352. as = AcpiGetPossibleResources(Object, &out);
  353. print("get the possible resources: %d\n", as);
  354. if (ACPI_SUCCESS(as)) {
  355. void *p = (void *)out.Pointer;
  356. hexdump(out.Pointer, out.Length);
  357. while(((ACPI_RESOURCE*)p)->Type != ACPI_RESOURCE_TYPE_END_TAG) {
  358. ACPI_RESOURCE *r = p;
  359. ACPI_RESOURCE_IRQ *i = p + sizeof(r->Type);
  360. print("\tACPI_RESOURCE_TYPE_%d: Length %d\n", r->Type, r->Length);
  361. p += r->Length;
  362. if (r->Type != ACPI_RESOURCE_TYPE_IRQ)
  363. continue;
  364. print("\t\tIRQ Triggering %d Polarity %d Sharable %d InterruptCount %d: ",
  365. i->Triggering, i->Polarity, i->Sharable, i->InterruptCount);
  366. for(int j = 0; j < i->InterruptCount; j++)
  367. print("%d,", i->Interrupts[j]);
  368. print("\n");
  369. }
  370. print("Length is %u ptr is %p\n", out.Length, out.Pointer);
  371. }
  372. #endif
  373. print("hi\n");
  374. return 0;
  375. }
  376. int
  377. acpiinit(void)
  378. {
  379. ACPI_STATUS as;
  380. ACPI_TABLE_HEADER *h;
  381. ACPI_BUFFER out;
  382. int status;
  383. int apiccnt = 1;
  384. out.Length = ACPI_ALLOCATE_BUFFER;
  385. out.Pointer = nil;
  386. status = AcpiInitializeSubsystem();
  387. if (ACPI_FAILURE(status))
  388. panic("can't start acpi");
  389. status = AcpiInitializeTables(NULL, 16, FALSE);
  390. if (ACPI_FAILURE(status))
  391. panic("can't set up acpi tables");
  392. status = AcpiLoadTables();
  393. if (ACPI_FAILURE(status))
  394. panic("Can't load ACPI tables");
  395. status = AcpiEnableSubsystem(0);
  396. if (ACPI_FAILURE(status))
  397. panic("Can't enable ACPI subsystem");
  398. status = AcpiInitializeObjects(0);
  399. if (ACPI_FAILURE(status))
  400. panic("Can't Initialize ACPI objects");
  401. int sublen;
  402. uint8_t *p;
  403. extern uint8_t *apicbase;
  404. ACPI_TABLE_MADT *m;
  405. status = AcpiGetTable(ACPI_SIG_MADT, apiccnt, &h);
  406. if (ACPI_FAILURE(status))
  407. panic("Can't find a MADT");
  408. m = (ACPI_TABLE_MADT *)h;
  409. print("APIC %d: %p 0x%x\n", apiccnt, (void *)(uint64_t)m->Address, m->Flags);
  410. if(apicbase == nil){
  411. if((apicbase = vmap((uintptr_t)m->Address, 1024)) == nil){
  412. panic("%s: can't map apicbase\n", __func__);
  413. }
  414. print("%s: apicbase %#p -> %#p\n", __func__, (void *)(uint64_t)m->Address, apicbase);
  415. }
  416. if (! set_machine_mode()){
  417. print("Set machine mode failed\n");
  418. return 0;
  419. }
  420. p = (void*)&m[1];
  421. sublen = m->Header.Length;
  422. /* we only process the ones we're certain we need to. */
  423. while (sublen > 0) {
  424. switch(p[0]){
  425. case ACPI_MADT_TYPE_LOCAL_APIC:
  426. {
  427. ACPI_MADT_LOCAL_APIC *l = (void *)p;
  428. if (!l->LapicFlags)
  429. break;
  430. apicinit(l->Id, m->Address, apiccnt == 1);
  431. print("ACPICODE: apicinit(%d, %p, %d\n", l->Id, m->Address, apiccnt == 1);
  432. apiccnt++;
  433. }
  434. break;
  435. case ACPI_MADT_TYPE_IO_APIC:
  436. {
  437. ACPI_MADT_IO_APIC *io = (void *)p;
  438. print("IOapic %d @ %p\n", io->Id, io->Address);
  439. ioapicinit(io->Id, io->Address);
  440. print("ACPICODE: ioapicinit(%d, %p);\n", io->Id, (void*)(uint64_t)io->Address);
  441. }
  442. break;
  443. case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
  444. {
  445. ACPI_MADT_INTERRUPT_OVERRIDE *e = (void *)p;
  446. print("What an eyesore. Bus %d, SourceIrq %d, GlobalIrq %d, InitFlags 0x%x\n",
  447. e->Bus, e->SourceIrq, e->GlobalIrq, e->IntiFlags);
  448. eyesore = realloc(eyesore, numeyesore+1);
  449. if (! eyesore)
  450. panic("Ran out of eyesores");
  451. eyesore[numeyesore] = *e;
  452. numeyesore++;
  453. }
  454. break;
  455. case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
  456. {
  457. ACPI_MADT_LOCAL_APIC_NMI *nmi = (void *)p;
  458. apicnmi(nmi->ProcessorId, nmi->Lint, nmi->IntiFlags);
  459. }
  460. break;
  461. default:
  462. print("%s: can't handle subtable type %d\n", __func__, p[0]);
  463. break;
  464. }
  465. sublen -= p[1];
  466. p += p[1];
  467. }
  468. /* Get the _PRT */
  469. int i;
  470. for(i = 0; i < 255; i++) {
  471. static char path[255];
  472. snprint(path, sizeof(path), "\\_SB.PCI%d._PRT", i);
  473. as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, path, NULL, &out);
  474. if (!ACPI_SUCCESS(as))
  475. continue;
  476. print("------>GOT the PRT: %d\n", i);
  477. print("Length is %u ptr is %p\n", out.Length, out.Pointer);
  478. hexdump(out.Pointer, out.Length);
  479. objwalk(out.Pointer);
  480. as = AcpiGetDevices (nil, device, nil, nil);
  481. print("acpigetdevices %d\n", as);
  482. }
  483. /* per device code. Not useful yet.
  484. as = AcpiGetIrqRoutingTable(some device, &out);
  485. print("get the PRT: %d\n", as);
  486. print("Length is %u ptr is %p\n", out.Length, out.Pointer);
  487. hexdump(out.Pointer, out.Length);
  488. */
  489. /* PCI devices: Walk all devices. For those with interrupts, enable them. */
  490. Pcidev*pci = nil;
  491. for(pci = pcimatch(pci, 0, 0); pci; pci = pcimatch(pci, 0, 0)){
  492. if (!pci->intl || pci->intl == 0xff)
  493. continue;
  494. print("Interrupt %d: \n", pci->intl);
  495. pcishowdev(pci);
  496. int bus = BUSBNO(pci->tbdf);
  497. int apicno = 1; /* for now */
  498. int low = 0x1a000; /* is PCI always this? */
  499. print("ACPICODE: ioapicintrinit(%d, %d, %d, 0x%x, 0x%x);\n", bus, apicno, pci->intl, pci->tbdf, low);
  500. }
  501. print("ACPICODE: ioapicintrinit(0xff, DONE\n");
  502. return 0;
  503. }
  504. static Chan*
  505. acpiattach(char *spec)
  506. {
  507. return nil;
  508. // return devattach(L'α', spec);
  509. }
  510. static Walkqid*
  511. acpiwalk(Chan *c, Chan *nc, char **name, int nname)
  512. {
  513. return devwalk(c, nc, name, nname, acpidir, nelem(acpidir), acpigen);
  514. }
  515. static int32_t
  516. acpistat(Chan *c, uint8_t *dp, int32_t n)
  517. {
  518. return devstat(c, dp, n, acpidir, nelem(acpidir), acpigen);
  519. }
  520. static Chan*
  521. acpiopen(Chan *c, int omode)
  522. {
  523. return devopen(c, omode, acpidir, nelem(acpidir), acpigen);
  524. }
  525. static void
  526. acpiclose(Chan *c)
  527. {
  528. }
  529. #if 0
  530. static char*ttext;
  531. static int tlen;
  532. #endif
  533. static int32_t
  534. acpiread(Chan *c, void *a, int32_t n, int64_t off)
  535. {
  536. uint64_t q;
  537. q = c->qid.path;
  538. switch(q){
  539. case Qdir:
  540. return devdirread(c, a, n, acpidir, nelem(acpidir), acpigen);
  541. case Qtbl:
  542. return -1; //readstr(off, a, n, ttext);
  543. case Qio:
  544. return -1; //regio(reg, a, n, off, 0);
  545. }
  546. error(Eperm);
  547. return -1;
  548. }
  549. static int32_t
  550. acpiwrite(Chan *c, void *a, int32_t n, int64_t off)
  551. {
  552. if(c->qid.path == Qio){
  553. //if(reg == nil)
  554. error("region not configured");
  555. }
  556. if(c->qid.path != Qctl)
  557. error(Eperm);
  558. error("NP");
  559. #if 0
  560. cb = parsecmd(a, n);
  561. if(waserror()){
  562. free(cb);
  563. nexterror();
  564. }
  565. ct = lookupcmd(cb, ctls, nelem(ctls));
  566. DBG("acpi ctl %s\n", cb->f[0]);
  567. switch(ct->index){
  568. case CMregion:
  569. r = reg;
  570. if(r == nil){
  571. r = smalloc(sizeof(Reg));
  572. r->name = nil;
  573. }
  574. kstrdup(&r->name, cb->f[1]);
  575. r->spc = acpiregid(cb->f[2]);
  576. if(r->spc < 0){
  577. free(r);
  578. reg = nil;
  579. error("bad region type");
  580. }
  581. if(r->spc == Rpcicfg || r->spc == Rpcibar){
  582. rno = r->base>>Rpciregshift & Rpciregmask;
  583. fun = r->base>>Rpcifunshift & Rpcifunmask;
  584. dev = r->base>>Rpcidevshift & Rpcidevmask;
  585. bus = r->base>>Rpcibusshift & Rpcibusmask;
  586. r->tbdf = MKBUS(BusPCI, bus, dev, fun);
  587. r->base = rno; /* register ~ our base addr */
  588. }
  589. r->base = strtoull(cb->f[3], nil, 0);
  590. r->len = strtoull(cb->f[4], nil, 0);
  591. r->accsz = strtoul(cb->f[5], nil, 0);
  592. if(r->accsz < 1 || r->accsz > 4){
  593. free(r);
  594. reg = nil;
  595. error("bad region access size");
  596. }
  597. reg = r;
  598. DBG("region %s %s %llux %llux sz%d",
  599. r->name, acpiregstr(r->spc), r->base, r->len, r->accsz);
  600. break;
  601. case CMgpe:
  602. i = strtoul(cb->f[1], nil, 0);
  603. if(i >= ngpes)
  604. error("gpe out of range");
  605. kstrdup(&gpes[i].obj, cb->f[2]);
  606. DBG("gpe %d %s\n", i, gpes[i].obj);
  607. setgpeen(i, 1);
  608. break;
  609. default:
  610. panic("acpi: unknown ctl");
  611. }
  612. poperror();
  613. free(cb);
  614. return n;
  615. #endif
  616. return -1;
  617. }
  618. Dev acpidevtab = {
  619. .dc = L'α',
  620. .name = "acpi",
  621. .reset = devreset,
  622. .init = devinit,
  623. .shutdown = devshutdown,
  624. .attach = acpiattach,
  625. .walk = acpiwalk,
  626. .stat = acpistat,
  627. .open = acpiopen,
  628. .create = devcreate,
  629. .close = acpiclose,
  630. .read = acpiread,
  631. .bread = devbread,
  632. .write = acpiwrite,
  633. .bwrite = devbwrite,
  634. .remove = devremove,
  635. .wstat = devwstat,
  636. };
  637. static int tbdf(ACPI_PCI_ID *p)
  638. {
  639. return (p->Bus << 8) | (p->Device << 3) | (p->Function);
  640. }
  641. ACPI_STATUS
  642. AcpiOsReadPciConfiguration (
  643. ACPI_PCI_ID *PciId,
  644. UINT32 Reg,
  645. UINT64 *Value,
  646. UINT32 Width)
  647. {
  648. Pcidev p;
  649. p.tbdf = tbdf(PciId);
  650. print("%s\n", __func__);
  651. switch(Width) {
  652. case 32:
  653. *Value = pcicfgr32(&p, Reg);
  654. break;
  655. case 16:
  656. *Value = pcicfgr16(&p, Reg);
  657. break;
  658. case 8:
  659. *Value = pcicfgr8(&p, Reg);
  660. break;
  661. default:
  662. panic("Can't read pci: bad width %d\n", Width);
  663. }
  664. return AE_OK;
  665. }
  666. ACPI_STATUS
  667. AcpiOsWritePciConfiguration (
  668. ACPI_PCI_ID *PciId,
  669. UINT32 Reg,
  670. UINT64 Value,
  671. UINT32 Width)
  672. {
  673. Pcidev p;
  674. p.tbdf = tbdf(PciId);
  675. print("%s\n", __func__);
  676. switch(Width) {
  677. case 32:
  678. pcicfgw32(&p, Reg, Value);
  679. break;
  680. case 16:
  681. pcicfgw16(&p, Reg, Value);
  682. break;
  683. case 8:
  684. pcicfgw8(&p, Reg, Value);
  685. break;
  686. default:
  687. panic("Can't read pci: bad width %d\n", Width);
  688. }
  689. return AE_OK;
  690. }
  691. /*
  692. * Miscellaneous
  693. */
  694. BOOLEAN
  695. AcpiOsReadable (
  696. void *Pointer,
  697. ACPI_SIZE Length)
  698. {
  699. print("%s\n", __func__);
  700. panic("%s", __func__);
  701. return AE_OK;
  702. }
  703. BOOLEAN
  704. AcpiOsWritable (
  705. void *Pointer,
  706. ACPI_SIZE Length)
  707. {
  708. print("%s\n", __func__);
  709. panic("%s", __func__);
  710. return AE_OK;
  711. }
  712. UINT64
  713. AcpiOsGetTimer (
  714. void)
  715. {
  716. print("%s\n", __func__);
  717. panic("%s", __func__);
  718. return AE_OK;
  719. }
  720. ACPI_STATUS
  721. AcpiOsSignal (
  722. UINT32 Function,
  723. void *Info)
  724. {
  725. print("%s\n", __func__);
  726. panic("%s", __func__);
  727. return AE_OK;
  728. }
  729. void ACPI_INTERNAL_VAR_XFACE
  730. AcpiOsPrintf (
  731. const char *Format,
  732. ...)
  733. {
  734. va_list args;
  735. va_start(args, Format);
  736. print((char *)Format, args);
  737. va_end(args);
  738. }
  739. void
  740. AcpiOsVprintf (
  741. const char *Format,
  742. va_list Args)
  743. {
  744. /* This is a leaf function, and this function is required to implement
  745. * the va_list argument. I couldn't find any other way to do this. */
  746. static char buf[1024];
  747. vseprint(buf, &buf[1023], (char *)Format, Args);
  748. print(buf);
  749. }
  750. void
  751. AcpiOsFree (
  752. void * Memory)
  753. {
  754. //print("%s\n", __func__);
  755. free(Memory);
  756. }
  757. void *
  758. AcpiOsAllocate (
  759. ACPI_SIZE Size)
  760. {
  761. //print("%s\n", __func__);
  762. return malloc(Size);
  763. }
  764. void *
  765. AcpiOsMapMemory (
  766. ACPI_PHYSICAL_ADDRESS Where,
  767. ACPI_SIZE Length)
  768. {
  769. void *v = vmap(Where, Length);
  770. print("%s %p = vmap(%p,0x%x)\n", __func__, v, (void*)Where, Length);
  771. print("Val @ %p is 0x%x\n", v, *(int *)v);
  772. return v;
  773. }
  774. void
  775. AcpiOsUnmapMemory (
  776. void *LogicalAddress,
  777. ACPI_SIZE Size)
  778. {
  779. print("%s %p %d \n", __func__, LogicalAddress, Size);
  780. vunmap(LogicalAddress, Size);
  781. }
  782. ACPI_STATUS
  783. AcpiOsGetPhysicalAddress (
  784. void *LogicalAddress,
  785. ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
  786. {
  787. ACPI_PHYSICAL_ADDRESS ret = mmuphysaddr((uintptr_t)LogicalAddress);
  788. print("%s %p = mmyphysaddr(%p)", __func__, (void *)ret, LogicalAddress);
  789. *PhysicalAddress = ret;
  790. return AE_OK;
  791. }
  792. /* This is the single threaded version of
  793. * these functions. This is now NetBSD does it. */
  794. ACPI_STATUS
  795. AcpiOsCreateSemaphore (
  796. UINT32 MaxUnits,
  797. UINT32 InitialUnits,
  798. ACPI_SEMAPHORE *OutHandle)
  799. {
  800. //print("%s\n", __func__);
  801. *OutHandle = (ACPI_SEMAPHORE) 1;
  802. return AE_OK;
  803. }
  804. ACPI_STATUS
  805. AcpiOsDeleteSemaphore (
  806. ACPI_SEMAPHORE Handle)
  807. {
  808. //print("%s\n", __func__);
  809. return AE_OK;
  810. }
  811. ACPI_STATUS
  812. AcpiOsWaitSemaphore (
  813. ACPI_SEMAPHORE Handle,
  814. UINT32 Units,
  815. UINT16 Timeout)
  816. {
  817. //print("%s\n", __func__);
  818. return AE_OK;
  819. }
  820. ACPI_STATUS
  821. AcpiOsSignalSemaphore (
  822. ACPI_SEMAPHORE Handle,
  823. UINT32 Units)
  824. {
  825. //print("%s\n", __func__);
  826. return AE_OK;
  827. }
  828. /* this is the single threaded case and as minix shows there is nothing to do. */
  829. ACPI_STATUS
  830. AcpiOsCreateLock (
  831. ACPI_SPINLOCK *OutHandle)
  832. {
  833. //print("%s\n", __func__);
  834. *OutHandle = nil;
  835. return AE_OK;
  836. }
  837. void
  838. AcpiOsDeleteLock (
  839. ACPI_SPINLOCK Handle)
  840. {
  841. //print("%s\n", __func__);
  842. }
  843. ACPI_CPU_FLAGS
  844. AcpiOsAcquireLock (
  845. ACPI_SPINLOCK Handle)
  846. {
  847. //print("%s\n", __func__);
  848. return 0;
  849. }
  850. void
  851. AcpiOsReleaseLock (
  852. ACPI_SPINLOCK Handle,
  853. ACPI_CPU_FLAGS Flags)
  854. {
  855. //print("%s\n", __func__);
  856. }
  857. struct handler {
  858. ACPI_OSD_HANDLER ServiceRoutine;
  859. void *Context;
  860. };
  861. /* The ACPI interrupt signature and the Harvey one are not compatible. So, we pass an arg to
  862. * intrenable that can in turn be used to this function to call the ACPI handler. */
  863. static void acpihandler(Ureg *_, void *arg)
  864. {
  865. struct handler *h = arg;
  866. h->ServiceRoutine(h->Context);
  867. }
  868. ACPI_STATUS
  869. AcpiOsInstallInterruptHandler (
  870. UINT32 InterruptNumber,
  871. ACPI_OSD_HANDLER ServiceRoutine,
  872. void *Context)
  873. {
  874. /* minix says "don't do it". So we don't, yet. */
  875. return AE_OK;
  876. struct handler *h = malloc(sizeof(*h));
  877. if (! h)
  878. return AE_NO_MEMORY;
  879. h->ServiceRoutine = ServiceRoutine;
  880. h->Context = Context;
  881. print("%s %d %p %p \n", __func__, InterruptNumber, ServiceRoutine, Context);
  882. /* once enabled, can't be disabled; ignore the return value unless it's nil. */
  883. intrenable(InterruptNumber, acpihandler, h, 0x5, "ACPI interrupt handler");
  884. return AE_OK;
  885. }
  886. ACPI_STATUS
  887. AcpiOsRemoveInterruptHandler (
  888. UINT32 InterruptNumber,
  889. ACPI_OSD_HANDLER ServiceRoutine)
  890. {
  891. print("%s\n", __func__);
  892. panic("%s", __func__);
  893. return AE_OK;
  894. }
  895. void
  896. AcpiOsWaitEventsComplete (
  897. void)
  898. {
  899. print("%s\n", __func__);
  900. panic("%s", __func__);
  901. }
  902. void
  903. AcpiOsSleep (
  904. UINT64 Milliseconds)
  905. {
  906. print("%s\n", __func__);
  907. panic("%s", __func__);
  908. }
  909. void
  910. AcpiOsStall(
  911. UINT32 Microseconds)
  912. {
  913. print("%s\n", __func__);
  914. panic("%s", __func__);
  915. }
  916. ACPI_THREAD_ID
  917. AcpiOsGetThreadId (
  918. void)
  919. {
  920. /* What to do here? ACPI won't take 0 for an answer.
  921. * I guess tell it we're 1? What do we do? */
  922. return 1;
  923. //print("%s\n", __func__);
  924. Proc *up = externup();
  925. return up->pid;
  926. }
  927. ACPI_STATUS
  928. AcpiOsExecute (
  929. ACPI_EXECUTE_TYPE Type,
  930. ACPI_OSD_EXEC_CALLBACK Function,
  931. void *Context)
  932. {
  933. print("%s\n", __func__);
  934. panic("%s", __func__);
  935. return AE_OK;
  936. }
  937. ACPI_STATUS
  938. AcpiOsReadPort (
  939. ACPI_IO_ADDRESS Address,
  940. UINT32 *Value,
  941. UINT32 Width)
  942. {
  943. /* Ooooooookay ... ACPI specifies the IO width in *bits*. */
  944. switch(Width) {
  945. case 4*8:
  946. *Value = inl(Address);
  947. break;
  948. case 2*8:
  949. *Value = ins(Address);
  950. break;
  951. case 1*8:
  952. *Value = inb(Address);
  953. break;
  954. default:
  955. panic("%s, bad width %d", __func__, Width);
  956. break;
  957. }
  958. print("%s 0x%x 0x%x\n", __func__, Address, *Value);
  959. return AE_OK;
  960. }
  961. ACPI_STATUS
  962. AcpiOsWritePort (
  963. ACPI_IO_ADDRESS Address,
  964. UINT32 Value,
  965. UINT32 Width)
  966. {
  967. switch(Width) {
  968. case 4*8:
  969. outl(Address, Value);
  970. break;
  971. case 2*8:
  972. outs(Address, Value);
  973. break;
  974. case 1*8:
  975. outb(Address, Value);
  976. break;
  977. default:
  978. panic("%s, bad width %d", __func__, Width);
  979. break;
  980. }
  981. print("%s 0x%x 0x%x\n", __func__, Address, Value);
  982. return AE_OK;
  983. }
  984. /*
  985. * Platform and hardware-independent physical memory interfaces
  986. */
  987. ACPI_STATUS
  988. AcpiOsReadMemory (
  989. ACPI_PHYSICAL_ADDRESS Address,
  990. UINT64 *Value,
  991. UINT32 Width)
  992. {
  993. print("%s\n", __func__);
  994. panic("%s", __func__);
  995. return AE_OK;
  996. }
  997. ACPI_STATUS
  998. AcpiOsWriteMemory (
  999. ACPI_PHYSICAL_ADDRESS Address,
  1000. UINT64 Value,
  1001. UINT32 Width)
  1002. {
  1003. print("%s\n", __func__);
  1004. panic("%s", __func__);
  1005. return AE_OK;
  1006. }
  1007. /*
  1008. * ACPI Table interfaces
  1009. */
  1010. ACPI_PHYSICAL_ADDRESS
  1011. AcpiOsGetRootPointer (
  1012. void)
  1013. {
  1014. print("%s returns %p\n", __func__, rsd);
  1015. return (ACPI_PHYSICAL_ADDRESS) PADDR(rsd);
  1016. }
  1017. ACPI_STATUS
  1018. AcpiOsPredefinedOverride (
  1019. const ACPI_PREDEFINED_NAMES *InitVal,
  1020. ACPI_STRING *NewVal)
  1021. {
  1022. print("%s\n", __func__);
  1023. *NewVal = nil;
  1024. return AE_OK;
  1025. }
  1026. ACPI_STATUS
  1027. AcpiOsTableOverride (
  1028. ACPI_TABLE_HEADER *ExistingTable,
  1029. ACPI_TABLE_HEADER **NewTable)
  1030. {
  1031. print("%s\n", __func__);
  1032. *NewTable = nil;
  1033. return AE_OK;
  1034. }
  1035. ACPI_STATUS
  1036. AcpiOsPhysicalTableOverride (
  1037. ACPI_TABLE_HEADER *ExistingTable,
  1038. ACPI_PHYSICAL_ADDRESS *NewAddress,
  1039. UINT32 *NewTableLength)
  1040. {
  1041. print("%s\n", __func__);
  1042. *NewAddress = (ACPI_PHYSICAL_ADDRESS)nil;
  1043. return AE_OK;
  1044. }
  1045. /*
  1046. * Debug input
  1047. */
  1048. ACPI_STATUS
  1049. AcpiOsGetLine (
  1050. char *Buffer,
  1051. UINT32 BufferLength,
  1052. UINT32 *BytesRead)
  1053. {
  1054. print("%s\n", __func__);
  1055. panic("%s", __func__);
  1056. return AE_OK;
  1057. }