harvey.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  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 <acpi.h>
  10. #define MiB (1<<20)
  11. BOOLEAN AcpiGbl_DebugTimeout = FALSE;
  12. static uint32_t rsdp;
  13. static char *name;
  14. /* debug prints for this file. You can set this in gdb or at compile time. */
  15. static int debug;
  16. #if 0
  17. static int
  18. xisprint(int c)
  19. {
  20. return (c >= 32 && c <= 126);
  21. }
  22. static void
  23. hexdump(void *v, int length)
  24. {
  25. int i;
  26. uint8_t *m = v;
  27. uintptr_t memory = (uintptr_t) v;
  28. int all_zero = 0;
  29. if (debug)
  30. fprint(2, "hexdump: %p, %u\n", v, length);
  31. for (i = 0; i < length; i += 16) {
  32. int j;
  33. all_zero++;
  34. for (j = 0; (j < 16) && (i + j < length); j++) {
  35. if (m[i + j] != 0) {
  36. all_zero = 0;
  37. break;
  38. }
  39. }
  40. if (all_zero < 2) {
  41. if (debug)
  42. fprint(2, "%p:", (void *)(memory + i));
  43. for (j = 0; j < 16; j++)
  44. if (debug)
  45. fprint(2, " %02x", m[i + j]);
  46. if (debug)
  47. fprint(2, " ");
  48. for (j = 0; j < 16; j++)
  49. if (debug)
  50. fprint(2, "%c", xisprint(m[i + j]) ? m[i + j] : '.');
  51. if (debug)
  52. fprint(2, "\n");
  53. } else if (all_zero == 2) {
  54. if (debug)
  55. fprint(2, "...\n");
  56. }
  57. }
  58. }
  59. #endif
  60. /* try several variants */
  61. static int
  62. rawfd(void)
  63. {
  64. int fd;
  65. if (name == nil) {
  66. name = "/dev/acpimem";
  67. if (debug)
  68. fprint(2, "Rawfd: open '%s'\n", name);
  69. fd = open(name, OREAD);
  70. if (fd > -1)
  71. return fd;
  72. name = "#P/acpimem";
  73. if (debug)
  74. fprint(2, "Rawfd: open '%s'\n", name);
  75. fd = open(name, OREAD);
  76. if (fd > -1)
  77. return fd;
  78. }
  79. return open(name, OREAD);
  80. }
  81. static int
  82. tbdf(ACPI_PCI_ID * p)
  83. {
  84. return (p->Bus << 8) | (p->Device << 3) | (p->Function);
  85. }
  86. int iol = -1, iow = -1, iob = -1;
  87. uint32_t
  88. inl(uint16_t addr)
  89. {
  90. uint64_t off = addr;
  91. uint32_t l;
  92. if (pread(iol, &l, 4, off) < 4)
  93. print("inl(0x%x): %r\n", addr);
  94. return l;
  95. }
  96. uint16_t
  97. ins(uint16_t addr)
  98. {
  99. uint64_t off = addr;
  100. uint16_t w;
  101. if (pread(iow, &w, 2, off) < 2)
  102. print("ins(0x%x): %r\n", addr);
  103. return w;
  104. }
  105. uint8_t
  106. inb(uint16_t addr)
  107. {
  108. uint64_t off = addr;
  109. uint16_t b;
  110. if (pread(iow, &b, 1, off) < 1)
  111. print("inb(0x%x): %r\n", addr);
  112. return b;
  113. }
  114. void
  115. outl(uint32_t val, uint16_t addr)
  116. {
  117. uint64_t off = addr;
  118. if (pwrite(iol, &val, 4, off) < 4)
  119. print("outl(0x%x): %r\n", addr);
  120. }
  121. void
  122. outs(uint16_t val, uint16_t addr)
  123. {
  124. uint64_t off = addr;
  125. if (pwrite(iow, &val, 2, off) < 2)
  126. print("outs(0x%x): %r\n", addr);
  127. }
  128. void
  129. outb(uint8_t val, uint16_t addr)
  130. {
  131. uint64_t off = addr;
  132. if (pwrite(iob, &val, 1, off) < 1)
  133. print("outb(0x%x): %r\n", addr);
  134. }
  135. #define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
  136. #define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
  137. #define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
  138. #define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
  139. #define BUSTYPE(tbdf) ((tbdf)>>24)
  140. #define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
  141. ACPI_STATUS
  142. AcpiOsReadPciConfiguration(ACPI_PCI_ID * PciId,
  143. UINT32 Reg, UINT64 * Value, UINT32 Width)
  144. {
  145. ACPI_STATUS ret = AE_OK;
  146. uint64_t val;
  147. int amt;
  148. static char path[128];
  149. snprint(path, sizeof(path), "/dev/pci/%d.%d.%draw", PciId->Bus,
  150. PciId->Device, PciId->Function);
  151. int fd = open(path, OREAD);
  152. if (fd < 0) {
  153. if (debug)
  154. print("%s: open %s: %r\n", __func__, path);
  155. return AE_IO_ERROR;
  156. }
  157. switch (Width) {
  158. case 32:
  159. case 16:
  160. case 8:
  161. amt = pread(fd, Value, Width / 8, Reg);
  162. if (amt < Width / 8)
  163. ret = AE_IO_ERROR;
  164. break;
  165. default:
  166. sysfatal("Can't read pci: bad width %d\n", Width);
  167. }
  168. close(fd);
  169. if (amt > 0)
  170. memmove(&val, Value, amt);
  171. if (debug)
  172. fprint(2, "pciread 0x%x 0x%x 0x%x 0x%x/%d 0x%x %d\n", PciId->Bus,
  173. PciId->Device, PciId->Function, Reg, Width / 8, *Value, ret);
  174. return ret;
  175. }
  176. ACPI_STATUS
  177. AcpiOsWritePciConfiguration(ACPI_PCI_ID * PciId,
  178. UINT32 Reg, UINT64 Value, UINT32 Width)
  179. {
  180. ACPI_STATUS ret = AE_OK;
  181. int amt;
  182. static char path[128];
  183. snprint(path, sizeof(path), "/dev/pci/%d.%d.%draw", PciId->Bus,
  184. PciId->Device, PciId->Function);
  185. int fd = open(path, ORDWR);
  186. if (fd < 0) {
  187. print("%s: open %s: %r\n", __func__, path);
  188. return AE_IO_ERROR;
  189. }
  190. switch (Width) {
  191. case 32:
  192. case 16:
  193. case 8:
  194. amt = pwrite(fd, &Value, Width / 8, Reg);
  195. if (amt < Width / 8)
  196. ret = AE_IO_ERROR;
  197. break;
  198. default:
  199. sysfatal("Can't read pci: bad width %d\n", Width);
  200. }
  201. close(fd);
  202. if (debug)
  203. fprint(2, "pciwrite 0x%x 0x%x 0x%x 0x%x/%d 0x%x %d\n", PciId->Bus,
  204. PciId->Device, PciId->Function, Reg, Width / 8, Value, ret);
  205. return ret;
  206. }
  207. /*
  208. * Miscellaneous
  209. */
  210. BOOLEAN
  211. AcpiOsReadable(void *Pointer, ACPI_SIZE Length)
  212. {
  213. if (debug)
  214. fprint(2, "%s\n", __func__);
  215. sysfatal("%s", __func__);
  216. return AE_OK;
  217. }
  218. BOOLEAN
  219. AcpiOsWritable(void *Pointer, ACPI_SIZE Length)
  220. {
  221. if (debug)
  222. fprint(2, "%s\n", __func__);
  223. sysfatal("%s", __func__);
  224. return AE_OK;
  225. }
  226. UINT64
  227. AcpiOsGetTimer(void)
  228. {
  229. if (debug)
  230. fprint(2, "%s\n", __func__);
  231. sysfatal("%s", __func__);
  232. return AE_OK;
  233. }
  234. ACPI_STATUS
  235. AcpiOsSignal(UINT32 Function, void *Info)
  236. {
  237. if (debug)
  238. fprint(2, "%s\n", __func__);
  239. sysfatal("%s", __func__);
  240. return AE_OK;
  241. }
  242. /* N.B. Only works for single thread! */
  243. void ACPI_INTERNAL_VAR_XFACE
  244. AcpiOsPrintf(const char *Format, ...)
  245. {
  246. static char buf[65536];
  247. va_list args;
  248. va_start(args, Format);
  249. vseprint(buf, &buf[65535], (char *)Format, args);
  250. va_end(args);
  251. if (debug)
  252. fprint(2, buf);
  253. }
  254. void
  255. AcpiOsVprintf(const char *Format, va_list Args)
  256. {
  257. /* This is a leaf function, and this function is required to implement
  258. * the va_list argument. I couldn't find any other way to do this. */
  259. static char buf[1024];
  260. vseprint(buf, &buf[1023], (char *)Format, Args);
  261. if (debug)
  262. fprint(2, buf);
  263. }
  264. void
  265. AcpiOsFree(void *Memory)
  266. {
  267. //fprint(2,"%s\n", __func__);
  268. free(Memory);
  269. }
  270. void *
  271. AcpiOsAllocate(ACPI_SIZE Size)
  272. {
  273. //fprint(2,"%s\n", __func__);
  274. return malloc(Size);
  275. }
  276. void hexdump(void *v, int length);
  277. void *
  278. AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
  279. {
  280. int fd, amt;
  281. fd = rawfd();
  282. if (debug)
  283. fprint(2, "%s %p %d\n", __func__, (void *)Where, Length);
  284. void *v = malloc(Length);
  285. if (!v) {
  286. sysfatal("%s: %r", __func__);
  287. return nil;
  288. }
  289. fd = rawfd();
  290. if (fd < 0) {
  291. if (debug)
  292. fprint(2, "%s: open %s: %r\n", __func__, name);
  293. return nil;
  294. }
  295. amt = pread(fd, v, Length, Where);
  296. close(fd);
  297. /* If we just do the amt < Length test, it will not work when
  298. * amt is -1. Length is uint64_t. */
  299. if ((amt < 0) || (amt < Length)) {
  300. free(v);
  301. if (debug)
  302. fprint(2, "%s: read %s: %r\n", __func__, name);
  303. return nil;
  304. }
  305. //hexdump(v, Length);
  306. //hexdump(v, 36);
  307. return v;
  308. }
  309. void
  310. AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size)
  311. {
  312. free(LogicalAddress);
  313. if (debug)
  314. fprint(2, "%s %p %d \n", __func__, LogicalAddress, Size);
  315. }
  316. ACPI_STATUS
  317. AcpiOsGetPhysicalAddress(void *LogicalAddress,
  318. ACPI_PHYSICAL_ADDRESS * PhysicalAddress)
  319. {
  320. ACPI_PHYSICAL_ADDRESS ret = (uintptr_t) LogicalAddress;
  321. if (debug)
  322. fprint(2, "%s %p = %p", __func__, (void *)ret, LogicalAddress);
  323. *PhysicalAddress = ret;
  324. return AE_OK;
  325. }
  326. /* This is the single threaded version of
  327. * these functions. This is now NetBSD does it. */
  328. ACPI_STATUS
  329. AcpiOsCreateSemaphore(UINT32 MaxUnits,
  330. UINT32 InitialUnits, ACPI_SEMAPHORE * OutHandle)
  331. {
  332. //fprint(2,"%s\n", __func__);
  333. *OutHandle = (ACPI_SEMAPHORE) 1;
  334. return AE_OK;
  335. }
  336. ACPI_STATUS
  337. AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
  338. {
  339. //fprint(2,"%s\n", __func__);
  340. return AE_OK;
  341. }
  342. ACPI_STATUS
  343. AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
  344. {
  345. //fprint(2,"%s\n", __func__);
  346. return AE_OK;
  347. }
  348. ACPI_STATUS
  349. AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
  350. {
  351. //fprint(2,"%s\n", __func__);
  352. return AE_OK;
  353. }
  354. /* this is the single threaded case and as minix shows there is nothing to do. */
  355. ACPI_STATUS
  356. AcpiOsCreateLock(ACPI_SPINLOCK * OutHandle)
  357. {
  358. //fprint(2,"%s\n", __func__);
  359. *OutHandle = nil;
  360. return AE_OK;
  361. }
  362. void
  363. AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
  364. {
  365. //fprint(2,"%s\n", __func__);
  366. }
  367. ACPI_CPU_FLAGS
  368. AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
  369. {
  370. //fprint(2,"%s\n", __func__);
  371. return 0;
  372. }
  373. void
  374. AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
  375. {
  376. //fprint(2,"%s\n", __func__);
  377. }
  378. struct handler {
  379. ACPI_OSD_HANDLER ServiceRoutine;
  380. void *Context;
  381. };
  382. #if 0
  383. /* The ACPI interrupt signature and the Harvey one are not compatible. So, we pass an arg to
  384. * intrenable that can in turn be used to this function to call the ACPI handler. */
  385. static void
  386. acpihandler(void *_, void *arg)
  387. {
  388. struct handler *h = arg;
  389. h->ServiceRoutine(h->Context);
  390. }
  391. #endif
  392. ACPI_STATUS
  393. AcpiOsInstallInterruptHandler(UINT32 InterruptNumber,
  394. ACPI_OSD_HANDLER ServiceRoutine, void *Context)
  395. {
  396. /* minix says "don't do it". So we don't, yet. */
  397. return AE_OK;
  398. struct handler *h = malloc(sizeof(*h));
  399. if (!h)
  400. return AE_NO_MEMORY;
  401. h->ServiceRoutine = ServiceRoutine;
  402. h->Context = Context;
  403. if (debug)
  404. fprint(2, "NOT DOING %s %d %p %p \n", __func__, InterruptNumber,
  405. ServiceRoutine, Context);
  406. /* once enabled, can't be disabled; ignore the return value unless it's nil. */
  407. //intrenable(InterruptNumber, acpihandler, h, 0x5, "ACPI interrupt handler");
  408. return AE_OK;
  409. }
  410. ACPI_STATUS
  411. AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber,
  412. ACPI_OSD_HANDLER ServiceRoutine)
  413. {
  414. if (debug)
  415. fprint(2, "%s\n", __func__);
  416. sysfatal("%s", __func__);
  417. return AE_OK;
  418. }
  419. void
  420. AcpiOsWaitEventsComplete(void)
  421. {
  422. if (debug)
  423. fprint(2, "%s\n", __func__);
  424. sysfatal("%s", __func__);
  425. }
  426. void
  427. AcpiOsSleep(UINT64 Milliseconds)
  428. {
  429. if (debug)
  430. fprint(2, "%s\n", __func__);
  431. sleep(Milliseconds);
  432. }
  433. void
  434. AcpiOsStall(UINT32 Microseconds)
  435. {
  436. if (debug)
  437. fprint(2, "%s\n", __func__);
  438. sleep(Microseconds / 1000 + 1);
  439. }
  440. ACPI_THREAD_ID
  441. AcpiOsGetThreadId(void)
  442. {
  443. static int pid = 2525;
  444. if (pid < 0)
  445. pid = getpid();
  446. return pid;
  447. }
  448. ACPI_STATUS
  449. AcpiOsExecute(ACPI_EXECUTE_TYPE Type,
  450. ACPI_OSD_EXEC_CALLBACK Function, void *Context)
  451. {
  452. ACPI_STATUS ret = AE_OK;
  453. if (debug)
  454. fprint(2, "%s\n", __func__);
  455. Function(Context);
  456. return ret;
  457. }
  458. ACPI_STATUS
  459. AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 * Value, UINT32 Width)
  460. {
  461. switch (Width) {
  462. case 4 * 8:
  463. *Value = inl(Address);
  464. break;
  465. case 2 * 8:
  466. *Value = ins(Address);
  467. break;
  468. case 1 * 8:
  469. *Value = inb(Address);
  470. break;
  471. default:
  472. sysfatal("%s, bad width %d", __func__, Width);
  473. break;
  474. }
  475. if (debug)
  476. fprint(2, "%s 0x%x 0x%x\n", __func__, Address, *Value);
  477. return AE_OK;
  478. }
  479. ACPI_STATUS
  480. AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
  481. {
  482. switch (Width) {
  483. case 4 * 8:
  484. outl(Address, Value);
  485. break;
  486. case 2 * 8:
  487. outs(Address, Value);
  488. break;
  489. case 1 * 8:
  490. outb(Address, Value);
  491. break;
  492. default:
  493. sysfatal("%s, bad width %d", __func__, Width);
  494. break;
  495. }
  496. if (debug)
  497. fprint(2, "%s 0x%x 0x%x\n", __func__, Address, Value);
  498. return AE_OK;
  499. }
  500. /*
  501. * Platform and hardware-independent physical memory interfaces
  502. */
  503. ACPI_STATUS
  504. AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 * Value, UINT32 Width)
  505. {
  506. if (debug)
  507. fprint(2, "%s\n", __func__);
  508. sysfatal("%s", __func__);
  509. return AE_OK;
  510. }
  511. ACPI_STATUS
  512. AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
  513. {
  514. if (debug)
  515. fprint(2, "%s\n", __func__);
  516. sysfatal("%s", __func__);
  517. return AE_OK;
  518. }
  519. /* Just try to read the rsdp, if that fails, we're screwed anyway. */
  520. ACPI_STATUS
  521. AcpiOsInitialize(void)
  522. {
  523. int fd, amt;
  524. if (debug)
  525. fprint(2, "%s\n", __func__);
  526. fd = rawfd();
  527. if (fd < 0) {
  528. if (debug)
  529. fprint(2, "%s: open %s: %r\n", __func__, name);
  530. return AE_ERROR;
  531. }
  532. amt = read(fd, &rsdp, sizeof(rsdp));
  533. if (amt < sizeof(rsdp)) {
  534. if (debug)
  535. fprint(2, "%s: read %s: %r\n", __func__, name);
  536. return AE_ERROR;
  537. }
  538. close(fd);
  539. iol = open("/dev/iol", ORDWR);
  540. if (iol < 0)
  541. sysfatal("iol: %r");
  542. iow = open("/dev/iow", ORDWR);
  543. if (iow < 0)
  544. sysfatal("iow: %r");
  545. iob = open("/dev/iob", ORDWR);
  546. if (iob < 0)
  547. sysfatal("iob: %r");
  548. return AE_OK;
  549. }
  550. /*
  551. * ACPI Table interfaces
  552. */
  553. __attribute__ ((weak))ACPI_PHYSICAL_ADDRESS
  554. AcpiOsGetRootPointer(void)
  555. {
  556. if (debug)
  557. fprint(2, "%s returns %p\n", __func__, rsdp);
  558. return (ACPI_PHYSICAL_ADDRESS) rsdp;
  559. }
  560. ACPI_STATUS
  561. AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES * InitVal,
  562. ACPI_STRING * NewVal)
  563. {
  564. if (debug)
  565. fprint(2, "%s\n", __func__);
  566. *NewVal = nil;
  567. return AE_OK;
  568. }
  569. ACPI_STATUS
  570. AcpiOsTableOverride(ACPI_TABLE_HEADER * ExistingTable,
  571. ACPI_TABLE_HEADER ** NewTable)
  572. {
  573. if (debug)
  574. fprint(2, "%s\n", __func__);
  575. *NewTable = nil;
  576. return AE_OK;
  577. }
  578. ACPI_STATUS
  579. AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER * ExistingTable,
  580. ACPI_PHYSICAL_ADDRESS * NewAddress,
  581. UINT32 * NewTableLength)
  582. {
  583. if (debug)
  584. fprint(2, "%s\n", __func__);
  585. *NewAddress = (ACPI_PHYSICAL_ADDRESS) nil;
  586. return AE_OK;
  587. }
  588. /*
  589. * Debug input
  590. */
  591. ACPI_STATUS
  592. AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 * BytesRead)
  593. {
  594. int amt;
  595. if (debug)
  596. fprint(2, "%s\n", __func__);
  597. amt = read(0, Buffer, BufferLength);
  598. if (BytesRead)
  599. *BytesRead = amt;
  600. return AE_OK;
  601. }
  602. ACPI_STATUS
  603. AcpiOsTerminate(void)
  604. {
  605. sysfatal("%s\n", __func__);
  606. return AE_OK;
  607. }
  608. /* Another acpica failure of vision: code in libraries that depends on functions defined only
  609. * in the compiler or other programs. Really! What to do?
  610. * this is how the acpi tools do it. Save we add a print so we know the function is called, duh! */
  611. typedef void *ACPI_PARSE_OBJECT;
  612. typedef void *AML_RESOURCE;
  613. /* this is from acpiexec. */
  614. /* For AcpiExec only */
  615. __attribute__ ((weak))void
  616. AeDoObjectOverrides(void)
  617. {
  618. if (debug)
  619. fprint(2, "%s\n", __func__);
  620. }
  621. /* Stubs for the disassembler */
  622. __attribute__ ((weak))
  623. void
  624. MpSaveGpioInfo(ACPI_PARSE_OBJECT * Op,
  625. AML_RESOURCE * Resource,
  626. UINT32 PinCount, UINT16 * PinList, char *DeviceName)
  627. {
  628. if (debug)
  629. fprint(2, "%s\n", __func__);
  630. }
  631. __attribute__ ((weak))
  632. void
  633. MpSaveSerialInfo(ACPI_PARSE_OBJECT * Op,
  634. AML_RESOURCE * Resource, char *DeviceName)
  635. {
  636. if (debug)
  637. fprint(2, "%s\n", __func__);
  638. }
  639. int
  640. AcpiOsWriteFile(ACPI_FILE File, void *Buffer, ACPI_SIZE Size, ACPI_SIZE Count)
  641. {
  642. if (debug)
  643. fprint(2, "%s(%p, %p, %d, %d);\n", File, Buffer, Size, Count);
  644. return write(1, Buffer, Size * Count);
  645. }
  646. __attribute__ ((weak))
  647. void hexdump(void *v, int length)
  648. {
  649. int i;
  650. uint8_t *m = v;
  651. uintptr_t memory = (uintptr_t) v;
  652. int all_zero = 0;
  653. print("hexdump: %p, %u\n", v, length);
  654. for (i = 0; i < length; i += 16) {
  655. int j;
  656. all_zero++;
  657. for (j = 0; (j < 16) && (i + j < length); j++) {
  658. if (m[i + j] != 0) {
  659. all_zero = 0;
  660. break;
  661. }
  662. }
  663. if (all_zero < 2) {
  664. print("%p:", (void *)(memory + i));
  665. for (j = 0; j < 16; j++)
  666. print(" %02x", m[i + j]);
  667. print(" ");
  668. for (j = 0; j < 16; j++)
  669. print("%c", isprint(m[i + j]) ? m[i + j] : '.');
  670. print("\n");
  671. } else if (all_zero == 2) {
  672. print("...\n");
  673. }
  674. }
  675. }