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