vmm: refactor userspace's emsr_fakewrite()
[akaros.git] / kern / include / acpi.h
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
10 /* -----------------------------------------------------------------------------
11  * ACPI is a table of tables. The tables define a hierarchy.
12  *
13  * From the hardware's perspective:
14  * Each table that we care about has a header, and the header has a
15  * length that includes the the length of all its subtables. So, even
16  * if you can't completely parse a table, you can find the next table.
17  *
18  * The process of parsing is to find the RSDP, and then for each subtable
19  * see what type it is and parse it. The process is recursive except for
20  * a few issues: The RSDP signature and header differs from the header of
21  * its subtables; their headers differ from the signatures of the tables
22  * they contain. As you walk down the tree, you need different parsers.
23  *
24  * The parser is recursive descent. Each parsing function takes a pointer
25  * to the parent of the node it is parsing and will attach itself to the parent
26  * via that pointer. Parsing functions are responsible for building the data
27  * structures that represent their node and recursive invocations of the parser
28  * for subtables.
29  *
30  * So, in this case, it's something like this:
31  *
32  * RSDP is the root. It has a standard header and size. You map that
33  * memory.  You find the first header, get its type and size, and
34  * parse as much of it as you can. Parsing will involve either a
35  * function or case statement for each element type. DMARs are complex
36  * and need functions; APICs are simple and we can get by with case
37  * statements.
38  *
39  * Each node in the tree is represented as a 'struct Atable'. This has a
40  * pointer to the actual node data, a type tag, a name, pointers to this
41  * node's children (if any) and a parent pointer. It also has a QID so that
42  * the entire structure can be exposed as a filesystem. The Atable doesn't
43  * contain any table data per se; it's metadata. The table pointer contains
44  * the table data as well as a pointer back to it's corresponding Atable.
45  *
46  * In the end we present a directory tree for #apic that looks, in this example:
47  * #acpi/DMAR/DRHD/0/{pretty,raw}
48  *
49  * 'cat pretty' will return JSON-encoded data described the element.
50  * 'cat raw' gets you the raw bytes.
51  */
52
53 #pragma once
54
55 #include <ns.h>
56 #include <slice.h>
57 #include <arch/intel-iommu.h>
58
59 enum {
60
61         Sdthdrsz = 36,          /* size of SDT header */
62
63         /* ACPI regions. Gas ids */
64         Rsysmem = 0,
65         Rsysio,
66         Rpcicfg,
67         Rembed,
68         Rsmbus,
69         Rcmos,
70         Rpcibar,
71         Ripmi,
72         Rfixedhw = 0x7f,
73
74         /* ACPI PM1 control */
75         Pm1SciEn = 0x1,         /* Generate SCI and not SMI */
76
77         /* ACPI tbdf as encoded in acpi region base addresses */
78         Rpciregshift = 0,
79         Rpciregmask = 0xFFFF,
80         Rpcifunshift = 16,
81         Rpcifunmask = 0xFFFF,
82         Rpcidevshift = 32,
83         Rpcidevmask = 0xFFFF,
84         Rpcibusshift = 48,
85         Rpcibusmask = 0xFFFF,
86
87         /* Apic structure types */
88         ASlapic = 0,            /* processor local apic */
89         ASioapic,               /* I/O apic */
90         ASintovr,               /* Interrupt source override */
91         ASnmi,                  /* NMI source */
92         ASlnmi,                 /* local apic nmi */
93         ASladdr,                /* local apic address override */
94         ASiosapic,              /* I/O sapic */
95         ASlsapic,               /* local sapic */
96         ASintsrc,               /* platform interrupt sources */
97         ASlx2apic,              /* local x2 apic */
98         ASlx2nmi,               /* local x2 apic NMI */
99
100         /* Apic flags */
101         AFbus = 0,              /* polarity/trigger like in ISA */
102         AFhigh = 1,             /* active high */
103         AFlow = 3,              /* active low */
104         AFpmask = 3,            /* polarity bits */
105         AFedge = 1 << 2,        /* edge triggered */
106         AFlevel = 3 << 2,       /* level triggered */
107         AFtmask = 3 << 2,       /* trigger bits */
108
109         /* Table types. */
110         RSDP = 0,
111         SDTH,
112         RSDT,
113         FADT,
114         FACS,
115         DSDT,
116         SSDT,
117         MADT,
118         SBST,
119         XSDT,
120         ECDT,
121         SLIT,
122         SRAT,
123         CPEP,
124         MSCT,
125         RASF,
126         MPST,
127         PMTT,
128         BGRT,
129         FPDT,
130         GTDT,
131         HPET,
132         APIC,
133         DMAR,
134         MCFG,
135         /* DMAR types */
136         DRHD,
137         RMRR,
138         ATSR,
139         RHSA,
140         ANDD,
141         NACPITBLS,              /* Number of ACPI tables */
142
143         /* SRAT types */
144         SRlapic = 0,            /* Local apic/sapic affinity */
145         SRmem,                  /* Memory affinity */
146         SRlx2apic,              /* x2 apic affinity */
147
148         /* Atable constants */
149         SIGSZ           = 4+1,  /* Size of the signature (including NUL) */
150         OEMIDSZ         = 6+1,  /* Size of the OEM ID (including NUL) */
151         OEMTBLIDSZ      = 8+1,  /* Size of the OEM Table ID (including NUL) */
152
153         /* Arg for _PIC */
154         Ppic = 0,               /* PIC interrupt model */
155         Papic,                  /* APIC interrupt model */
156         Psapic,                 /* SAPIC interrupt model */
157
158         CMregion = 0,           /* regio name spc base len accsz */
159         CMgpe,                  /* gpe name id */
160 };
161
162 /*
163  * ACPI table (sw)
164  *
165  * This Atable struct corresponds to an interpretation of the standard header
166  * for all table types we support. It has a pointer to the converted data, i.e.
167  * the structs created by functions like acpimadt and so on. Note: althouh the
168  * various things in this are a superset of many ACPI table names (DRHD, DRHD
169  * scopes, etc). The raw data follows this header.
170  *
171  * Child entries in the table are kept in an array of pointers. Each entry has
172  * a pointer to it's logically "next" sibling, thus forming a linked list. But
173  * these lists are purely for convenience and all point to nodes within the
174  * same array.
175  */
176 struct Atable {
177         struct qid qid;         /* QID corresponding to this table. */
178         struct qid rqid;        /* This table's 'raw' QID. */
179         struct qid pqid;        /* This table's 'pretty' QID. */
180         struct qid tqid;        /* This table's 'table' QID. */
181         int type;               /* This table's type */
182         void *tbl;              /* pointer to the converted table, e.g. madt. */
183         char name[16];          /* name of this table */
184
185         struct Atable *parent;  /* Parent pointer */
186         struct Atable **children; /* children of this node (an array). */
187         struct dirtab *cdirs;   /* child directory entries of this node. */
188         size_t nchildren;       /* count of this node's children */
189         struct Atable *next;    /* Pointer to the next sibling. */
190
191         size_t rawsize;         /* Total size of raw table */
192         uint8_t *raw;           /* Raw data. */
193 };
194
195 struct Gpe {
196         uintptr_t stsio;        /* port used for status */
197         int stsbit;             /* bit number */
198         uintptr_t enio;         /* port used for enable */
199         int enbit;              /* bit number */
200         int nb;                 /* event number */
201         char *obj;              /* handler object  */
202         int id;                 /* id as supplied by user */
203 };
204
205 struct Regio {
206         void *arg;
207         uint8_t (*get8)(uintptr_t, void *);
208         void (*set8)(uintptr_t, uint8_t unused_int, void *);
209         uint16_t (*get16)(uintptr_t, void *);
210         void (*set16)(uintptr_t, uint16_t unused_int, void *);
211         uint32_t (*get32)(uintptr_t, void *);
212         void (*set32)(uintptr_t, uint32_t, void *);
213         uint64_t (*get64)(uintptr_t, void *);
214         void (*set64)(uintptr_t, uint64_t unused_int, void *);
215 };
216
217 struct Reg {
218         char *name;
219         int spc;                /* io space */
220         uint64_t base;          /* address, physical */
221         uint8_t *p;             /* address, kmapped */
222         uint64_t len;
223         int tbdf;
224         int accsz;              /* access size */
225 };
226
227 /* Generic address structure.
228  */
229 struct Gas {
230         uint8_t spc;            /* address space id */
231         uint8_t len;            /* register size in bits */
232         uint8_t off;            /* bit offset */
233         uint8_t accsz;          /* 1: byte; 2: word; 3: dword; 4: qword */
234         uint64_t addr;          /* address (or acpi encoded tbdf + reg) */
235 };
236
237 /* Root system description table pointer.
238  * Used to locate the root system description table RSDT
239  * (or the extended system description table from version 2) XSDT.
240  * The XDST contains (after the DST header) a list of pointers to tables:
241  *      - FADT  fixed acpi description table.
242  *              It points to the DSDT, AML code making the acpi namespace.
243  *      - SSDTs tables with AML code to add to the acpi namespace.
244  *      - pointers to other tables for apics, etc.
245  */
246 struct Rsdp {
247         uint8_t signature[8];   /* "RSD PTR " */
248         uint8_t rchecksum;
249         uint8_t oemid[6];
250         uint8_t revision;
251         uint8_t raddr[4];       /* RSDT */
252         uint8_t length[4];
253         uint8_t xaddr[8];       /* XSDT */
254         uint8_t xchecksum;      /* XSDT */
255         uint8_t _reserved[3];   /* reserved */
256 };
257
258 /* Header for ACPI description tables
259  */
260 struct Sdthdr {
261         uint8_t sig[4];         /* "FACP" or whatever */
262         uint8_t length[4];
263         uint8_t rev;
264         uint8_t csum;
265         uint8_t oemid[6];
266         uint8_t oemtblid[8];
267         uint8_t oemrev[4];
268         uint8_t creatorid[4];
269         uint8_t creatorrev[4];
270 };
271
272 /* Firmware control structure
273  */
274 struct Facs {
275         uint8_t sig[4];
276         uint8_t len[4];
277         uint32_t hwsig;
278         uint32_t wakingv;
279         uint32_t glock;
280         uint32_t flags;
281         uint64_t xwakingv;
282         uint8_t vers;
283         uint32_t ospmflags;
284 };
285
286 /* Maximum System Characteristics table
287  */
288 struct Msct {
289         int ndoms;              /* number of domains */
290         int nclkdoms;           /* number of clock domains */
291         uint64_t maxpa;         /* max physical address */
292         size_t nmdom;           /* number of discovered domains */
293         struct Mdom *dom;       /* array of domains */
294 };
295
296 struct Mdom {
297         int start;              /* start dom id */
298         int end;                /* end dom id */
299         int maxproc;            /* max processor capacity */
300         uint64_t maxmem;        /* max memory capacity */
301 };
302
303 /* Multiple APIC description table
304  * Interrupts are virtualized by ACPI and each APIC has
305  * a `virtual interrupt base' where its interrupts start.
306  * Addresses are processor-relative physical addresses.
307  * Only enabled devices are linked, others are filtered out.
308  */
309 struct Madt {
310         uint64_t lapicpa;       /* local APIC addr */
311         int pcat;               /* the machine has PC/AT 8259s */
312 };
313
314 struct Apicst {
315         int type;
316         union {
317                 struct {
318                         int pid;                /* processor id */
319                         int id;                 /* apic no */
320                 } lapic;
321                 struct {
322                         int id;                 /* io apic id */
323                         uint32_t ibase;         /* interrupt base addr. */
324                         uint64_t addr;          /* base address */
325                 } ioapic, iosapic;
326                 struct {
327                         int irq;                /* bus intr. source (ISA only) */
328                         int intr;               /* system interrupt */
329                         int flags;              /* apic flags */
330                 } intovr;
331                 struct {
332                         int intr;               /* system interrupt */
333                         int flags;              /* apic flags */
334                 } nmi;
335                 struct {
336                         int pid;                /* processor id */
337                         int flags;              /* lapic flags */
338                         int lint;               /* lapic LINTn for nmi */
339                 } lnmi;
340                 struct {
341                         int pid;                /* processor id */
342                         int id;                 /* apic id */
343                         int eid;                /* apic eid */
344                         int puid;               /* processor uid */
345                         char *puids;            /* same thing */
346                 } lsapic;
347                 struct {
348                         int pid;                /* processor id */
349                         int peid;               /* processor eid */
350                         int iosv;               /* io sapic vector */
351                         int intr;               /* global sys intr. */
352                         int type;               /* intr type */
353                         int flags;              /* apic flags */
354                         int any;                /* err sts at any proc */
355                 } intsrc;
356                 struct {
357                         int id;                 /* x2 apic id */
358                         int puid;               /* processor uid */
359                 } lx2apic;
360                 struct {
361                         int puid;
362                         int flags;
363                         int intr;
364                 } lx2nmi;
365         };
366 };
367
368 /* System resource affinity table
369  */
370 struct Srat {
371         int type;
372         union {
373                 struct {
374                         int dom;                /* proximity domain */
375                         int apic;               /* apic id */
376                         int sapic;              /* sapic id */
377                         int clkdom;             /* clock domain */
378                 } lapic;
379                 struct {
380                         int dom;                /* proximity domain */
381                         uint64_t addr;          /* base address */
382                         uint64_t len;
383                         int hplug;              /* hot pluggable */
384                         int nvram;              /* non volatile */
385                 } mem;
386                 struct {
387                         int dom;                /* proximity domain */
388                         int apic;               /* x2 apic id */
389                         int clkdom;             /* clock domain */
390                 } lx2apic;
391         };
392 };
393
394 /* System locality information table
395  */
396 struct Slit {
397         uint64_t rowlen;
398         struct SlEntry **e;
399 };
400
401 struct SlEntry {
402         int dom;                        /* proximity domain */
403         unsigned int dist;              /* distance to proximity domain */
404 };
405
406 /* Fixed ACPI description table.
407  * Describes implementation and hardware registers.
408  * PM* blocks are low level functions.
409  * GPE* blocks refer to general purpose events.
410  * P_* blocks are for processor features.
411  * Has address for the DSDT.
412  */
413 struct Fadt {
414         uint32_t facs;
415         uint32_t dsdt;
416         /* 1 reserved */
417         uint8_t pmprofile;
418         uint16_t sciint;
419         uint32_t smicmd;
420         uint8_t acpienable;
421         uint8_t acpidisable;
422         uint8_t s4biosreq;
423         uint8_t pstatecnt;
424         uint32_t pm1aevtblk;
425         uint32_t pm1bevtblk;
426         uint32_t pm1acntblk;
427         uint32_t pm1bcntblk;
428         uint32_t pm2cntblk;
429         uint32_t pmtmrblk;
430         uint32_t gpe0blk;
431         uint32_t gpe1blk;
432         uint8_t pm1evtlen;
433         uint8_t pm1cntlen;
434         uint8_t pm2cntlen;
435         uint8_t pmtmrlen;
436         uint8_t gpe0blklen;
437         uint8_t gpe1blklen;
438         uint8_t gp1base;
439         uint8_t cstcnt;
440         uint16_t plvl2lat;
441         uint16_t plvl3lat;
442         uint16_t flushsz;
443         uint16_t flushstride;
444         uint8_t dutyoff;
445         uint8_t dutywidth;
446         uint8_t dayalrm;
447         uint8_t monalrm;
448         uint8_t century;
449         uint16_t iapcbootarch;
450         /* 1 reserved */
451         uint32_t flags;
452         struct Gas resetreg;
453         uint8_t resetval;
454         /* 3 reserved */
455         uint64_t xfacs;
456         uint64_t xdsdt;
457         struct Gas xpm1aevtblk;
458         struct Gas xpm1bevtblk;
459         struct Gas xpm1acntblk;
460         struct Gas xpm1bcntblk;
461         struct Gas xpm2cntblk;
462         struct Gas xpmtmrblk;
463         struct Gas xgpe0blk;
464         struct Gas xgpe1blk;
465 };
466
467 /* XSDT/RSDT. 4/8 byte addresses starting at p.
468  */
469 struct Xsdt {
470         size_t len;
471         size_t asize;
472         uint8_t *p;
473 };
474
475 /* DMAR.
476  */
477 /*
478  * Device scope.
479  */
480 struct DevScope {
481         int enumeration_id;
482         int start_bus_number;
483         int npath;
484         int *paths;
485 };
486 /*
487  * The device scope is basic tbdf as uint32_t. There is a special value
488  * that means "everything" and if we see that we set "all" in the Drhd.
489  */
490 struct Drhd {
491         int flags;
492         int segment;
493         uintptr_t rba;
494         uintptr_t all;  // This drhd scope is for everything.
495         size_t nscope;
496         struct DevScope *scopes;
497         struct iommu iommu; /* not part of the ACPI table */
498 };
499
500 struct Dmar {
501         int haw;
502         /*
503          * If your firmware disables x2apic mode, you should not be here.
504          * We ignore that bit.
505          */
506         int intr_remap;
507 };
508
509 struct acpi_mcfg {
510         uint8_t sig[4];
511         uint8_t length[4];
512         uint8_t rev;
513         uint8_t csum;
514         uint8_t oemid[6];
515         uint8_t oemtblid[8];
516         uint8_t oemrev[4];
517         uint8_t creatorid[4];
518         uint8_t creatorrev[4];
519         uint8_t _pad[8];
520         uint8_t entries[0];
521 };
522
523 struct acpi_mcfg_entry {
524         physaddr_t addr;
525         uint16_t segment;
526         uint8_t start_bus;
527         uint8_t end_bus;
528 };
529
530 struct acpi_mcfg_data {
531         size_t nr_entries;
532         struct acpi_mcfg_entry entries[];
533 };
534
535 int acpiinit(void);
536 struct Atable *mkatable(struct Atable *parent,
537                         int type, char *name, uint8_t *raw,
538                         size_t rawsize, size_t addsize);
539 struct Atable *finatable(struct Atable *t, struct slice *slice);
540 struct Atable *finatable_nochildren(struct Atable *t);
541
542 int get_early_num_cores(void);
543 physaddr_t acpi_pci_get_mmio_cfg_addr(int segment, int bus, int dev, int func);
544
545 extern struct Atable *apics;
546 extern struct Atable *dmar;
547 extern struct Atable *srat;