acpi.h 13 KB

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