|
|
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: /*
56: * MADT values and structures
57: */
58:
59: /* Values for MADT PCATCompat */
60:
61: #define DUAL_PIC 0
62: #define MULTIPLE_APIC 1
63:
64:
65: /* Master MADT */
66:
67: #define APIC_SIGNATURE 0x43495041 // APIC
68: struct multiple_apic_table
69: {
70: ACPI_TABLE_HEADER_DEF /* ACPI common table header */
71: u32 local_apic_address; /* Physical address of local APIC */
72: #if 0
73: u32 PCATcompat : 1; /* A one indicates system also has dual 8259s */
74: u32 reserved1 : 31;
75: #else
76: u32 flags;
77: #endif
78: } PACKED;
79:
80:
81: /* Values for Type in APIC sub-headers */
82:
83: #define APIC_PROCESSOR 0
84: #define APIC_IO 1
85: #define APIC_XRUPT_OVERRIDE 2
86: #define APIC_NMI 3
87: #define APIC_LOCAL_NMI 4
88: #define APIC_ADDRESS_OVERRIDE 5
89: #define APIC_IO_SAPIC 6
90: #define APIC_LOCAL_SAPIC 7
91: #define APIC_XRUPT_SOURCE 8
92: #define APIC_RESERVED 9 /* 9 and greater are reserved */
93:
94: /*
95: * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
96: */
97: #define ACPI_SUB_HEADER_DEF /* Common ACPI sub-structure header */\
98: u8 type; \
99: u8 length;
100:
101: /* Sub-structures for MADT */
102:
103: struct madt_processor_apic
104: {
105: ACPI_SUB_HEADER_DEF
106: u8 processor_id; /* ACPI processor id */
107: u8 local_apic_id; /* Processor's local APIC id */
108: #if 0
109: u32 processor_enabled: 1; /* Processor is usable if set */
110: u32 reserved2 : 31; /* Reserved, must be zero */
111: #else
112: u32 flags;
113: #endif
114: } PACKED;
115:
116: struct madt_io_apic
117: {
118: ACPI_SUB_HEADER_DEF
119: u8 io_apic_id; /* I/O APIC ID */
120: u8 reserved; /* Reserved - must be zero */
121: u32 address; /* APIC physical address */
122: u32 interrupt; /* Global system interrupt where INTI
123: * lines start */
124: } PACKED;
125:
126: /* IRQs 5,9,10,11 */
127: #define PCI_ISA_IRQ_MASK 0x0e20
128:
129: struct madt_intsrcovr {
130: ACPI_SUB_HEADER_DEF
131: u8 bus;
132: u8 source;
133: u32 gsi;
134: u16 flags;
135: } PACKED;
136:
137: /*
138: * ACPI 2.0 Generic Address Space definition.
139: */
140: struct acpi_20_generic_address {
141: u8 address_space_id;
142: u8 register_bit_width;
143: u8 register_bit_offset;
144: u8 reserved;
145: u64 address;
146: } PACKED;
147:
148: /*
149: * HPET Description Table
150: */
151: struct acpi_20_hpet {
152: ACPI_TABLE_HEADER_DEF /* ACPI common table header */
153: u32 timer_block_id;
154: struct acpi_20_generic_address addr;
155: u8 hpet_number;
156: u16 min_tick;
157: u8 page_protect;
158: } PACKED;
159: #define ACPI_HPET_ADDRESS 0xFED00000UL
160:
161: /*
162: * SRAT (NUMA topology description) table
163: */
164:
165: #define SRAT_PROCESSOR 0
166: #define SRAT_MEMORY 1
167:
168: struct system_resource_affinity_table
169: {
170: ACPI_TABLE_HEADER_DEF
171: u32 reserved1;
172: u32 reserved2[2];
173: } PACKED;
174:
175: struct srat_processor_affinity
176: {
177: ACPI_SUB_HEADER_DEF
178: u8 proximity_lo;
179: u8 local_apic_id;
180: u32 flags;
181: u8 local_sapic_eid;
182: u8 proximity_hi[3];
183: u32 reserved;
184: } PACKED;
185:
186: struct srat_memory_affinity
187: {
188: ACPI_SUB_HEADER_DEF
189: u8 proximity[4];
190: u16 reserved1;
191: u32 base_addr_low,base_addr_high;
192: u32 length_low,length_high;
193: u32 reserved2;
194: u32 flags;
195: u32 reserved3[2];
196: } PACKED;
197:
198: #include "acpi-dsdt.hex"
199:
200: static void
201: build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
202: {
203: h->signature = sig;
204: h->length = cpu_to_le32(len);
205: h->revision = rev;
206: memcpy(h->oem_id, CONFIG_APPNAME6, 6);
207: memcpy(h->oem_table_id, CONFIG_APPNAME4, 4);
208: memcpy(h->asl_compiler_id, CONFIG_APPNAME4, 4);
209: memcpy(h->oem_table_id + 4, (void*)&sig, 4);
210: h->oem_revision = cpu_to_le32(1);
211: h->asl_compiler_revision = cpu_to_le32(1);
212: h->checksum -= checksum(h, len);
213: }
214:
1.1.1.7 ! root 215: #define PIIX4_ACPI_ENABLE 0xf1
! 216: #define PIIX4_ACPI_DISABLE 0xf0
! 217: #define PIIX4_GPE0_BLK 0xafe0
! 218: #define PIIX4_GPE0_BLK_LEN 4
! 219:
! 220: static void piix4_fadt_init(struct pci_device *pci, void *arg)
! 221: {
! 222: struct fadt_descriptor_rev1 *fadt = arg;
! 223: fadt->acpi_enable = PIIX4_ACPI_ENABLE;
! 224: fadt->acpi_disable = PIIX4_ACPI_DISABLE;
! 225: fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK);
! 226: fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN;
! 227: }
! 228:
1.1.1.5 root 229: static const struct pci_device_id fadt_init_tbl[] = {
230: /* PIIX4 Power Management device (for ACPI) */
231: PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
232: piix4_fadt_init),
233:
234: PCI_DEVICE_END
235: };
236:
1.1.1.7 ! root 237: static void *
! 238: build_fadt(struct pci_device *pci)
1.1 root 239: {
240: struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
241: struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
242: void *dsdt = malloc_high(sizeof(AmlCode));
243:
244: if (!fadt || !facs || !dsdt) {
1.1.1.4 root 245: warn_noalloc();
1.1 root 246: return NULL;
247: }
248:
249: /* FACS */
250: memset(facs, 0, sizeof(*facs));
251: facs->signature = FACS_SIGNATURE;
252: facs->length = cpu_to_le32(sizeof(*facs));
253:
254: /* DSDT */
255: memcpy(dsdt, AmlCode, sizeof(AmlCode));
256:
257: /* FADT */
258: memset(fadt, 0, sizeof(*fadt));
259: fadt->firmware_ctrl = cpu_to_le32((u32)facs);
260: fadt->dsdt = cpu_to_le32((u32)dsdt);
261: fadt->model = 1;
262: fadt->reserved1 = 0;
1.1.1.7 ! root 263: int pm_sci_int = pci_config_readb(pci->bdf, PCI_INTERRUPT_LINE);
1.1 root 264: fadt->sci_int = cpu_to_le16(pm_sci_int);
265: fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
266: fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
267: fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
268: fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
269: fadt->pm1_evt_len = 4;
270: fadt->pm1_cnt_len = 2;
271: fadt->pm_tmr_len = 4;
272: fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
273: fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
1.1.1.7 ! root 274: pci_init_device(fadt_init_tbl, pci, fadt);
1.1.1.6 root 275: /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC + RTC_S4 */
276: fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6) | (1 << 7));
1.1 root 277:
278: build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1);
279:
280: return fadt;
281: }
282:
283: static void*
284: build_madt(void)
285: {
286: int madt_size = (sizeof(struct multiple_apic_table)
287: + sizeof(struct madt_processor_apic) * MaxCountCPUs
288: + sizeof(struct madt_io_apic)
289: + sizeof(struct madt_intsrcovr) * 16);
290: struct multiple_apic_table *madt = malloc_high(madt_size);
291: if (!madt) {
1.1.1.4 root 292: warn_noalloc();
1.1 root 293: return NULL;
294: }
295: memset(madt, 0, madt_size);
296: madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
297: madt->flags = cpu_to_le32(1);
298: struct madt_processor_apic *apic = (void*)&madt[1];
299: int i;
300: for (i=0; i<MaxCountCPUs; i++) {
301: apic->type = APIC_PROCESSOR;
302: apic->length = sizeof(*apic);
303: apic->processor_id = i;
304: apic->local_apic_id = i;
305: if (i < CountCPUs)
306: apic->flags = cpu_to_le32(1);
307: else
308: apic->flags = cpu_to_le32(0);
309: apic++;
310: }
311: struct madt_io_apic *io_apic = (void*)apic;
312: io_apic->type = APIC_IO;
313: io_apic->length = sizeof(*io_apic);
314: io_apic->io_apic_id = CountCPUs;
315: io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
316: io_apic->interrupt = cpu_to_le32(0);
317:
318: struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1];
319: if (qemu_cfg_irq0_override()) {
320: memset(intsrcovr, 0, sizeof(*intsrcovr));
321: intsrcovr->type = APIC_XRUPT_OVERRIDE;
322: intsrcovr->length = sizeof(*intsrcovr);
323: intsrcovr->source = 0;
324: intsrcovr->gsi = 2;
325: intsrcovr->flags = 0; /* conforms to bus specifications */
326: intsrcovr++;
327: }
328: for (i = 1; i < 16; i++) {
329: if (!(PCI_ISA_IRQ_MASK & (1 << i)))
330: /* No need for a INT source override structure. */
331: continue;
332: memset(intsrcovr, 0, sizeof(*intsrcovr));
333: intsrcovr->type = APIC_XRUPT_OVERRIDE;
334: intsrcovr->length = sizeof(*intsrcovr);
335: intsrcovr->source = i;
336: intsrcovr->gsi = i;
337: intsrcovr->flags = 0xd; /* active high, level triggered */
338: intsrcovr++;
339: }
340:
341: build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt, 1);
342: return madt;
343: }
344:
1.1.1.5 root 345: // Encode a hex value
346: static inline char getHex(u32 val) {
347: val &= 0x0f;
348: return (val <= 9) ? ('0' + val) : ('A' + val - 10);
349: }
350:
351: // Encode a length in an SSDT.
352: static u8 *
353: encodeLen(u8 *ssdt_ptr, int length, int bytes)
354: {
355: switch (bytes) {
356: default:
357: case 4: ssdt_ptr[3] = ((length >> 20) & 0xff);
358: case 3: ssdt_ptr[2] = ((length >> 12) & 0xff);
359: case 2: ssdt_ptr[1] = ((length >> 4) & 0xff);
360: ssdt_ptr[0] = (((bytes-1) & 0x3) << 6) | (length & 0x0f);
361: break;
362: case 1: ssdt_ptr[0] = length & 0x3f;
363: }
364: return ssdt_ptr + bytes;
365: }
366:
367: // AML Processor() object. See src/ssdt-proc.dsl for info.
368: static unsigned char ssdt_proc[] = {
369: 0x5b,0x83,0x42,0x05,0x43,0x50,0x41,0x41,
370: 0xaa,0x10,0xb0,0x00,0x00,0x06,0x08,0x49,
371: 0x44,0x5f,0x5f,0x0a,0xaa,0x08,0x5f,0x48,
372: 0x49,0x44,0x0d,0x41,0x43,0x50,0x49,0x30,
373: 0x30,0x30,0x37,0x00,0x14,0x0f,0x5f,0x4d,
374: 0x41,0x54,0x00,0xa4,0x43,0x50,0x4d,0x41,
375: 0x49,0x44,0x5f,0x5f,0x14,0x0f,0x5f,0x53,
376: 0x54,0x41,0x00,0xa4,0x43,0x50,0x53,0x54,
377: 0x49,0x44,0x5f,0x5f,0x14,0x0f,0x5f,0x45,
378: 0x4a,0x30,0x01,0x43,0x50,0x45,0x4a,0x49,
379: 0x44,0x5f,0x5f,0x68
380: };
381: #define SD_OFFSET_CPUHEX 6
382: #define SD_OFFSET_CPUID1 8
383: #define SD_OFFSET_CPUID2 20
384:
1.1 root 385: #define SSDT_SIGNATURE 0x54445353 // SSDT
386: static void*
387: build_ssdt(void)
388: {
389: int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs;
1.1.1.5 root 390: // length = ScopeOp + procs + NTYF method + CPON package
391: int length = ((1+3+4)
392: + (acpi_cpus * sizeof(ssdt_proc))
393: + (1+2+5+(12*acpi_cpus))
394: + (6+2+1+(1*acpi_cpus)));
395: u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length);
1.1 root 396: if (! ssdt) {
1.1.1.4 root 397: warn_noalloc();
1.1 root 398: return NULL;
399: }
1.1.1.5 root 400: u8 *ssdt_ptr = ssdt + sizeof(struct acpi_table_header);
1.1 root 401:
1.1.1.5 root 402: // build Scope(_SB_) header
1.1 root 403: *(ssdt_ptr++) = 0x10; // ScopeOp
1.1.1.5 root 404: ssdt_ptr = encodeLen(ssdt_ptr, length-1, 3);
405: *(ssdt_ptr++) = '_';
406: *(ssdt_ptr++) = 'S';
407: *(ssdt_ptr++) = 'B';
1.1 root 408: *(ssdt_ptr++) = '_';
409:
1.1.1.5 root 410: // build Processor object for each processor
1.1 root 411: int i;
412: for (i=0; i<acpi_cpus; i++) {
1.1.1.5 root 413: memcpy(ssdt_ptr, ssdt_proc, sizeof(ssdt_proc));
414: ssdt_ptr[SD_OFFSET_CPUHEX] = getHex(i >> 4);
415: ssdt_ptr[SD_OFFSET_CPUHEX+1] = getHex(i);
416: ssdt_ptr[SD_OFFSET_CPUID1] = i;
417: ssdt_ptr[SD_OFFSET_CPUID2] = i;
418: ssdt_ptr += sizeof(ssdt_proc);
419: }
420:
421: // build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}"
422: *(ssdt_ptr++) = 0x14; // MethodOp
423: ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*acpi_cpus), 2);
424: *(ssdt_ptr++) = 'N';
425: *(ssdt_ptr++) = 'T';
426: *(ssdt_ptr++) = 'F';
427: *(ssdt_ptr++) = 'Y';
428: *(ssdt_ptr++) = 0x02;
429: for (i=0; i<acpi_cpus; i++) {
430: *(ssdt_ptr++) = 0xA0; // IfOp
431: ssdt_ptr = encodeLen(ssdt_ptr, 11, 1);
432: *(ssdt_ptr++) = 0x93; // LEqualOp
433: *(ssdt_ptr++) = 0x68; // Arg0Op
434: *(ssdt_ptr++) = 0x0A; // BytePrefix
1.1 root 435: *(ssdt_ptr++) = i;
1.1.1.5 root 436: *(ssdt_ptr++) = 0x86; // NotifyOp
437: *(ssdt_ptr++) = 'C';
438: *(ssdt_ptr++) = 'P';
439: *(ssdt_ptr++) = getHex(i >> 4);
440: *(ssdt_ptr++) = getHex(i);
441: *(ssdt_ptr++) = 0x69; // Arg1Op
1.1 root 442: }
443:
1.1.1.5 root 444: // build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
445: *(ssdt_ptr++) = 0x08; // NameOp
446: *(ssdt_ptr++) = 'C';
447: *(ssdt_ptr++) = 'P';
448: *(ssdt_ptr++) = 'O';
449: *(ssdt_ptr++) = 'N';
450: *(ssdt_ptr++) = 0x12; // PackageOp
451: ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2);
452: *(ssdt_ptr++) = acpi_cpus;
453: for (i=0; i<acpi_cpus; i++)
454: *(ssdt_ptr++) = (i < CountCPUs) ? 0x01 : 0x00;
455:
1.1 root 456: build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
457:
1.1.1.5 root 458: //hexdump(ssdt, ssdt_ptr - ssdt);
459:
1.1 root 460: return ssdt;
461: }
462:
463: #define HPET_SIGNATURE 0x54455048 //HPET
464: static void*
465: build_hpet(void)
466: {
467: struct acpi_20_hpet *hpet = malloc_high(sizeof(*hpet));
468: if (!hpet) {
1.1.1.4 root 469: warn_noalloc();
1.1 root 470: return NULL;
471: }
472:
473: memset(hpet, 0, sizeof(*hpet));
474: /* Note timer_block_id value must be kept in sync with value advertised by
475: * emulated hpet
476: */
477: hpet->timer_block_id = cpu_to_le32(0x8086a201);
478: hpet->addr.address = cpu_to_le32(ACPI_HPET_ADDRESS);
479: build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1);
480:
481: return hpet;
482: }
483:
484: static void
485: acpi_build_srat_memory(struct srat_memory_affinity *numamem,
486: u64 base, u64 len, int node, int enabled)
487: {
488: numamem->type = SRAT_MEMORY;
489: numamem->length = sizeof(*numamem);
490: memset (numamem->proximity, 0 ,4);
491: numamem->proximity[0] = node;
492: numamem->flags = cpu_to_le32(!!enabled);
493: numamem->base_addr_low = base & 0xFFFFFFFF;
494: numamem->base_addr_high = base >> 32;
495: numamem->length_low = len & 0xFFFFFFFF;
496: numamem->length_high = len >> 32;
497: }
498:
499: #define SRAT_SIGNATURE 0x54415253 //HPET
500: static void *
501: build_srat(void)
502: {
503: int nb_numa_nodes = qemu_cfg_get_numa_nodes();
504:
505: if (nb_numa_nodes == 0)
506: return NULL;
507:
508: u64 *numadata = malloc_tmphigh(sizeof(u64) * (MaxCountCPUs + nb_numa_nodes));
509: if (!numadata) {
1.1.1.4 root 510: warn_noalloc();
1.1 root 511: return NULL;
512: }
513:
514: qemu_cfg_get_numa_data(numadata, MaxCountCPUs + nb_numa_nodes);
515:
516: struct system_resource_affinity_table *srat;
517: int srat_size = sizeof(*srat) +
518: sizeof(struct srat_processor_affinity) * MaxCountCPUs +
519: sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
520:
521: srat = malloc_high(srat_size);
522: if (!srat) {
1.1.1.4 root 523: warn_noalloc();
524: free(numadata);
1.1 root 525: return NULL;
526: }
527:
528: memset(srat, 0, srat_size);
529: srat->reserved1=1;
530: struct srat_processor_affinity *core = (void*)(srat + 1);
531: int i;
532: u64 curnode;
533:
534: for (i = 0; i < MaxCountCPUs; ++i) {
535: core->type = SRAT_PROCESSOR;
536: core->length = sizeof(*core);
537: core->local_apic_id = i;
538: curnode = *numadata++;
539: core->proximity_lo = curnode;
540: memset(core->proximity_hi, 0, 3);
541: core->local_sapic_eid = 0;
542: if (i < CountCPUs)
543: core->flags = cpu_to_le32(1);
544: else
545: core->flags = 0;
546: core++;
547: }
548:
549:
550: /* the memory map is a bit tricky, it contains at least one hole
551: * from 640k-1M and possibly another one from 3.5G-4G.
552: */
553: struct srat_memory_affinity *numamem = (void*)core;
554: int slots = 0;
555: u64 mem_len, mem_base, next_base = 0;
556:
557: acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
558: next_base = 1024 * 1024;
559: numamem++;
560: slots++;
561: for (i = 1; i < nb_numa_nodes + 1; ++i) {
562: mem_base = next_base;
563: mem_len = *numadata++;
564: if (i == 1)
565: mem_len -= 1024 * 1024;
566: next_base = mem_base + mem_len;
567:
568: /* Cut out the PCI hole */
569: if (mem_base <= RamSize && next_base > RamSize) {
570: mem_len -= next_base - RamSize;
571: if (mem_len > 0) {
572: acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
573: numamem++;
574: slots++;
575: }
576: mem_base = 1ULL << 32;
577: mem_len = next_base - RamSize;
578: next_base += (1ULL << 32) - RamSize;
579: }
580: acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
581: numamem++;
582: slots++;
583: }
584: for (; slots < nb_numa_nodes + 2; slots++) {
585: acpi_build_srat_memory(numamem, 0, 0, 0, 0);
586: numamem++;
587: }
588:
589: build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1);
590:
1.1.1.4 root 591: free(numadata);
1.1 root 592: return srat;
593: }
594:
1.1.1.5 root 595: static const struct pci_device_id acpi_find_tbl[] = {
596: /* PIIX4 Power Management device. */
597: PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL),
598:
599: PCI_DEVICE_END,
600: };
601:
1.1 root 602: struct rsdp_descriptor *RsdpAddr;
603:
604: #define MAX_ACPI_TABLES 20
605: void
606: acpi_bios_init(void)
607: {
608: if (! CONFIG_ACPI)
609: return;
610:
611: dprintf(3, "init ACPI tables\n");
612:
613: // This code is hardcoded for PIIX4 Power Management device.
1.1.1.7 ! root 614: struct pci_device *pci = pci_find_init_device(acpi_find_tbl, NULL);
! 615: if (!pci)
1.1 root 616: // Device not found
617: return;
618:
619: // Create initial rsdt table
620: struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
621: if (!rsdp) {
1.1.1.4 root 622: warn_noalloc();
1.1 root 623: return;
624: }
625:
626: u32 tables[MAX_ACPI_TABLES], tbl_idx = 0;
627:
628: #define ACPI_INIT_TABLE(X) \
629: do { \
630: tables[tbl_idx] = (u32)(X); \
631: if (tables[tbl_idx]) \
632: tbl_idx++; \
633: } while(0)
634:
635: // Add tables
1.1.1.7 ! root 636: ACPI_INIT_TABLE(build_fadt(pci));
1.1 root 637: ACPI_INIT_TABLE(build_ssdt());
638: ACPI_INIT_TABLE(build_madt());
639: ACPI_INIT_TABLE(build_hpet());
640: ACPI_INIT_TABLE(build_srat());
641:
642: u16 i, external_tables = qemu_cfg_acpi_additional_tables();
643:
644: for(i = 0; i < external_tables; i++) {
645: u16 len = qemu_cfg_next_acpi_table_len();
646: void *addr = malloc_high(len);
647: if (!addr) {
1.1.1.4 root 648: warn_noalloc();
1.1 root 649: continue;
650: }
651: ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len));
652: if (tbl_idx == MAX_ACPI_TABLES) {
1.1.1.4 root 653: warn_noalloc();
1.1 root 654: break;
655: }
656: }
657:
658: struct rsdt_descriptor_rev1 *rsdt;
659: size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx;
660: rsdt = malloc_high(rsdt_len);
661:
662: if (!rsdt) {
1.1.1.4 root 663: warn_noalloc();
1.1 root 664: return;
665: }
666: memset(rsdt, 0, rsdt_len);
667: memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx);
668:
669: build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
670:
671: // Build rsdp pointer table
672: memset(rsdp, 0, sizeof(*rsdp));
673: rsdp->signature = RSDP_SIGNATURE;
674: memcpy(rsdp->oem_id, CONFIG_APPNAME6, 6);
675: rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt);
676: rsdp->checksum -= checksum(rsdp, 20);
677: RsdpAddr = rsdp;
678: dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt);
679: }
680:
681: u32
1.1.1.2 root 682: find_resume_vector(void)
1.1 root 683: {
684: dprintf(4, "rsdp=%p\n", RsdpAddr);
685: if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE)
686: return 0;
687: struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address;
688: dprintf(4, "rsdt=%p\n", rsdt);
689: if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
690: return 0;
691: void *end = (void*)rsdt + rsdt->length;
692: int i;
693: for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
694: struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i];
695: if (!fadt || fadt->signature != FACP_SIGNATURE)
696: continue;
697: dprintf(4, "fadt=%p\n", fadt);
698: struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
699: dprintf(4, "facs=%p\n", facs);
700: if (! facs || facs->signature != FACS_SIGNATURE)
701: return 0;
702: // Found it.
703: dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector);
704: return facs->firmware_waking_vector;
705: }
706: return 0;
707: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.