|
|
1.1 root 1: // Support for generating ACPI tables (on emulators)
2: //
1.1.1.5 root 3: // Copyright (C) 2008-2010 Kevin O'Connor <[email protected]>
1.1 root 4: // Copyright (C) 2006 Fabrice Bellard
5: //
6: // This file may be distributed under the terms of the GNU LGPLv3 license.
7:
8: #include "acpi.h" // struct rsdp_descriptor
9: #include "util.h" // memcpy
1.1.1.7 root 10: #include "pci.h" // pci_find_init_device
1.1 root 11: #include "biosvar.h" // GET_EBDA
12: #include "pci_ids.h" // PCI_VENDOR_ID_INTEL
13: #include "pci_regs.h" // PCI_INTERRUPT_LINE
14: #include "paravirt.h"
15:
16: /****************************************************/
17: /* ACPI tables init */
18:
19: /* Table structure from Linux kernel (the ACPI tables are under the
20: BSD license) */
21:
22: struct acpi_table_header /* ACPI common table header */
23: {
24: ACPI_TABLE_HEADER_DEF
25: } PACKED;
26:
27: /*
28: * ACPI 1.0 Root System Description Table (RSDT)
29: */
30: #define RSDT_SIGNATURE 0x54445352 // RSDT
31: struct rsdt_descriptor_rev1
32: {
33: ACPI_TABLE_HEADER_DEF /* ACPI common table header */
34: u32 table_offset_entry[0]; /* Array of pointers to other */
35: /* ACPI tables */
36: } PACKED;
37:
38: /*
39: * ACPI 1.0 Firmware ACPI Control Structure (FACS)
40: */
41: #define FACS_SIGNATURE 0x53434146 // FACS
42: struct facs_descriptor_rev1
43: {
44: u32 signature; /* ACPI Signature */
45: u32 length; /* Length of structure, in bytes */
46: u32 hardware_signature; /* Hardware configuration signature */
47: u32 firmware_waking_vector; /* ACPI OS waking vector */
48: u32 global_lock; /* Global Lock */
49: u32 S4bios_f : 1; /* Indicates if S4BIOS support is present */
50: u32 reserved1 : 31; /* Must be 0 */
51: u8 resverved3 [40]; /* Reserved - must be zero */
52: } PACKED;
53:
54:
55: /*
1.1.1.8 ! root 56: * Differentiated System Description Table (DSDT)
! 57: */
! 58: #define DSDT_SIGNATURE 0x54445344 // DSDT
! 59:
! 60: /*
1.1 root 61: * MADT values and structures
62: */
63:
64: /* Values for MADT PCATCompat */
65:
66: #define DUAL_PIC 0
67: #define MULTIPLE_APIC 1
68:
69:
70: /* Master MADT */
71:
72: #define APIC_SIGNATURE 0x43495041 // APIC
73: struct multiple_apic_table
74: {
75: ACPI_TABLE_HEADER_DEF /* ACPI common table header */
76: u32 local_apic_address; /* Physical address of local APIC */
77: #if 0
78: u32 PCATcompat : 1; /* A one indicates system also has dual 8259s */
79: u32 reserved1 : 31;
80: #else
81: u32 flags;
82: #endif
83: } PACKED;
84:
85:
86: /* Values for Type in APIC sub-headers */
87:
88: #define APIC_PROCESSOR 0
89: #define APIC_IO 1
90: #define APIC_XRUPT_OVERRIDE 2
91: #define APIC_NMI 3
92: #define APIC_LOCAL_NMI 4
93: #define APIC_ADDRESS_OVERRIDE 5
94: #define APIC_IO_SAPIC 6
95: #define APIC_LOCAL_SAPIC 7
96: #define APIC_XRUPT_SOURCE 8
97: #define APIC_RESERVED 9 /* 9 and greater are reserved */
98:
99: /*
100: * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
101: */
102: #define ACPI_SUB_HEADER_DEF /* Common ACPI sub-structure header */\
103: u8 type; \
104: u8 length;
105:
106: /* Sub-structures for MADT */
107:
108: struct madt_processor_apic
109: {
110: ACPI_SUB_HEADER_DEF
111: u8 processor_id; /* ACPI processor id */
112: u8 local_apic_id; /* Processor's local APIC id */
113: #if 0
114: u32 processor_enabled: 1; /* Processor is usable if set */
115: u32 reserved2 : 31; /* Reserved, must be zero */
116: #else
117: u32 flags;
118: #endif
119: } PACKED;
120:
121: struct madt_io_apic
122: {
123: ACPI_SUB_HEADER_DEF
124: u8 io_apic_id; /* I/O APIC ID */
125: u8 reserved; /* Reserved - must be zero */
126: u32 address; /* APIC physical address */
127: u32 interrupt; /* Global system interrupt where INTI
128: * lines start */
129: } PACKED;
130:
131: /* IRQs 5,9,10,11 */
132: #define PCI_ISA_IRQ_MASK 0x0e20
133:
134: struct madt_intsrcovr {
135: ACPI_SUB_HEADER_DEF
136: u8 bus;
137: u8 source;
138: u32 gsi;
139: u16 flags;
140: } PACKED;
141:
1.1.1.8 ! root 142: struct madt_local_nmi {
! 143: ACPI_SUB_HEADER_DEF
! 144: u8 processor_id; /* ACPI processor id */
! 145: u16 flags; /* MPS INTI flags */
! 146: u8 lint; /* Local APIC LINT# */
! 147: } PACKED;
! 148:
! 149:
1.1 root 150: /*
151: * ACPI 2.0 Generic Address Space definition.
152: */
153: struct acpi_20_generic_address {
154: u8 address_space_id;
155: u8 register_bit_width;
156: u8 register_bit_offset;
157: u8 reserved;
158: u64 address;
159: } PACKED;
160:
161: /*
162: * HPET Description Table
163: */
164: struct acpi_20_hpet {
165: ACPI_TABLE_HEADER_DEF /* ACPI common table header */
166: u32 timer_block_id;
167: struct acpi_20_generic_address addr;
168: u8 hpet_number;
169: u16 min_tick;
170: u8 page_protect;
171: } PACKED;
1.1.1.8 ! root 172:
! 173: #define HPET_ID 0x000
! 174: #define HPET_PERIOD 0x004
1.1 root 175:
176: /*
177: * SRAT (NUMA topology description) table
178: */
179:
180: #define SRAT_PROCESSOR 0
181: #define SRAT_MEMORY 1
182:
183: struct system_resource_affinity_table
184: {
185: ACPI_TABLE_HEADER_DEF
186: u32 reserved1;
187: u32 reserved2[2];
188: } PACKED;
189:
190: struct srat_processor_affinity
191: {
192: ACPI_SUB_HEADER_DEF
193: u8 proximity_lo;
194: u8 local_apic_id;
195: u32 flags;
196: u8 local_sapic_eid;
197: u8 proximity_hi[3];
198: u32 reserved;
199: } PACKED;
200:
201: struct srat_memory_affinity
202: {
203: ACPI_SUB_HEADER_DEF
204: u8 proximity[4];
205: u16 reserved1;
206: u32 base_addr_low,base_addr_high;
207: u32 length_low,length_high;
208: u32 reserved2;
209: u32 flags;
210: u32 reserved3[2];
211: } PACKED;
212:
213: #include "acpi-dsdt.hex"
214:
215: static void
216: build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
217: {
218: h->signature = sig;
219: h->length = cpu_to_le32(len);
220: h->revision = rev;
221: memcpy(h->oem_id, CONFIG_APPNAME6, 6);
222: memcpy(h->oem_table_id, CONFIG_APPNAME4, 4);
223: memcpy(h->oem_table_id + 4, (void*)&sig, 4);
224: h->oem_revision = cpu_to_le32(1);
1.1.1.8 ! root 225: memcpy(h->asl_compiler_id, CONFIG_APPNAME4, 4);
1.1 root 226: h->asl_compiler_revision = cpu_to_le32(1);
227: h->checksum -= checksum(h, len);
228: }
229:
1.1.1.7 root 230: #define PIIX4_ACPI_ENABLE 0xf1
231: #define PIIX4_ACPI_DISABLE 0xf0
232: #define PIIX4_GPE0_BLK 0xafe0
233: #define PIIX4_GPE0_BLK_LEN 4
234:
235: static void piix4_fadt_init(struct pci_device *pci, void *arg)
236: {
237: struct fadt_descriptor_rev1 *fadt = arg;
238: fadt->acpi_enable = PIIX4_ACPI_ENABLE;
239: fadt->acpi_disable = PIIX4_ACPI_DISABLE;
240: fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK);
241: fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN;
242: }
243:
1.1.1.5 root 244: static const struct pci_device_id fadt_init_tbl[] = {
245: /* PIIX4 Power Management device (for ACPI) */
246: PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
247: piix4_fadt_init),
248:
249: PCI_DEVICE_END
250: };
251:
1.1.1.8 ! root 252: static void fill_dsdt(struct fadt_descriptor_rev1 *fadt, void *dsdt)
! 253: {
! 254: if (fadt->dsdt) {
! 255: free((void *)le32_to_cpu(fadt->dsdt));
! 256: }
! 257: fadt->dsdt = cpu_to_le32((u32)dsdt);
! 258: fadt->checksum -= checksum(fadt, sizeof(*fadt));
! 259: dprintf(1, "ACPI DSDT=%p\n", dsdt);
! 260: }
! 261:
1.1.1.7 root 262: static void *
263: build_fadt(struct pci_device *pci)
1.1 root 264: {
265: struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
266: struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
267:
1.1.1.8 ! root 268: if (!fadt || !facs) {
1.1.1.4 root 269: warn_noalloc();
1.1 root 270: return NULL;
271: }
272:
273: /* FACS */
274: memset(facs, 0, sizeof(*facs));
275: facs->signature = FACS_SIGNATURE;
276: facs->length = cpu_to_le32(sizeof(*facs));
277:
278: /* FADT */
279: memset(fadt, 0, sizeof(*fadt));
280: fadt->firmware_ctrl = cpu_to_le32((u32)facs);
1.1.1.8 ! root 281: fadt->dsdt = 0; /* dsdt will be filled later in acpi_bios_init()
! 282: by fill_dsdt() */
1.1 root 283: fadt->model = 1;
284: fadt->reserved1 = 0;
1.1.1.7 root 285: int pm_sci_int = pci_config_readb(pci->bdf, PCI_INTERRUPT_LINE);
1.1 root 286: fadt->sci_int = cpu_to_le16(pm_sci_int);
287: fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
288: fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
289: fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
290: fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
291: fadt->pm1_evt_len = 4;
292: fadt->pm1_cnt_len = 2;
293: fadt->pm_tmr_len = 4;
294: fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
295: fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
1.1.1.7 root 296: pci_init_device(fadt_init_tbl, pci, fadt);
1.1.1.8 ! root 297: /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 */
! 298: fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7));
1.1 root 299:
300: build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1);
301:
302: return fadt;
303: }
304:
305: static void*
306: build_madt(void)
307: {
308: int madt_size = (sizeof(struct multiple_apic_table)
309: + sizeof(struct madt_processor_apic) * MaxCountCPUs
310: + sizeof(struct madt_io_apic)
1.1.1.8 ! root 311: + sizeof(struct madt_intsrcovr) * 16
! 312: + sizeof(struct madt_local_nmi));
! 313:
1.1 root 314: struct multiple_apic_table *madt = malloc_high(madt_size);
315: if (!madt) {
1.1.1.4 root 316: warn_noalloc();
1.1 root 317: return NULL;
318: }
319: memset(madt, 0, madt_size);
320: madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
321: madt->flags = cpu_to_le32(1);
322: struct madt_processor_apic *apic = (void*)&madt[1];
323: int i;
324: for (i=0; i<MaxCountCPUs; i++) {
325: apic->type = APIC_PROCESSOR;
326: apic->length = sizeof(*apic);
327: apic->processor_id = i;
328: apic->local_apic_id = i;
329: if (i < CountCPUs)
330: apic->flags = cpu_to_le32(1);
331: else
332: apic->flags = cpu_to_le32(0);
333: apic++;
334: }
335: struct madt_io_apic *io_apic = (void*)apic;
336: io_apic->type = APIC_IO;
337: io_apic->length = sizeof(*io_apic);
338: io_apic->io_apic_id = CountCPUs;
339: io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
340: io_apic->interrupt = cpu_to_le32(0);
341:
342: struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1];
343: if (qemu_cfg_irq0_override()) {
344: memset(intsrcovr, 0, sizeof(*intsrcovr));
345: intsrcovr->type = APIC_XRUPT_OVERRIDE;
346: intsrcovr->length = sizeof(*intsrcovr);
347: intsrcovr->source = 0;
348: intsrcovr->gsi = 2;
349: intsrcovr->flags = 0; /* conforms to bus specifications */
350: intsrcovr++;
351: }
352: for (i = 1; i < 16; i++) {
353: if (!(PCI_ISA_IRQ_MASK & (1 << i)))
354: /* No need for a INT source override structure. */
355: continue;
356: memset(intsrcovr, 0, sizeof(*intsrcovr));
357: intsrcovr->type = APIC_XRUPT_OVERRIDE;
358: intsrcovr->length = sizeof(*intsrcovr);
359: intsrcovr->source = i;
360: intsrcovr->gsi = i;
361: intsrcovr->flags = 0xd; /* active high, level triggered */
362: intsrcovr++;
363: }
364:
1.1.1.8 ! root 365: struct madt_local_nmi *local_nmi = (void*)intsrcovr;
! 366: local_nmi->type = APIC_LOCAL_NMI;
! 367: local_nmi->length = sizeof(*local_nmi);
! 368: local_nmi->processor_id = 0xff; /* all processors */
! 369: local_nmi->flags = 0;
! 370: local_nmi->lint = 1; /* LINT1 */
! 371: local_nmi++;
! 372:
! 373: build_header((void*)madt, APIC_SIGNATURE, (void*)local_nmi - (void*)madt, 1);
1.1 root 374: return madt;
375: }
376:
1.1.1.5 root 377: // Encode a hex value
378: static inline char getHex(u32 val) {
379: val &= 0x0f;
380: return (val <= 9) ? ('0' + val) : ('A' + val - 10);
381: }
382:
383: // Encode a length in an SSDT.
384: static u8 *
385: encodeLen(u8 *ssdt_ptr, int length, int bytes)
386: {
387: switch (bytes) {
388: default:
389: case 4: ssdt_ptr[3] = ((length >> 20) & 0xff);
390: case 3: ssdt_ptr[2] = ((length >> 12) & 0xff);
391: case 2: ssdt_ptr[1] = ((length >> 4) & 0xff);
392: ssdt_ptr[0] = (((bytes-1) & 0x3) << 6) | (length & 0x0f);
393: break;
394: case 1: ssdt_ptr[0] = length & 0x3f;
395: }
396: return ssdt_ptr + bytes;
397: }
398:
1.1.1.8 ! root 399: #include "ssdt-proc.hex"
! 400:
! 401: /* 0x5B 0x83 ProcessorOp PkgLength NameString ProcID */
! 402: #define SD_OFFSET_CPUHEX (*ssdt_proc_name - *ssdt_proc_start + 2)
! 403: #define SD_OFFSET_CPUID1 (*ssdt_proc_name - *ssdt_proc_start + 4)
! 404: #define SD_OFFSET_CPUID2 (*ssdt_proc_id - *ssdt_proc_start)
! 405: #define SD_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
! 406: #define SD_PROC (ssdp_proc_aml + *ssdt_proc_start)
1.1.1.5 root 407:
1.1 root 408: #define SSDT_SIGNATURE 0x54445353 // SSDT
1.1.1.8 ! root 409:
1.1 root 410: static void*
411: build_ssdt(void)
412: {
413: int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs;
1.1.1.5 root 414: // length = ScopeOp + procs + NTYF method + CPON package
415: int length = ((1+3+4)
1.1.1.8 ! root 416: + (acpi_cpus * SD_SIZEOF)
1.1.1.5 root 417: + (1+2+5+(12*acpi_cpus))
418: + (6+2+1+(1*acpi_cpus)));
419: u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length);
1.1 root 420: if (! ssdt) {
1.1.1.4 root 421: warn_noalloc();
1.1 root 422: return NULL;
423: }
1.1.1.5 root 424: u8 *ssdt_ptr = ssdt + sizeof(struct acpi_table_header);
1.1 root 425:
1.1.1.5 root 426: // build Scope(_SB_) header
1.1 root 427: *(ssdt_ptr++) = 0x10; // ScopeOp
1.1.1.5 root 428: ssdt_ptr = encodeLen(ssdt_ptr, length-1, 3);
429: *(ssdt_ptr++) = '_';
430: *(ssdt_ptr++) = 'S';
431: *(ssdt_ptr++) = 'B';
1.1 root 432: *(ssdt_ptr++) = '_';
433:
1.1.1.5 root 434: // build Processor object for each processor
1.1 root 435: int i;
436: for (i=0; i<acpi_cpus; i++) {
1.1.1.8 ! root 437: memcpy(ssdt_ptr, SD_PROC, SD_SIZEOF);
1.1.1.5 root 438: ssdt_ptr[SD_OFFSET_CPUHEX] = getHex(i >> 4);
439: ssdt_ptr[SD_OFFSET_CPUHEX+1] = getHex(i);
440: ssdt_ptr[SD_OFFSET_CPUID1] = i;
441: ssdt_ptr[SD_OFFSET_CPUID2] = i;
1.1.1.8 ! root 442: ssdt_ptr += SD_SIZEOF;
1.1.1.5 root 443: }
444:
445: // build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}"
446: *(ssdt_ptr++) = 0x14; // MethodOp
447: ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*acpi_cpus), 2);
448: *(ssdt_ptr++) = 'N';
449: *(ssdt_ptr++) = 'T';
450: *(ssdt_ptr++) = 'F';
451: *(ssdt_ptr++) = 'Y';
452: *(ssdt_ptr++) = 0x02;
453: for (i=0; i<acpi_cpus; i++) {
454: *(ssdt_ptr++) = 0xA0; // IfOp
455: ssdt_ptr = encodeLen(ssdt_ptr, 11, 1);
456: *(ssdt_ptr++) = 0x93; // LEqualOp
457: *(ssdt_ptr++) = 0x68; // Arg0Op
458: *(ssdt_ptr++) = 0x0A; // BytePrefix
1.1 root 459: *(ssdt_ptr++) = i;
1.1.1.5 root 460: *(ssdt_ptr++) = 0x86; // NotifyOp
461: *(ssdt_ptr++) = 'C';
462: *(ssdt_ptr++) = 'P';
463: *(ssdt_ptr++) = getHex(i >> 4);
464: *(ssdt_ptr++) = getHex(i);
465: *(ssdt_ptr++) = 0x69; // Arg1Op
1.1 root 466: }
467:
1.1.1.5 root 468: // build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
469: *(ssdt_ptr++) = 0x08; // NameOp
470: *(ssdt_ptr++) = 'C';
471: *(ssdt_ptr++) = 'P';
472: *(ssdt_ptr++) = 'O';
473: *(ssdt_ptr++) = 'N';
474: *(ssdt_ptr++) = 0x12; // PackageOp
475: ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2);
476: *(ssdt_ptr++) = acpi_cpus;
477: for (i=0; i<acpi_cpus; i++)
478: *(ssdt_ptr++) = (i < CountCPUs) ? 0x01 : 0x00;
479:
1.1 root 480: build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
481:
1.1.1.5 root 482: //hexdump(ssdt, ssdt_ptr - ssdt);
483:
1.1 root 484: return ssdt;
485: }
486:
1.1.1.8 ! root 487: #include "ssdt-pcihp.hex"
! 488:
! 489: #define PCI_RMV_BASE 0xae0c
! 490:
! 491: extern void link_time_assertion(void);
! 492:
! 493: static void* build_pcihp(void)
! 494: {
! 495: u32 rmvc_pcrm;
! 496: int i;
! 497:
! 498: u8 *ssdt = malloc_high(sizeof ssdp_pcihp_aml);
! 499: if (!ssdt) {
! 500: warn_noalloc();
! 501: return NULL;
! 502: }
! 503: memcpy(ssdt, ssdp_pcihp_aml, sizeof ssdp_pcihp_aml);
! 504:
! 505: /* Runtime patching of EJ0: to disable hotplug for a slot,
! 506: * replace the method name: _EJ0 by EJ0_. */
! 507: if (ARRAY_SIZE(aml_ej0_name) != ARRAY_SIZE(aml_adr_dword)) {
! 508: link_time_assertion();
! 509: }
! 510:
! 511: rmvc_pcrm = inl(PCI_RMV_BASE);
! 512: for (i = 0; i < ARRAY_SIZE(aml_ej0_name); ++i) {
! 513: /* Slot is in byte 2 in _ADR */
! 514: u8 slot = ssdp_pcihp_aml[aml_adr_dword[i] + 2] & 0x1F;
! 515: /* Sanity check */
! 516: if (memcmp(ssdp_pcihp_aml + aml_ej0_name[i], "_EJ0", 4)) {
! 517: warn_internalerror();
! 518: free(ssdt);
! 519: return NULL;
! 520: }
! 521: if (!(rmvc_pcrm & (0x1 << slot))) {
! 522: memcpy(ssdt + aml_ej0_name[i], "EJ0_", 4);
! 523: }
! 524: }
! 525:
! 526: return ssdt;
! 527: }
! 528:
! 529: #define HPET_SIGNATURE 0x54455048 // HPET
1.1 root 530: static void*
531: build_hpet(void)
532: {
1.1.1.8 ! root 533: struct acpi_20_hpet *hpet;
! 534: const void *hpet_base = (void *)BUILD_HPET_ADDRESS;
! 535: u32 hpet_vendor = readl(hpet_base + HPET_ID) >> 16;
! 536: u32 hpet_period = readl(hpet_base + HPET_PERIOD);
! 537:
! 538: if (hpet_vendor == 0 || hpet_vendor == 0xffff ||
! 539: hpet_period == 0 || hpet_period > 100000000)
! 540: return NULL;
! 541:
! 542: hpet = malloc_high(sizeof(*hpet));
1.1 root 543: if (!hpet) {
1.1.1.4 root 544: warn_noalloc();
1.1 root 545: return NULL;
546: }
547:
548: memset(hpet, 0, sizeof(*hpet));
549: /* Note timer_block_id value must be kept in sync with value advertised by
550: * emulated hpet
551: */
552: hpet->timer_block_id = cpu_to_le32(0x8086a201);
1.1.1.8 ! root 553: hpet->addr.address = cpu_to_le32(BUILD_HPET_ADDRESS);
1.1 root 554: build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1);
555:
556: return hpet;
557: }
558:
559: static void
560: acpi_build_srat_memory(struct srat_memory_affinity *numamem,
561: u64 base, u64 len, int node, int enabled)
562: {
563: numamem->type = SRAT_MEMORY;
564: numamem->length = sizeof(*numamem);
1.1.1.8 ! root 565: memset(numamem->proximity, 0 ,4);
1.1 root 566: numamem->proximity[0] = node;
567: numamem->flags = cpu_to_le32(!!enabled);
568: numamem->base_addr_low = base & 0xFFFFFFFF;
569: numamem->base_addr_high = base >> 32;
570: numamem->length_low = len & 0xFFFFFFFF;
571: numamem->length_high = len >> 32;
572: }
573:
1.1.1.8 ! root 574: #define SRAT_SIGNATURE 0x54415253 // SRAT
1.1 root 575: static void *
576: build_srat(void)
577: {
578: int nb_numa_nodes = qemu_cfg_get_numa_nodes();
579:
580: if (nb_numa_nodes == 0)
581: return NULL;
582:
583: u64 *numadata = malloc_tmphigh(sizeof(u64) * (MaxCountCPUs + nb_numa_nodes));
584: if (!numadata) {
1.1.1.4 root 585: warn_noalloc();
1.1 root 586: return NULL;
587: }
588:
589: qemu_cfg_get_numa_data(numadata, MaxCountCPUs + nb_numa_nodes);
590:
591: struct system_resource_affinity_table *srat;
592: int srat_size = sizeof(*srat) +
593: sizeof(struct srat_processor_affinity) * MaxCountCPUs +
594: sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
595:
596: srat = malloc_high(srat_size);
597: if (!srat) {
1.1.1.4 root 598: warn_noalloc();
599: free(numadata);
1.1 root 600: return NULL;
601: }
602:
603: memset(srat, 0, srat_size);
604: srat->reserved1=1;
605: struct srat_processor_affinity *core = (void*)(srat + 1);
606: int i;
607: u64 curnode;
608:
609: for (i = 0; i < MaxCountCPUs; ++i) {
610: core->type = SRAT_PROCESSOR;
611: core->length = sizeof(*core);
612: core->local_apic_id = i;
613: curnode = *numadata++;
614: core->proximity_lo = curnode;
615: memset(core->proximity_hi, 0, 3);
616: core->local_sapic_eid = 0;
617: if (i < CountCPUs)
618: core->flags = cpu_to_le32(1);
619: else
620: core->flags = 0;
621: core++;
622: }
623:
624:
625: /* the memory map is a bit tricky, it contains at least one hole
626: * from 640k-1M and possibly another one from 3.5G-4G.
627: */
628: struct srat_memory_affinity *numamem = (void*)core;
629: int slots = 0;
630: u64 mem_len, mem_base, next_base = 0;
631:
632: acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
633: next_base = 1024 * 1024;
634: numamem++;
635: slots++;
636: for (i = 1; i < nb_numa_nodes + 1; ++i) {
637: mem_base = next_base;
638: mem_len = *numadata++;
639: if (i == 1)
640: mem_len -= 1024 * 1024;
641: next_base = mem_base + mem_len;
642:
643: /* Cut out the PCI hole */
644: if (mem_base <= RamSize && next_base > RamSize) {
645: mem_len -= next_base - RamSize;
646: if (mem_len > 0) {
647: acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
648: numamem++;
649: slots++;
650: }
651: mem_base = 1ULL << 32;
652: mem_len = next_base - RamSize;
653: next_base += (1ULL << 32) - RamSize;
654: }
655: acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
656: numamem++;
657: slots++;
658: }
659: for (; slots < nb_numa_nodes + 2; slots++) {
660: acpi_build_srat_memory(numamem, 0, 0, 0, 0);
661: numamem++;
662: }
663:
664: build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1);
665:
1.1.1.4 root 666: free(numadata);
1.1 root 667: return srat;
668: }
669:
1.1.1.5 root 670: static const struct pci_device_id acpi_find_tbl[] = {
671: /* PIIX4 Power Management device. */
672: PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL),
673:
674: PCI_DEVICE_END,
675: };
676:
1.1 root 677: struct rsdp_descriptor *RsdpAddr;
678:
679: #define MAX_ACPI_TABLES 20
680: void
681: acpi_bios_init(void)
682: {
683: if (! CONFIG_ACPI)
684: return;
685:
686: dprintf(3, "init ACPI tables\n");
687:
688: // This code is hardcoded for PIIX4 Power Management device.
1.1.1.7 root 689: struct pci_device *pci = pci_find_init_device(acpi_find_tbl, NULL);
690: if (!pci)
1.1 root 691: // Device not found
692: return;
693:
1.1.1.8 ! root 694: // Build ACPI tables
1.1 root 695: u32 tables[MAX_ACPI_TABLES], tbl_idx = 0;
696:
697: #define ACPI_INIT_TABLE(X) \
698: do { \
699: tables[tbl_idx] = (u32)(X); \
700: if (tables[tbl_idx]) \
701: tbl_idx++; \
702: } while(0)
703:
1.1.1.8 ! root 704: struct fadt_descriptor_rev1 *fadt = build_fadt(pci);
! 705: ACPI_INIT_TABLE(fadt);
1.1 root 706: ACPI_INIT_TABLE(build_ssdt());
707: ACPI_INIT_TABLE(build_madt());
708: ACPI_INIT_TABLE(build_hpet());
709: ACPI_INIT_TABLE(build_srat());
1.1.1.8 ! root 710: ACPI_INIT_TABLE(build_pcihp());
1.1 root 711:
712: u16 i, external_tables = qemu_cfg_acpi_additional_tables();
713:
1.1.1.8 ! root 714: for (i = 0; i < external_tables; i++) {
1.1 root 715: u16 len = qemu_cfg_next_acpi_table_len();
716: void *addr = malloc_high(len);
717: if (!addr) {
1.1.1.4 root 718: warn_noalloc();
1.1 root 719: continue;
720: }
1.1.1.8 ! root 721: struct acpi_table_header *header =
! 722: qemu_cfg_next_acpi_table_load(addr, len);
! 723: if (header->signature == DSDT_SIGNATURE) {
! 724: if (fadt) {
! 725: fill_dsdt(fadt, addr);
! 726: }
! 727: } else {
! 728: ACPI_INIT_TABLE(header);
! 729: }
1.1 root 730: if (tbl_idx == MAX_ACPI_TABLES) {
1.1.1.4 root 731: warn_noalloc();
1.1 root 732: break;
733: }
734: }
1.1.1.8 ! root 735: if (fadt && !fadt->dsdt) {
! 736: /* default DSDT */
! 737: void *dsdt = malloc_high(sizeof(AmlCode));
! 738: if (!dsdt) {
! 739: warn_noalloc();
! 740: return;
! 741: }
! 742: memcpy(dsdt, AmlCode, sizeof(AmlCode));
! 743: fill_dsdt(fadt, dsdt);
! 744: }
1.1 root 745:
1.1.1.8 ! root 746: // Build final rsdt table
1.1 root 747: struct rsdt_descriptor_rev1 *rsdt;
748: size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx;
749: rsdt = malloc_high(rsdt_len);
750: if (!rsdt) {
1.1.1.4 root 751: warn_noalloc();
1.1 root 752: return;
753: }
754: memset(rsdt, 0, rsdt_len);
755: memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx);
756: build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
757:
758: // Build rsdp pointer table
1.1.1.8 ! root 759: struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
! 760: if (!rsdp) {
! 761: warn_noalloc();
! 762: return;
! 763: }
1.1 root 764: memset(rsdp, 0, sizeof(*rsdp));
765: rsdp->signature = RSDP_SIGNATURE;
766: memcpy(rsdp->oem_id, CONFIG_APPNAME6, 6);
767: rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt);
768: rsdp->checksum -= checksum(rsdp, 20);
769: RsdpAddr = rsdp;
770: dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt);
771: }
772:
773: u32
1.1.1.2 root 774: find_resume_vector(void)
1.1 root 775: {
776: dprintf(4, "rsdp=%p\n", RsdpAddr);
777: if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE)
778: return 0;
779: struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address;
780: dprintf(4, "rsdt=%p\n", rsdt);
781: if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
782: return 0;
783: void *end = (void*)rsdt + rsdt->length;
784: int i;
785: for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
786: struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i];
787: if (!fadt || fadt->signature != FACP_SIGNATURE)
788: continue;
789: dprintf(4, "fadt=%p\n", fadt);
790: struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
791: dprintf(4, "facs=%p\n", facs);
792: if (! facs || facs->signature != FACS_SIGNATURE)
793: return 0;
794: // Found it.
795: dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector);
796: return facs->firmware_waking_vector;
797: }
798: return 0;
799: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.