9ns: Support SYS_access (XCC)
[akaros.git] / kern / include / acpi.h
index 0af238b..02b4df2 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -7,13 +7,60 @@
  * in the LICENSE file.
  */
 
-enum
-{
+/* -----------------------------------------------------------------------------
+ * ACPI is a table of tables. The tables define a hierarchy.
+ *
+ * From the hardware's perspective:
+ * Each table that we care about has a header, and the header has a
+ * length that includes the the length of all its subtables. So, even
+ * if you can't completely parse a table, you can find the next table.
+ *
+ * The process of parsing is to find the RSDP, and then for each subtable
+ * see what type it is and parse it. The process is recursive except for
+ * a few issues: The RSDP signature and header differs from the header of
+ * its subtables; their headers differ from the signatures of the tables
+ * they contain. As you walk down the tree, you need different parsers.
+ *
+ * The parser is recursive descent. Each parsing function takes a pointer
+ * to the parent of the node it is parsing and will attach itself to the parent
+ * via that pointer. Parsing functions are responsible for building the data
+ * structures that represent their node and recursive invocations of the parser
+ * for subtables.
+ *
+ * So, in this case, it's something like this:
+ *
+ * RSDP is the root. It has a standard header and size. You map that
+ * memory.  You find the first header, get its type and size, and
+ * parse as much of it as you can. Parsing will involve either a
+ * function or case statement for each element type. DMARs are complex
+ * and need functions; APICs are simple and we can get by with case
+ * statements.
+ *
+ * Each node in the tree is represented as a 'struct Atable'. This has a
+ * pointer to the actual node data, a type tag, a name, pointers to this
+ * node's children (if any) and a parent pointer. It also has a QID so that
+ * the entire structure can be exposed as a filesystem. The Atable doesn't
+ * contain any table data per se; it's metadata. The table pointer contains
+ * the table data as well as a pointer back to it's corresponding Atable.
+ *
+ * In the end we present a directory tree for #apic that looks, in this example:
+ * #acpi/DMAR/DRHD/0/{pretty,raw}
+ *
+ * 'cat pretty' will return JSON-encoded data described the element.
+ * 'cat raw' gets you the raw bytes.
+ */
+
+#pragma once
 
-       Sdthdrsz        = 36,   /* size of SDT header */
+#include <ns.h>
+#include <slice.h>
+
+enum {
+
+       Sdthdrsz = 36,                  /* size of SDT header */
 
        /* ACPI regions. Gas ids */
-       Rsysmem = 0,
+       Rsysmem = 0,
        Rsysio,
        Rpcicfg,
        Rembed,
@@ -21,126 +68,168 @@ enum
        Rcmos,
        Rpcibar,
        Ripmi,
-       Rfixedhw        = 0x7f,
+       Rfixedhw = 0x7f,
 
        /* ACPI PM1 control */
-       Pm1SciEn                = 0x1,          /* Generate SCI and not SMI */
+       Pm1SciEn = 0x1,                 /* Generate SCI and not SMI */
 
        /* ACPI tbdf as encoded in acpi region base addresses */
-       Rpciregshift    = 0,
-       Rpciregmask     = 0xFFFF,
-       Rpcifunshift    = 16,
-       Rpcifunmask     = 0xFFFF,
-       Rpcidevshift    = 32,
-       Rpcidevmask     = 0xFFFF,
-       Rpcibusshift    = 48,
-       Rpcibusmask     = 0xFFFF,
+       Rpciregshift = 0,
+       Rpciregmask = 0xFFFF,
+       Rpcifunshift = 16,
+       Rpcifunmask = 0xFFFF,
+       Rpcidevshift = 32,
+       Rpcidevmask = 0xFFFF,
+       Rpcibusshift = 48,
+       Rpcibusmask = 0xFFFF,
 
        /* Apic structure types */
-       ASlapic = 0,    /* processor local apic */
-       ASioapic,       /* I/O apic */
-       ASintovr,       /* Interrupt source override */
-       ASnmi,          /* NMI source */
-       ASlnmi,         /* local apic nmi */
-       ASladdr,        /* local apic address override */
-       ASiosapic,      /* I/O sapic */
-       ASlsapic,       /* local sapic */
-       ASintsrc,       /* platform interrupt sources */
-       ASlx2apic,      /* local x2 apic */
-       ASlx2nmi,       /* local x2 apic NMI */
+       ASlapic = 0,            /* processor local apic */
+       ASioapic,                       /* I/O apic */
+       ASintovr,                       /* Interrupt source override */
+       ASnmi,                          /* NMI source */
+       ASlnmi,                         /* local apic nmi */
+       ASladdr,                        /* local apic address override */
+       ASiosapic,                      /* I/O sapic */
+       ASlsapic,                       /* local sapic */
+       ASintsrc,                       /* platform interrupt sources */
+       ASlx2apic,                      /* local x2 apic */
+       ASlx2nmi,                       /* local x2 apic NMI */
 
        /* Apic flags */
-       AFbus   = 0,    /* polarity/trigger like in ISA */
-       AFhigh  = 1,    /* active high */
-       AFlow   = 3,    /* active low */
-       AFpmask = 3,    /* polarity bits */
-       AFedge  = 1<<2, /* edge triggered */
-       AFlevel = 3<<2, /* level triggered */
-       AFtmask = 3<<2, /* trigger bits */
+       AFbus = 0,                      /* polarity/trigger like in ISA */
+       AFhigh = 1,                     /* active high */
+       AFlow = 3,                      /* active low */
+       AFpmask = 3,            /* polarity bits */
+       AFedge = 1 << 2,        /* edge triggered */
+       AFlevel = 3 << 2,       /* level triggered */
+       AFtmask = 3 << 2,       /* trigger bits */
+
+       /* Table types. */
+       RSDP = 0,
+       SDTH,
+       RSDT,
+       FADT,
+       FACS,
+       DSDT,
+       SSDT,
+       MADT,
+       SBST,
+       XSDT,
+       ECDT,
+       SLIT,
+       SRAT,
+       CPEP,
+       MSCT,
+       RASF,
+       MPST,
+       PMTT,
+       BGRT,
+       FPDT,
+       GTDT,
+       HPET,
+       APIC,
+       DMAR,
+       /* DMAR types */
+       DRHD,
+       RMRR,
+       ATSR,
+       RHSA,
+       ANDD,
+       NACPITBLS,                      /* Number of ACPI tables */
 
        /* SRAT types */
-       SRlapic = 0,    /* Local apic/sapic affinity */
-       SRmem,          /* Memory affinity */
-       SRlx2apic,      /* x2 apic affinity */
+       SRlapic = 0,            /* Local apic/sapic affinity */
+       SRmem,                          /* Memory affinity */
+       SRlx2apic,                      /* x2 apic affinity */
 
-       /* Arg for _PIC */
-       Ppic = 0,       /* PIC interrupt model */
-       Papic,          /* APIC interrupt model */
-       Psapic,         /* SAPIC interrupt model */
+       /* Atable constants */
+       SIGSZ           = 4+1,  /* Size of the signature (including NUL) */
+       OEMIDSZ         = 6+1,  /* Size of the OEM ID (including NUL) */
+       OEMTBLIDSZ      = 8+1,  /* Size of the OEM Table ID (including NUL) */
 
+       /* Arg for _PIC */
+       Ppic = 0,                       /* PIC interrupt model */
+       Papic,                          /* APIC interrupt model */
+       Psapic,                         /* SAPIC interrupt model */
 
-       CMregion = 0,                   /* regio name spc base len accsz*/
+       CMregion = 0,           /* regio name spc base len accsz */
        CMgpe,                          /* gpe name id */
-
-       Qdir = 0,
-       Qctl,
-       Qtbl,
-       Qio,
 };
 
 /*
  * ACPI table (sw)
+ *
+ * This Atable struct corresponds to an interpretation of the standard header
+ * for all table types we support. It has a pointer to the converted data, i.e.
+ * the structs created by functions like acpimadt and so on. Note: althouh the
+ * various things in this are a superset of many ACPI table names (DRHD, DRHD
+ * scopes, etc). The raw data follows this header.
+ *
+ * Child entries in the table are kept in an array of pointers. Each entry has
+ * a pointer to it's logically "next" sibling, thus forming a linked list. But
+ * these lists are purely for convenience and all point to nodes within the
+ * same array.
  */
-struct Atable
-{
-       struct Atable*  next;           /* next table in list */
-       int     is64;           /* uses 64bits */
-       char    sig[5];         /* signature */
-       char    oemid[7];       /* oem id str. */
-       char    oemtblid[9];    /* oem tbl. id str. */
-       uint8_t* tbl;           /* pointer to table in memory */
-       long    dlen;           /* size of data in table, after Stdhdr */
+struct Atable {
+       struct qid qid;             /* QID corresponding to this table. */
+       struct qid rqid;                        /* This table's 'raw' QID. */
+       struct qid pqid;                        /* This table's 'pretty' QID. */
+       struct qid tqid;                        /* This table's 'table' QID. */
+       int type;                                       /* This table's type */
+       void *tbl;                                      /* pointer to the converted table, e.g. madt. */
+       char name[16];                          /* name of this table */
+
+       struct Atable *parent;          /* Parent pointer */
+       struct Atable **children;       /* children of this node (an array). */
+       struct dirtab *cdirs;           /* child directory entries of this node. */
+       size_t nchildren;                       /* count of this node's children */
+       struct Atable *next;            /* Pointer to the next sibling. */
+
+       size_t rawsize;                         /* Total size of raw table */
+       uint8_t *raw;                           /* Raw data. */
 };
 
-struct Gpe
-{
-       uintptr_t       stsio;          /* port used for status */
-       int     stsbit;         /* bit number */
-       uintptr_t       enio;           /* port used for enable */
-       int     enbit;          /* bit number */
-       int     nb;             /* event number */
-       char*   obj;            /* handler object  */
-       int     id;             /* id as supplied by user */
+struct Gpe {
+       uintptr_t stsio;                        /* port used for status */
+       int stsbit;                                     /* bit number */
+       uintptr_t enio;                         /* port used for enable */
+       int enbit;                                      /* bit number */
+       int nb;                                         /* event number */
+       char *obj;                                      /* handler object  */
+       int id;                                         /* id as supplied by user */
 };
 
-struct Parse
-{
-       char*   sig;
-       struct Atable*  (*f)( uint8_t *unused_uint8_p_t, int);  /* return NULL to keep vmap */
+struct Regio {
+       void *arg;
+       uint8_t (*get8)(uintptr_t, void *);
+       void (*set8)(uintptr_t, uint8_t unused_int, void *);
+       uint16_t (*get16)(uintptr_t, void *);
+       void (*set16)(uintptr_t, uint16_t unused_int, void *);
+       uint32_t (*get32)(uintptr_t, void *);
+       void (*set32)(uintptr_t, uint32_t, void *);
+       uint64_t (*get64)(uintptr_t, void *);
+       void (*set64)(uintptr_t, uint64_t unused_int, void *);
 };
 
-struct Regio{
-       void    *arg;
-       uint8_t (*get8)(uintptr_t, void*);
-       void    (*set8)(uintptr_t, uint8_t unused_int, void*);
-       uint16_t        (*get16)(uintptr_t, void*);
-       void    (*set16)(uintptr_t, uint16_t unused_int, void*);
-       uint32_t        (*get32)(uintptr_t, void*);
-       void    (*set32)(uintptr_t, uint32_t, void*);
-       uint64_t        (*get64)(uintptr_t, void*);
-       void    (*set64)(uintptr_t, uint64_t unused_int, void*);
+struct Reg {
+       char *name;
+       int spc;                                        /* io space */
+       uint64_t base;                          /* address, physical */
+       uint8_t *p;                                     /* address, kmapped */
+       uint64_t len;
+       int tbdf;
+       int accsz;                                      /* access size */
 };
 
-struct Reg
-{
-       char*   name;
-       int     spc;            /* io space */
-       uint64_t        base;           /* address, physical */
-       uint8_t*        p;              /* address, kmapped */
-       uint64_t        len;
-       int     tbdf;
-       int     accsz;          /* access size */
-};
-
-/* Generic address structure. 
+/* Generic address structure.
  */
-struct Gas
-{
-       uint8_t spc;    /* address space id */
-       uint8_t len;    /* register size in bits */
-       uint8_t off;    /* bit offset */
-       uint8_t accsz;  /* 1: byte; 2: word; 3: dword; 4: qword */
-       uint64_t        addr;   /* address (or acpi encoded tbdf + reg) */
+struct Gas {
+       uint8_t spc;                            /* address space id */
+       uint8_t len;                            /* register size in bits */
+       uint8_t off;                            /* bit offset */
+       uint8_t accsz;                          /* 1: byte; 2: word; 3: dword; 4: qword */
+       uint64_t addr;                          /* address (or acpi encoded tbdf + reg) */
 };
 
 /* Root system description table pointer.
@@ -152,67 +241,61 @@ struct Gas
  *     - SSDTs tables with AML code to add to the acpi namespace.
  *     - pointers to other tables for apics, etc.
  */
-
-struct Rsdp
-{
-       uint8_t signature[8];                   /* "RSD PTR " */
-       uint8_t rchecksum;
-       uint8_t oemid[6];
-       uint8_t revision;
-       uint8_t raddr[4];                       /* RSDT */
-       uint8_t length[4];
-       uint8_t xaddr[8];                       /* XSDT */
-       uint8_t xchecksum;                      /* XSDT */
-       uint8_t _33_[3];                        /* reserved */
+struct Rsdp {
+       uint8_t signature[8];           /* "RSD PTR " */
+       uint8_t rchecksum;
+       uint8_t oemid[6];
+       uint8_t revision;
+       uint8_t raddr[4];                       /* RSDT */
+       uint8_t length[4];
+       uint8_t xaddr[8];                       /* XSDT */
+       uint8_t xchecksum;                      /* XSDT */
+       uint8_t _reserved[3];                   /* reserved */
 };
 
 /* Header for ACPI description tables
  */
-struct Sdthdr
-{
-       uint8_t sig[4];                 /* "FACP" or whatever */
-       uint8_t length[4];
-       uint8_t rev;
-       uint8_t csum;
-       uint8_t oemid[6];
-       uint8_t oemtblid[8];
-       uint8_t oemrev[4];
-       uint8_t creatorid[4];
-       uint8_t creatorrev[4];
+struct Sdthdr {
+       uint8_t sig[4];                         /* "FACP" or whatever */
+       uint8_t length[4];
+       uint8_t rev;
+       uint8_t csum;
+       uint8_t oemid[6];
+       uint8_t oemtblid[8];
+       uint8_t oemrev[4];
+       uint8_t creatorid[4];
+       uint8_t creatorrev[4];
 };
 
 /* Firmware control structure
  */
-struct Facs
-{
-       uint32_t        hwsig;
-       uint32_t        wakingv;
-       uint32_t        glock;
-       uint32_t        flags;
-       uint64_t        xwakingv;
-       uint8_t vers;
-       uint32_t        ospmflags;
+struct Facs {
+       uint8_t sig[4];
+       uint8_t len[4];
+       uint32_t hwsig;
+       uint32_t wakingv;
+       uint32_t glock;
+       uint32_t flags;
+       uint64_t xwakingv;
+       uint8_t vers;
+       uint32_t ospmflags;
 };
 
-
 /* Maximum System Characteristics table
  */
-struct Msct
-{
-       int     ndoms;          /* number of domains */
-       int     nclkdoms;       /* number of clock domains */
-       uint64_t        maxpa;          /* max physical address */
-
-       struct Mdom*    dom;            /* domain information list */
+struct Msct {
+       int ndoms;                                      /* number of domains */
+       int nclkdoms;                           /* number of clock domains */
+       uint64_t maxpa;                         /* max physical address */
+       size_t nmdom;                           /* number of discovered domains */
+       struct Mdom *dom;                       /* array of domains */
 };
 
-struct Mdom
-{
-       struct Mdom*    next;
-       int     start;          /* start dom id */
-       int     end;            /* end dom id */
-       int     maxproc;        /* max processor capacity */
-       uint64_t        maxmem;         /* max memory capacity */
+struct Mdom {
+       int start;                                      /* start dom id */
+       int end;                                        /* end dom id */
+       int maxproc;                            /* max processor capacity */
+       uint64_t maxmem;                        /* max memory capacity */
 };
 
 /* Multiple APIC description table
@@ -221,93 +304,87 @@ struct Mdom
  * Addresses are processor-relative physical addresses.
  * Only enabled devices are linked, others are filtered out.
  */
-struct Madt
-{
-       uint64_t        lapicpa;                /* local APIC addr */
-       int     pcat;           /* the machine has PC/AT 8259s */
-       struct Apicst*  st;             /* list of Apic related structures */
+struct Madt {
+       uint64_t lapicpa;                       /* local APIC addr */
+       int pcat;                                       /* the machine has PC/AT 8259s */
 };
 
-struct Apicst
-{
-       int     type;
-       struct Apicst*  next;
-       union{
-               struct{
-                       int     pid;    /* processor id */
-                       int     id;     /* apic no */
+struct Apicst {
+       int type;
+       union {
+               struct {
+                       int pid;                        /* processor id */
+                       int id;                         /* apic no */
                } lapic;
-               struct{
-                       int     id;     /* io apic id */
-                       uint32_t        ibase;  /* interrupt base addr. */
-                       uint64_t        addr;   /* base address */
+               struct {
+                       int id;                         /* io apic id */
+                       uint32_t ibase;         /* interrupt base addr. */
+                       uint64_t addr;          /* base address */
                } ioapic, iosapic;
-               struct{
-                       int     irq;    /* bus intr. source (ISA only) */
-                       int     intr;   /* system interrupt */
-                       int     flags;  /* apic flags */
+               struct {
+                       int irq;                        /* bus intr. source (ISA only) */
+                       int intr;                       /* system interrupt */
+                       int flags;                      /* apic flags */
                } intovr;
-               struct{
-                       int     intr;   /* system interrupt */
-                       int     flags;  /* apic flags */
+               struct {
+                       int intr;                       /* system interrupt */
+                       int flags;                      /* apic flags */
                } nmi;
-               struct{
-                       int     pid;    /* processor id */
-                       int     flags;  /* lapic flags */
-                       int     lint;   /* lapic LINTn for nmi */
+               struct {
+                       int pid;                        /* processor id */
+                       int flags;                      /* lapic flags */
+                       int lint;                       /* lapic LINTn for nmi */
                } lnmi;
-               struct{
-                       int     pid;    /* processor id */
-                       int     id;     /* apic id */
-                       int     eid;    /* apic eid */
-                       int     puid;   /* processor uid */
-                       char*   puids;  /* same thing */
+               struct {
+                       int pid;                        /* processor id */
+                       int id;                         /* apic id */
+                       int eid;                        /* apic eid */
+                       int puid;                       /* processor uid */
+                       char *puids;            /* same thing */
                } lsapic;
-               struct{
-                       int     pid;    /* processor id */
-                       int     peid;   /* processor eid */
-                       int     iosv;   /* io sapic vector */
-                       int     intr;   /* global sys intr. */
-                       int     type;   /* intr type */
-                       int     flags;  /* apic flags */
-                       int     any;    /* err sts at any proc */
+               struct {
+                       int pid;                        /* processor id */
+                       int peid;                       /* processor eid */
+                       int iosv;                       /* io sapic vector */
+                       int intr;                       /* global sys intr. */
+                       int type;                       /* intr type */
+                       int flags;                      /* apic flags */
+                       int any;                        /* err sts at any proc */
                } intsrc;
-               struct{
-                       int     id;     /* x2 apic id */
-                       int     puid;   /* processor uid */
+               struct {
+                       int id;                         /* x2 apic id */
+                       int puid;                       /* processor uid */
                } lx2apic;
-               struct{
-                       int     puid;
-                       int     flags;
-                       int     intr;
+               struct {
+                       int puid;
+                       int flags;
+                       int intr;
                } lx2nmi;
        };
 };
 
 /* System resource affinity table
  */
-struct Srat
-{
-       int     type;
-       struct Srat*    next;
-       union{
-               struct{
-                       int     dom;    /* proximity domain */
-                       int     apic;   /* apic id */
-                       int     sapic;  /* sapic id */
-                       int     clkdom; /* clock domain */
+struct Srat {
+       int type;
+       union {
+               struct {
+                       int dom;                        /* proximity domain */
+                       int apic;                       /* apic id */
+                       int sapic;                      /* sapic id */
+                       int clkdom;                     /* clock domain */
                } lapic;
-               struct{
-                       int     dom;    /* proximity domain */
-                       uint64_t        addr;   /* base address */
-                       uint64_t        len;
-                       int     hplug;  /* hot pluggable */
-                       int     nvram;  /* non volatile */      
+               struct {
+                       int dom;                        /* proximity domain */
+                       uint64_t addr;          /* base address */
+                       uint64_t len;
+                       int hplug;                      /* hot pluggable */
+                       int nvram;                      /* non volatile */
                } mem;
-               struct{
-                       int     dom;    /* proximity domain */
-                       int     apic;   /* x2 apic id */
-                       int     clkdom; /* clock domain */
+               struct {
+                       int dom;                        /* proximity domain */
+                       int apic;                       /* x2 apic id */
+                       int clkdom;                     /* clock domain */
                } lx2apic;
        };
 };
@@ -320,8 +397,8 @@ struct Slit {
 };
 
 struct SlEntry {
-       int dom;        /* proximity domain */
-       unsigned int dist;      /* distance to proximity domain */
+       int dom;                                        /* proximity domain */
+       unsigned int dist;                      /* distance to proximity domain */
 };
 
 /* Fixed ACPI description table.
@@ -331,70 +408,109 @@ struct SlEntry {
  * P_* blocks are for processor features.
  * Has address for the DSDT.
  */
-struct Fadt
-{
-       uint32_t        facs;
-       uint32_t        dsdt;
+struct Fadt {
+       uint32_t facs;
+       uint32_t dsdt;
        /* 1 reserved */
-       uint8_t pmprofile;
-       uint16_t        sciint;
-       uint32_t        smicmd;
-       uint8_t acpienable;
-       uint8_t acpidisable;
-       uint8_t s4biosreq;
-       uint8_t pstatecnt;
-       uint32_t        pm1aevtblk;
-       uint32_t        pm1bevtblk;
-       uint32_t        pm1acntblk;
-       uint32_t        pm1bcntblk;
-       uint32_t        pm2cntblk;
-       uint32_t        pmtmrblk;
-       uint32_t        gpe0blk;
-       uint32_t        gpe1blk;
-       uint8_t pm1evtlen;
-       uint8_t pm1cntlen;
-       uint8_t pm2cntlen;
-       uint8_t pmtmrlen;
-       uint8_t gpe0blklen;
-       uint8_t gpe1blklen;
-       uint8_t gp1base;
-       uint8_t cstcnt;
-       uint16_t        plvl2lat;
-       uint16_t        plvl3lat;
-       uint16_t        flushsz;
-       uint16_t        flushstride;
-       uint8_t dutyoff;
-       uint8_t dutywidth;
-       uint8_t dayalrm;
-       uint8_t monalrm;
-       uint8_t century;
-       uint16_t        iapcbootarch;
+       uint8_t pmprofile;
+       uint16_t sciint;
+       uint32_t smicmd;
+       uint8_t acpienable;
+       uint8_t acpidisable;
+       uint8_t s4biosreq;
+       uint8_t pstatecnt;
+       uint32_t pm1aevtblk;
+       uint32_t pm1bevtblk;
+       uint32_t pm1acntblk;
+       uint32_t pm1bcntblk;
+       uint32_t pm2cntblk;
+       uint32_t pmtmrblk;
+       uint32_t gpe0blk;
+       uint32_t gpe1blk;
+       uint8_t pm1evtlen;
+       uint8_t pm1cntlen;
+       uint8_t pm2cntlen;
+       uint8_t pmtmrlen;
+       uint8_t gpe0blklen;
+       uint8_t gpe1blklen;
+       uint8_t gp1base;
+       uint8_t cstcnt;
+       uint16_t plvl2lat;
+       uint16_t plvl3lat;
+       uint16_t flushsz;
+       uint16_t flushstride;
+       uint8_t dutyoff;
+       uint8_t dutywidth;
+       uint8_t dayalrm;
+       uint8_t monalrm;
+       uint8_t century;
+       uint16_t iapcbootarch;
        /* 1 reserved */
-       uint32_t        flags;
-       struct Gas      resetreg;
-       uint8_t resetval;
+       uint32_t flags;
+       struct Gas resetreg;
+       uint8_t resetval;
        /* 3 reserved */
-       uint64_t        xfacs;
-       uint64_t        xdsdt;
-       struct Gas      xpm1aevtblk;
-       struct Gas      xpm1bevtblk;
-       struct Gas      xpm1acntblk;
-       struct Gas      xpm1bcntblk;
-       struct Gas      xpm2cntblk;
-       struct Gas      xpmtmrblk;
-       struct Gas      xgpe0blk;
-       struct Gas      xgpe1blk;
+       uint64_t xfacs;
+       uint64_t xdsdt;
+       struct Gas xpm1aevtblk;
+       struct Gas xpm1bevtblk;
+       struct Gas xpm1acntblk;
+       struct Gas xpm1bcntblk;
+       struct Gas xpm2cntblk;
+       struct Gas xpmtmrblk;
+       struct Gas xgpe0blk;
+       struct Gas xgpe1blk;
 };
 
 /* XSDT/RSDT. 4/8 byte addresses starting at p.
  */
-struct Xsdt
-{
-       int     len;
-       int     asize;
-       uint8_t*        p;
+struct Xsdt {
+       size_t len;
+       size_t asize;
+       uint8_t *p;
 };
 
-extern uintptr_t acpimblocksize(uintptr_t, int*);
+/* DMAR.
+ */
+/*
+ * Device scope.
+ */
+struct DevScope {
+       int enumeration_id;
+       int start_bus_number;
+       int npath;
+       int *paths;
+};
+/*
+ * The device scope is basic tbdf as uint32_t. There is a special value
+ * that means "everything" and if we see that we set "all" in the Drhd.
+ */
+struct Drhd {
+       int flags;
+       int segment;
+       uintptr_t rba;
+       uintptr_t all;  // This drhd scope is for everything.
+       size_t nscope;
+       struct DevScope *scopes;
+};
+
+struct Dmar {
+       int haw;
+       /*
+        * If your firmware disables x2apic mode, you should not be here.
+        * We ignore that bit.
+        */
+       int intr_remap;
+};
 
-void dumpGas(char *prefix, struct Gas *g);
+int acpiinit(void);
+struct Atable *mkatable(struct Atable *parent,
+                        int type, char *name, uint8_t *raw,
+                        size_t rawsize, size_t addsize);
+struct Atable *finatable(struct Atable *t, struct slice *slice);
+struct Atable *finatable_nochildren(struct Atable *t);
+int get_early_num_cores(void);
+
+extern struct Atable *apics;
+extern struct Atable *dmar;
+extern struct Atable *srat;