123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include <acpi.h>
- #define MiB (1<<20)
- BOOLEAN AcpiGbl_DebugTimeout = FALSE;
- static uint32_t rsdp;
- static char *name;
- /* debug prints for this file. You can set this in gdb or at compile time. */
- static int debug;
- #if 0
- static int
- xisprint(int c)
- {
- return (c >= 32 && c <= 126);
- }
- static void
- hexdump(void *v, int length)
- {
- int i;
- uint8_t *m = v;
- uintptr_t memory = (uintptr_t) v;
- int all_zero = 0;
- if (debug)
- fprint(2, "hexdump: %p, %u\n", v, length);
- for (i = 0; i < length; i += 16) {
- int j;
- all_zero++;
- for (j = 0; (j < 16) && (i + j < length); j++) {
- if (m[i + j] != 0) {
- all_zero = 0;
- break;
- }
- }
- if (all_zero < 2) {
- if (debug)
- fprint(2, "%p:", (void *)(memory + i));
- for (j = 0; j < 16; j++)
- if (debug)
- fprint(2, " %02x", m[i + j]);
- if (debug)
- fprint(2, " ");
- for (j = 0; j < 16; j++)
- if (debug)
- fprint(2, "%c", xisprint(m[i + j]) ? m[i + j] : '.');
- if (debug)
- fprint(2, "\n");
- } else if (all_zero == 2) {
- if (debug)
- fprint(2, "...\n");
- }
- }
- }
- #endif
- /* try several variants */
- static int
- rawfd(void)
- {
- int fd;
- if (name == nil) {
- name = "/dev/acpimem";
- if (debug)
- fprint(2, "Rawfd: open '%s'\n", name);
- fd = open(name, OREAD);
- if (fd > -1)
- return fd;
- name = "#P/acpimem";
- if (debug)
- fprint(2, "Rawfd: open '%s'\n", name);
- fd = open(name, OREAD);
- if (fd > -1)
- return fd;
- }
- return open(name, OREAD);
- }
- static int
- tbdf(ACPI_PCI_ID * p)
- {
- return (p->Bus << 8) | (p->Device << 3) | (p->Function);
- }
- int iol = -1, iow = -1, iob = -1;
- uint32_t
- inl(uint16_t addr)
- {
- uint64_t off = addr;
- uint32_t l;
- if (pread(iol, &l, 4, off) < 4)
- print("inl(0x%x): %r\n", addr);
- return l;
- }
- uint16_t
- ins(uint16_t addr)
- {
- uint64_t off = addr;
- uint16_t w;
- if (pread(iow, &w, 2, off) < 2)
- print("ins(0x%x): %r\n", addr);
- return w;
- }
- uint8_t
- inb(uint16_t addr)
- {
- uint64_t off = addr;
- uint16_t b;
- if (pread(iow, &b, 1, off) < 1)
- print("inb(0x%x): %r\n", addr);
- return b;
- }
- void
- outl(uint32_t val, uint16_t addr)
- {
- uint64_t off = addr;
- if (pwrite(iol, &val, 4, off) < 4)
- print("outl(0x%x): %r\n", addr);
- }
- void
- outs(uint16_t val, uint16_t addr)
- {
- uint64_t off = addr;
- if (pwrite(iow, &val, 2, off) < 2)
- print("outs(0x%x): %r\n", addr);
- }
- void
- outb(uint8_t val, uint16_t addr)
- {
- uint64_t off = addr;
- if (pwrite(iob, &val, 1, off) < 1)
- print("outb(0x%x): %r\n", addr);
- }
- #define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
- #define BUSFNO(tbdf) (((tbdf)>>8)&0x07)
- #define BUSDNO(tbdf) (((tbdf)>>11)&0x1F)
- #define BUSBNO(tbdf) (((tbdf)>>16)&0xFF)
- #define BUSTYPE(tbdf) ((tbdf)>>24)
- #define BUSBDF(tbdf) ((tbdf)&0x00FFFF00)
- ACPI_STATUS
- AcpiOsReadPciConfiguration(ACPI_PCI_ID * PciId,
- UINT32 Reg, UINT64 * Value, UINT32 Width)
- {
- ACPI_STATUS ret = AE_OK;
- uint64_t val;
- int amt;
- static char path[128];
- snprint(path, sizeof(path), "/dev/pci/%d.%d.%draw", PciId->Bus,
- PciId->Device, PciId->Function);
- int fd = open(path, OREAD);
- if (fd < 0) {
- if (debug)
- print("%s: open %s: %r\n", __func__, path);
- return AE_IO_ERROR;
- }
- switch (Width) {
- case 32:
- case 16:
- case 8:
- amt = pread(fd, Value, Width / 8, Reg);
- if (amt < Width / 8)
- ret = AE_IO_ERROR;
- break;
- default:
- sysfatal("Can't read pci: bad width %d\n", Width);
- }
- close(fd);
- if (amt > 0)
- memmove(&val, Value, amt);
- if (debug)
- fprint(2, "pciread 0x%x 0x%x 0x%x 0x%x/%d 0x%x %d\n", PciId->Bus,
- PciId->Device, PciId->Function, Reg, Width / 8, *Value, ret);
- return ret;
- }
- ACPI_STATUS
- AcpiOsWritePciConfiguration(ACPI_PCI_ID * PciId,
- UINT32 Reg, UINT64 Value, UINT32 Width)
- {
- ACPI_STATUS ret = AE_OK;
- int amt;
- static char path[128];
- snprint(path, sizeof(path), "/dev/pci/%d.%d.%draw", PciId->Bus,
- PciId->Device, PciId->Function);
- int fd = open(path, ORDWR);
- if (fd < 0) {
- print("%s: open %s: %r\n", __func__, path);
- return AE_IO_ERROR;
- }
- switch (Width) {
- case 32:
- case 16:
- case 8:
- amt = pwrite(fd, &Value, Width / 8, Reg);
- if (amt < Width / 8)
- ret = AE_IO_ERROR;
- break;
- default:
- sysfatal("Can't read pci: bad width %d\n", Width);
- }
- close(fd);
- if (debug)
- fprint(2, "pciwrite 0x%x 0x%x 0x%x 0x%x/%d 0x%x %d\n", PciId->Bus,
- PciId->Device, PciId->Function, Reg, Width / 8, Value, ret);
- return ret;
- }
- /*
- * Miscellaneous
- */
- BOOLEAN
- AcpiOsReadable(void *Pointer, ACPI_SIZE Length)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- BOOLEAN
- AcpiOsWritable(void *Pointer, ACPI_SIZE Length)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- UINT64
- AcpiOsGetTimer(void)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsSignal(UINT32 Function, void *Info)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- /* N.B. Only works for single thread! */
- void ACPI_INTERNAL_VAR_XFACE
- AcpiOsPrintf(const char *Format, ...)
- {
- static char buf[65536];
- va_list args;
- va_start(args, Format);
- vseprint(buf, &buf[65535], (char *)Format, args);
- va_end(args);
- if (debug)
- fprint(2, buf);
- }
- void
- AcpiOsVprintf(const char *Format, va_list Args)
- {
- /* This is a leaf function, and this function is required to implement
- * the va_list argument. I couldn't find any other way to do this. */
- static char buf[1024];
- vseprint(buf, &buf[1023], (char *)Format, Args);
- if (debug)
- fprint(2, buf);
- }
- void
- AcpiOsFree(void *Memory)
- {
- //fprint(2,"%s\n", __func__);
- free(Memory);
- }
- void *
- AcpiOsAllocate(ACPI_SIZE Size)
- {
- //fprint(2,"%s\n", __func__);
- return malloc(Size);
- }
- void hexdump(void *v, int length);
- void *
- AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
- {
- int fd, amt;
- fd = rawfd();
- if (debug)
- fprint(2, "%s %p %d\n", __func__, (void *)Where, Length);
- void *v = malloc(Length);
- if (!v) {
- sysfatal("%s: %r", __func__);
- return nil;
- }
- fd = rawfd();
- if (fd < 0) {
- if (debug)
- fprint(2, "%s: open %s: %r\n", __func__, name);
- return nil;
- }
- amt = pread(fd, v, Length, Where);
- close(fd);
- /* If we just do the amt < Length test, it will not work when
- * amt is -1. Length is uint64_t. */
- if ((amt < 0) || (amt < Length)) {
- free(v);
- if (debug)
- fprint(2, "%s: read %s: %r\n", __func__, name);
- return nil;
- }
- //hexdump(v, Length);
- //hexdump(v, 36);
- return v;
- }
- void
- AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size)
- {
- free(LogicalAddress);
- if (debug)
- fprint(2, "%s %p %d \n", __func__, LogicalAddress, Size);
- }
- ACPI_STATUS
- AcpiOsGetPhysicalAddress(void *LogicalAddress,
- ACPI_PHYSICAL_ADDRESS * PhysicalAddress)
- {
- ACPI_PHYSICAL_ADDRESS ret = (uintptr_t) LogicalAddress;
- if (debug)
- fprint(2, "%s %p = %p", __func__, (void *)ret, LogicalAddress);
- *PhysicalAddress = ret;
- return AE_OK;
- }
- /* This is the single threaded version of
- * these functions. This is now NetBSD does it. */
- ACPI_STATUS
- AcpiOsCreateSemaphore(UINT32 MaxUnits,
- UINT32 InitialUnits, ACPI_SEMAPHORE * OutHandle)
- {
- //fprint(2,"%s\n", __func__);
- *OutHandle = (ACPI_SEMAPHORE) 1;
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
- {
- //fprint(2,"%s\n", __func__);
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
- {
- //fprint(2,"%s\n", __func__);
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
- {
- //fprint(2,"%s\n", __func__);
- return AE_OK;
- }
- /* this is the single threaded case and as minix shows there is nothing to do. */
- ACPI_STATUS
- AcpiOsCreateLock(ACPI_SPINLOCK * OutHandle)
- {
- //fprint(2,"%s\n", __func__);
- *OutHandle = nil;
- return AE_OK;
- }
- void
- AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
- {
- //fprint(2,"%s\n", __func__);
- }
- ACPI_CPU_FLAGS
- AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
- {
- //fprint(2,"%s\n", __func__);
- return 0;
- }
- void
- AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
- {
- //fprint(2,"%s\n", __func__);
- }
- struct handler {
- ACPI_OSD_HANDLER ServiceRoutine;
- void *Context;
- };
- #if 0
- /* The ACPI interrupt signature and the Harvey one are not compatible. So, we pass an arg to
- * intrenable that can in turn be used to this function to call the ACPI handler. */
- static void
- acpihandler(void *_, void *arg)
- {
- struct handler *h = arg;
- h->ServiceRoutine(h->Context);
- }
- #endif
- ACPI_STATUS
- AcpiOsInstallInterruptHandler(UINT32 InterruptNumber,
- ACPI_OSD_HANDLER ServiceRoutine, void *Context)
- {
- /* minix says "don't do it". So we don't, yet. */
- return AE_OK;
- struct handler *h = malloc(sizeof(*h));
- if (!h)
- return AE_NO_MEMORY;
- h->ServiceRoutine = ServiceRoutine;
- h->Context = Context;
- if (debug)
- fprint(2, "NOT DOING %s %d %p %p \n", __func__, InterruptNumber,
- ServiceRoutine, Context);
- /* once enabled, can't be disabled; ignore the return value unless it's nil. */
- //intrenable(InterruptNumber, acpihandler, h, 0x5, "ACPI interrupt handler");
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber,
- ACPI_OSD_HANDLER ServiceRoutine)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- void
- AcpiOsWaitEventsComplete(void)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- }
- void
- AcpiOsSleep(UINT64 Milliseconds)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sleep(Milliseconds);
- }
- void
- AcpiOsStall(UINT32 Microseconds)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sleep(Microseconds / 1000 + 1);
- }
- ACPI_THREAD_ID
- AcpiOsGetThreadId(void)
- {
- static int pid = 2525;
- if (pid < 0)
- pid = getpid();
- return pid;
- }
- ACPI_STATUS
- AcpiOsExecute(ACPI_EXECUTE_TYPE Type,
- ACPI_OSD_EXEC_CALLBACK Function, void *Context)
- {
- ACPI_STATUS ret = AE_OK;
- if (debug)
- fprint(2, "%s\n", __func__);
- Function(Context);
- return ret;
- }
- ACPI_STATUS
- AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 * Value, UINT32 Width)
- {
- switch (Width) {
- case 4 * 8:
- *Value = inl(Address);
- break;
- case 2 * 8:
- *Value = ins(Address);
- break;
- case 1 * 8:
- *Value = inb(Address);
- break;
- default:
- sysfatal("%s, bad width %d", __func__, Width);
- break;
- }
- if (debug)
- fprint(2, "%s 0x%x 0x%x\n", __func__, Address, *Value);
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
- {
- switch (Width) {
- case 4 * 8:
- outl(Address, Value);
- break;
- case 2 * 8:
- outs(Address, Value);
- break;
- case 1 * 8:
- outb(Address, Value);
- break;
- default:
- sysfatal("%s, bad width %d", __func__, Width);
- break;
- }
- if (debug)
- fprint(2, "%s 0x%x 0x%x\n", __func__, Address, Value);
- return AE_OK;
- }
- /*
- * Platform and hardware-independent physical memory interfaces
- */
- ACPI_STATUS
- AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 * Value, UINT32 Width)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- sysfatal("%s", __func__);
- return AE_OK;
- }
- /* Just try to read the rsdp, if that fails, we're screwed anyway. */
- ACPI_STATUS
- AcpiOsInitialize(void)
- {
- int fd, amt;
- if (debug)
- fprint(2, "%s\n", __func__);
- fd = rawfd();
- if (fd < 0) {
- if (debug)
- fprint(2, "%s: open %s: %r\n", __func__, name);
- return AE_ERROR;
- }
- amt = read(fd, &rsdp, sizeof(rsdp));
- if (amt < sizeof(rsdp)) {
- if (debug)
- fprint(2, "%s: read %s: %r\n", __func__, name);
- return AE_ERROR;
- }
- close(fd);
- iol = open("/dev/iol", ORDWR);
- if (iol < 0)
- sysfatal("iol: %r");
- iow = open("/dev/iow", ORDWR);
- if (iow < 0)
- sysfatal("iow: %r");
- iob = open("/dev/iob", ORDWR);
- if (iob < 0)
- sysfatal("iob: %r");
- return AE_OK;
- }
- /*
- * ACPI Table interfaces
- */
- __attribute__ ((weak))ACPI_PHYSICAL_ADDRESS
- AcpiOsGetRootPointer(void)
- {
- if (debug)
- fprint(2, "%s returns %p\n", __func__, rsdp);
- return (ACPI_PHYSICAL_ADDRESS) rsdp;
- }
- ACPI_STATUS
- AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES * InitVal,
- ACPI_STRING * NewVal)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- *NewVal = nil;
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsTableOverride(ACPI_TABLE_HEADER * ExistingTable,
- ACPI_TABLE_HEADER ** NewTable)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- *NewTable = nil;
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER * ExistingTable,
- ACPI_PHYSICAL_ADDRESS * NewAddress,
- UINT32 * NewTableLength)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- *NewAddress = (ACPI_PHYSICAL_ADDRESS) nil;
- return AE_OK;
- }
- /*
- * Debug input
- */
- ACPI_STATUS
- AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 * BytesRead)
- {
- int amt;
- if (debug)
- fprint(2, "%s\n", __func__);
- amt = read(0, Buffer, BufferLength);
- if (BytesRead)
- *BytesRead = amt;
- return AE_OK;
- }
- ACPI_STATUS
- AcpiOsTerminate(void)
- {
- sysfatal("%s\n", __func__);
- return AE_OK;
- }
- /* Another acpica failure of vision: code in libraries that depends on functions defined only
- * in the compiler or other programs. Really! What to do?
- * this is how the acpi tools do it. Save we add a print so we know the function is called, duh! */
- typedef void *ACPI_PARSE_OBJECT;
- typedef void *AML_RESOURCE;
- /* this is from acpiexec. */
- /* For AcpiExec only */
- __attribute__ ((weak))void
- AeDoObjectOverrides(void)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- }
- /* Stubs for the disassembler */
- __attribute__ ((weak))
- void
- MpSaveGpioInfo(ACPI_PARSE_OBJECT * Op,
- AML_RESOURCE * Resource,
- UINT32 PinCount, UINT16 * PinList, char *DeviceName)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- }
- __attribute__ ((weak))
- void
- MpSaveSerialInfo(ACPI_PARSE_OBJECT * Op,
- AML_RESOURCE * Resource, char *DeviceName)
- {
- if (debug)
- fprint(2, "%s\n", __func__);
- }
- int
- AcpiOsWriteFile(ACPI_FILE File, void *Buffer, ACPI_SIZE Size, ACPI_SIZE Count)
- {
- if (debug)
- fprint(2, "%s(%p, %p, %d, %d);\n", File, Buffer, Size, Count);
- return write(1, Buffer, Size * Count);
- }
- __attribute__ ((weak))
- void hexdump(void *v, int length)
- {
- int i;
- uint8_t *m = v;
- uintptr_t memory = (uintptr_t) v;
- int all_zero = 0;
- print("hexdump: %p, %u\n", v, length);
- for (i = 0; i < length; i += 16) {
- int j;
- all_zero++;
- for (j = 0; (j < 16) && (i + j < length); j++) {
- if (m[i + j] != 0) {
- all_zero = 0;
- break;
- }
- }
- if (all_zero < 2) {
- print("%p:", (void *)(memory + i));
- for (j = 0; j < 16; j++)
- print(" %02x", m[i + j]);
- print(" ");
- for (j = 0; j < 16; j++)
- print("%c", isprint(m[i + j]) ? m[i + j] : '.');
- print("\n");
- } else if (all_zero == 2) {
- print("...\n");
- }
- }
- }
|