Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / src / acpi.c
1 // Support for generating ACPI tables (on emulators)
2 //
3 // Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
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
10 #include "pci.h" // pci_find_init_device
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
160 #define HPET_ID         0x000
161 #define HPET_PERIOD     0x004
162
163 /*
164  * SRAT (NUMA topology description) table
165  */
166
167 #define SRAT_PROCESSOR          0
168 #define SRAT_MEMORY             1
169
170 struct system_resource_affinity_table
171 {
172     ACPI_TABLE_HEADER_DEF
173     u32    reserved1;
174     u32    reserved2[2];
175 } PACKED;
176
177 struct srat_processor_affinity
178 {
179     ACPI_SUB_HEADER_DEF
180     u8     proximity_lo;
181     u8     local_apic_id;
182     u32    flags;
183     u8     local_sapic_eid;
184     u8     proximity_hi[3];
185     u32    reserved;
186 } PACKED;
187
188 struct srat_memory_affinity
189 {
190     ACPI_SUB_HEADER_DEF
191     u8     proximity[4];
192     u16    reserved1;
193     u32    base_addr_low,base_addr_high;
194     u32    length_low,length_high;
195     u32    reserved2;
196     u32    flags;
197     u32    reserved3[2];
198 } PACKED;
199
200 #include "acpi-dsdt.hex"
201
202 static void
203 build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
204 {
205     h->signature = sig;
206     h->length = cpu_to_le32(len);
207     h->revision = rev;
208     memcpy(h->oem_id, CONFIG_APPNAME6, 6);
209     memcpy(h->oem_table_id, CONFIG_APPNAME4, 4);
210     memcpy(h->oem_table_id + 4, (void*)&sig, 4);
211     h->oem_revision = cpu_to_le32(1);
212     memcpy(h->asl_compiler_id, CONFIG_APPNAME4, 4);
213     h->asl_compiler_revision = cpu_to_le32(1);
214     h->checksum -= checksum(h, len);
215 }
216
217 #define PIIX4_ACPI_ENABLE       0xf1
218 #define PIIX4_ACPI_DISABLE      0xf0
219 #define PIIX4_GPE0_BLK          0xafe0
220 #define PIIX4_GPE0_BLK_LEN      4
221
222 static void piix4_fadt_init(struct pci_device *pci, void *arg)
223 {
224     struct fadt_descriptor_rev1 *fadt = arg;
225     fadt->acpi_enable = PIIX4_ACPI_ENABLE;
226     fadt->acpi_disable = PIIX4_ACPI_DISABLE;
227     fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK);
228     fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN;
229 }
230
231 static const struct pci_device_id fadt_init_tbl[] = {
232     /* PIIX4 Power Management device (for ACPI) */
233     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3,
234                piix4_fadt_init),
235
236     PCI_DEVICE_END
237 };
238
239 static void *
240 build_fadt(struct pci_device *pci)
241 {
242     struct fadt_descriptor_rev1 *fadt = malloc_high(sizeof(*fadt));
243     struct facs_descriptor_rev1 *facs = memalign_high(64, sizeof(*facs));
244     void *dsdt = malloc_high(sizeof(AmlCode));
245
246     if (!fadt || !facs || !dsdt) {
247         warn_noalloc();
248         return NULL;
249     }
250
251     /* FACS */
252     memset(facs, 0, sizeof(*facs));
253     facs->signature = FACS_SIGNATURE;
254     facs->length = cpu_to_le32(sizeof(*facs));
255
256     /* DSDT */
257     memcpy(dsdt, AmlCode, sizeof(AmlCode));
258
259     /* FADT */
260     memset(fadt, 0, sizeof(*fadt));
261     fadt->firmware_ctrl = cpu_to_le32((u32)facs);
262     fadt->dsdt = cpu_to_le32((u32)dsdt);
263     fadt->model = 1;
264     fadt->reserved1 = 0;
265
266     if (pci) {
267         int pm_sci_int = pci_config_readb(pci->bdf, PCI_INTERRUPT_LINE);
268
269         fadt->sci_int = cpu_to_le16(pm_sci_int);
270         fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD);
271         fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE);
272         fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04);
273         fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08);
274         fadt->pm1_evt_len = 4;
275         fadt->pm1_cnt_len = 2;
276         fadt->pm_tmr_len = 4;
277
278
279         fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
280         fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
281         pci_init_device(fadt_init_tbl, pci, fadt);
282     } else {
283
284         fadt->sci_int = 0;
285         fadt->smi_cmd = 0;
286         fadt->pm1a_evt_blk = 0;
287         fadt->pm1a_cnt_blk = 0;
288         fadt->pm_tmr_blk = 0;
289         fadt->pm1_evt_len = 0;
290         fadt->pm1_cnt_len = 0;
291         fadt->pm_tmr_len = 0;
292
293
294         fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported
295         fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported
296         
297         // No PIIX4 to init
298         //      pci_init_device(fadt_init_tbl, pci, fadt);
299
300     }
301
302     /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC + RTC_S4 */
303     fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6) | (1 << 7));
304
305     build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1);
306
307     return fadt;
308 }
309
310 static void*
311 build_madt(void)
312 {
313     int madt_size = (sizeof(struct multiple_apic_table)
314                      + sizeof(struct madt_processor_apic) * MaxCountCPUs
315                      + sizeof(struct madt_io_apic)
316                      + sizeof(struct madt_intsrcovr) * 16);
317     struct multiple_apic_table *madt = malloc_high(madt_size);
318     if (!madt) {
319         warn_noalloc();
320         return NULL;
321     }
322     memset(madt, 0, madt_size);
323     madt->local_apic_address = cpu_to_le32(BUILD_APIC_ADDR);
324     madt->flags = cpu_to_le32(1);
325     struct madt_processor_apic *apic = (void*)&madt[1];
326     int i;
327     for (i=0; i<MaxCountCPUs; i++) {
328         apic->type = APIC_PROCESSOR;
329         apic->length = sizeof(*apic);
330         apic->processor_id = i;
331         apic->local_apic_id = i;
332         if (i < CountCPUs)
333             apic->flags = cpu_to_le32(1);
334         else
335             apic->flags = cpu_to_le32(0);
336         apic++;
337     }
338     struct madt_io_apic *io_apic = (void*)apic;
339     io_apic->type = APIC_IO;
340     io_apic->length = sizeof(*io_apic);
341     io_apic->io_apic_id = CountCPUs;
342     io_apic->address = cpu_to_le32(BUILD_IOAPIC_ADDR);
343     io_apic->interrupt = cpu_to_le32(0);
344
345     struct madt_intsrcovr *intsrcovr = (void*)&io_apic[1];
346     if (qemu_cfg_irq0_override()) {
347         memset(intsrcovr, 0, sizeof(*intsrcovr));
348         intsrcovr->type   = APIC_XRUPT_OVERRIDE;
349         intsrcovr->length = sizeof(*intsrcovr);
350         intsrcovr->source = 0;
351         intsrcovr->gsi    = 2;
352         intsrcovr->flags  = 0; /* conforms to bus specifications */
353         intsrcovr++;
354     }
355     for (i = 1; i < 16; i++) {
356         if (!(PCI_ISA_IRQ_MASK & (1 << i)))
357             /* No need for a INT source override structure. */
358             continue;
359         memset(intsrcovr, 0, sizeof(*intsrcovr));
360         intsrcovr->type   = APIC_XRUPT_OVERRIDE;
361         intsrcovr->length = sizeof(*intsrcovr);
362         intsrcovr->source = i;
363         intsrcovr->gsi    = i;
364         intsrcovr->flags  = 0xd; /* active high, level triggered */
365         intsrcovr++;
366     }
367
368     build_header((void*)madt, APIC_SIGNATURE, (void*)intsrcovr - (void*)madt, 1);
369     return madt;
370 }
371
372 // Encode a hex value
373 static inline char getHex(u32 val) {
374     val &= 0x0f;
375     return (val <= 9) ? ('0' + val) : ('A' + val - 10);
376 }
377
378 // Encode a length in an SSDT.
379 static u8 *
380 encodeLen(u8 *ssdt_ptr, int length, int bytes)
381 {
382     switch (bytes) {
383     default:
384     case 4: ssdt_ptr[3] = ((length >> 20) & 0xff);
385     case 3: ssdt_ptr[2] = ((length >> 12) & 0xff);
386     case 2: ssdt_ptr[1] = ((length >> 4) & 0xff);
387             ssdt_ptr[0] = (((bytes-1) & 0x3) << 6) | (length & 0x0f);
388             break;
389     case 1: ssdt_ptr[0] = length & 0x3f;
390     }
391     return ssdt_ptr + bytes;
392 }
393
394 // AML Processor() object.  See src/ssdt-proc.dsl for info.
395 static unsigned char ssdt_proc[] = {
396     0x5b,0x83,0x42,0x05,0x43,0x50,0x41,0x41,
397     0xaa,0x10,0xb0,0x00,0x00,0x06,0x08,0x49,
398     0x44,0x5f,0x5f,0x0a,0xaa,0x08,0x5f,0x48,
399     0x49,0x44,0x0d,0x41,0x43,0x50,0x49,0x30,
400     0x30,0x30,0x37,0x00,0x14,0x0f,0x5f,0x4d,
401     0x41,0x54,0x00,0xa4,0x43,0x50,0x4d,0x41,
402     0x49,0x44,0x5f,0x5f,0x14,0x0f,0x5f,0x53,
403     0x54,0x41,0x00,0xa4,0x43,0x50,0x53,0x54,
404     0x49,0x44,0x5f,0x5f,0x14,0x0f,0x5f,0x45,
405     0x4a,0x30,0x01,0x43,0x50,0x45,0x4a,0x49,
406     0x44,0x5f,0x5f,0x68
407 };
408 #define SD_OFFSET_CPUHEX 6
409 #define SD_OFFSET_CPUID1 8
410 #define SD_OFFSET_CPUID2 20
411
412 #define SSDT_SIGNATURE 0x54445353 // SSDT
413 static void*
414 build_ssdt(void)
415 {
416     int acpi_cpus = MaxCountCPUs > 0xff ? 0xff : MaxCountCPUs;
417     // length = ScopeOp + procs + NTYF method + CPON package
418     int length = ((1+3+4)
419                   + (acpi_cpus * sizeof(ssdt_proc))
420                   + (1+2+5+(12*acpi_cpus))
421                   + (6+2+1+(1*acpi_cpus)));
422     u8 *ssdt = malloc_high(sizeof(struct acpi_table_header) + length);
423     if (! ssdt) {
424         warn_noalloc();
425         return NULL;
426     }
427     u8 *ssdt_ptr = ssdt + sizeof(struct acpi_table_header);
428
429     // build Scope(_SB_) header
430     *(ssdt_ptr++) = 0x10; // ScopeOp
431     ssdt_ptr = encodeLen(ssdt_ptr, length-1, 3);
432     *(ssdt_ptr++) = '_';
433     *(ssdt_ptr++) = 'S';
434     *(ssdt_ptr++) = 'B';
435     *(ssdt_ptr++) = '_';
436
437     // build Processor object for each processor
438     int i;
439     for (i=0; i<acpi_cpus; i++) {
440         memcpy(ssdt_ptr, ssdt_proc, sizeof(ssdt_proc));
441         ssdt_ptr[SD_OFFSET_CPUHEX] = getHex(i >> 4);
442         ssdt_ptr[SD_OFFSET_CPUHEX+1] = getHex(i);
443         ssdt_ptr[SD_OFFSET_CPUID1] = i;
444         ssdt_ptr[SD_OFFSET_CPUID2] = i;
445         ssdt_ptr += sizeof(ssdt_proc);
446     }
447
448     // build "Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}"
449     *(ssdt_ptr++) = 0x14; // MethodOp
450     ssdt_ptr = encodeLen(ssdt_ptr, 2+5+(12*acpi_cpus), 2);
451     *(ssdt_ptr++) = 'N';
452     *(ssdt_ptr++) = 'T';
453     *(ssdt_ptr++) = 'F';
454     *(ssdt_ptr++) = 'Y';
455     *(ssdt_ptr++) = 0x02;
456     for (i=0; i<acpi_cpus; i++) {
457         *(ssdt_ptr++) = 0xA0; // IfOp
458         ssdt_ptr = encodeLen(ssdt_ptr, 11, 1);
459         *(ssdt_ptr++) = 0x93; // LEqualOp
460         *(ssdt_ptr++) = 0x68; // Arg0Op
461         *(ssdt_ptr++) = 0x0A; // BytePrefix
462         *(ssdt_ptr++) = i;
463         *(ssdt_ptr++) = 0x86; // NotifyOp
464         *(ssdt_ptr++) = 'C';
465         *(ssdt_ptr++) = 'P';
466         *(ssdt_ptr++) = getHex(i >> 4);
467         *(ssdt_ptr++) = getHex(i);
468         *(ssdt_ptr++) = 0x69; // Arg1Op
469     }
470
471     // build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
472     *(ssdt_ptr++) = 0x08; // NameOp
473     *(ssdt_ptr++) = 'C';
474     *(ssdt_ptr++) = 'P';
475     *(ssdt_ptr++) = 'O';
476     *(ssdt_ptr++) = 'N';
477     *(ssdt_ptr++) = 0x12; // PackageOp
478     ssdt_ptr = encodeLen(ssdt_ptr, 2+1+(1*acpi_cpus), 2);
479     *(ssdt_ptr++) = acpi_cpus;
480     for (i=0; i<acpi_cpus; i++)
481         *(ssdt_ptr++) = (i < CountCPUs) ? 0x01 : 0x00;
482
483     build_header((void*)ssdt, SSDT_SIGNATURE, ssdt_ptr - ssdt, 1);
484
485     //hexdump(ssdt, ssdt_ptr - ssdt);
486
487     return ssdt;
488 }
489
490 #define HPET_SIGNATURE 0x54455048 // HPET
491 static void*
492 build_hpet(void)
493 {
494     struct acpi_20_hpet *hpet;
495     const void *hpet_base = (void *)BUILD_HPET_ADDRESS;
496     u32 hpet_vendor = readl(hpet_base + HPET_ID) >> 16;
497     u32 hpet_period = readl(hpet_base + HPET_PERIOD);
498
499     if (hpet_vendor == 0 || hpet_vendor == 0xffff ||
500         hpet_period == 0 || hpet_period > 100000000)
501         return NULL;
502
503     hpet = malloc_high(sizeof(*hpet));
504     if (!hpet) {
505         warn_noalloc();
506         return NULL;
507     }
508
509     memset(hpet, 0, sizeof(*hpet));
510     /* Note timer_block_id value must be kept in sync with value advertised by
511      * emulated hpet
512      */
513     hpet->timer_block_id = cpu_to_le32(0x8086a201);
514     hpet->addr.address = cpu_to_le32(BUILD_HPET_ADDRESS);
515     build_header((void*)hpet, HPET_SIGNATURE, sizeof(*hpet), 1);
516
517     return hpet;
518 }
519
520 static void
521 acpi_build_srat_memory(struct srat_memory_affinity *numamem,
522                        u64 base, u64 len, int node, int enabled)
523 {
524     numamem->type = SRAT_MEMORY;
525     numamem->length = sizeof(*numamem);
526     memset(numamem->proximity, 0 ,4);
527     numamem->proximity[0] = node;
528     numamem->flags = cpu_to_le32(!!enabled);
529     numamem->base_addr_low = base & 0xFFFFFFFF;
530     numamem->base_addr_high = base >> 32;
531     numamem->length_low = len & 0xFFFFFFFF;
532     numamem->length_high = len >> 32;
533 }
534
535 #define SRAT_SIGNATURE 0x54415253 // SRAT
536 static void *
537 build_srat(void)
538 {
539     int nb_numa_nodes = qemu_cfg_get_numa_nodes();
540
541     if (nb_numa_nodes == 0)
542         return NULL;
543
544     u64 *numadata = malloc_tmphigh(sizeof(u64) * (MaxCountCPUs + nb_numa_nodes));
545     if (!numadata) {
546         warn_noalloc();
547         return NULL;
548     }
549
550     qemu_cfg_get_numa_data(numadata, MaxCountCPUs + nb_numa_nodes);
551
552     struct system_resource_affinity_table *srat;
553     int srat_size = sizeof(*srat) +
554         sizeof(struct srat_processor_affinity) * MaxCountCPUs +
555         sizeof(struct srat_memory_affinity) * (nb_numa_nodes + 2);
556
557     srat = malloc_high(srat_size);
558     if (!srat) {
559         warn_noalloc();
560         free(numadata);
561         return NULL;
562     }
563
564     memset(srat, 0, srat_size);
565     srat->reserved1=1;
566     struct srat_processor_affinity *core = (void*)(srat + 1);
567     int i;
568     u64 curnode;
569
570     for (i = 0; i < MaxCountCPUs; ++i) {
571         core->type = SRAT_PROCESSOR;
572         core->length = sizeof(*core);
573         core->local_apic_id = i;
574         curnode = *numadata++;
575         core->proximity_lo = curnode;
576         memset(core->proximity_hi, 0, 3);
577         core->local_sapic_eid = 0;
578         if (i < CountCPUs)
579             core->flags = cpu_to_le32(1);
580         else
581             core->flags = 0;
582         core++;
583     }
584
585
586     /* the memory map is a bit tricky, it contains at least one hole
587      * from 640k-1M and possibly another one from 3.5G-4G.
588      */
589     struct srat_memory_affinity *numamem = (void*)core;
590     int slots = 0;
591     u64 mem_len, mem_base, next_base = 0;
592
593     acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
594     next_base = 1024 * 1024;
595     numamem++;
596     slots++;
597     for (i = 1; i < nb_numa_nodes + 1; ++i) {
598         mem_base = next_base;
599         mem_len = *numadata++;
600         if (i == 1)
601             mem_len -= 1024 * 1024;
602         next_base = mem_base + mem_len;
603
604         /* Cut out the PCI hole */
605         if (mem_base <= RamSize && next_base > RamSize) {
606             mem_len -= next_base - RamSize;
607             if (mem_len > 0) {
608                 acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
609                 numamem++;
610                 slots++;
611             }
612             mem_base = 1ULL << 32;
613             mem_len = next_base - RamSize;
614             next_base += (1ULL << 32) - RamSize;
615         }
616         acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
617         numamem++;
618         slots++;
619     }
620     for (; slots < nb_numa_nodes + 2; slots++) {
621         acpi_build_srat_memory(numamem, 0, 0, 0, 0);
622         numamem++;
623     }
624
625     build_header((void*)srat, SRAT_SIGNATURE, srat_size, 1);
626
627     free(numadata);
628     return srat;
629 }
630
631 static const struct pci_device_id acpi_find_tbl[] = {
632     /* PIIX4 Power Management device. */
633     PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL),
634
635     PCI_DEVICE_END,
636 };
637
638 struct rsdp_descriptor *RsdpAddr;
639
640 #define MAX_ACPI_TABLES 20
641 void
642 acpi_bios_init(void)
643 {
644     if (! CONFIG_ACPI)
645         return;
646
647     dprintf(3, "init ACPI tables\n");
648
649     // This code is hardcoded for PIIX4 Power Management device.
650     struct pci_device *pci = pci_find_init_device(acpi_find_tbl, NULL);
651
652     /* 
653     if (!pci) {
654         // Device not found
655         return;
656     */
657     if (!pci) {
658         /* JRL: No PIIX4: Disable power management ACPI functions */
659         dprintf(1, "No PIIX4 (v3vee): Disabling ACPI power management functions\n");
660     }
661
662
663     // Build ACPI tables
664     u32 tables[MAX_ACPI_TABLES], tbl_idx = 0;
665
666 #define ACPI_INIT_TABLE(X)                                   \
667     do {                                                     \
668         tables[tbl_idx] = (u32)(X);                          \
669         if (tables[tbl_idx])                                 \
670             tbl_idx++;                                       \
671     } while(0)
672
673     ACPI_INIT_TABLE(build_fadt(pci));
674     ACPI_INIT_TABLE(build_ssdt());
675     ACPI_INIT_TABLE(build_madt());
676     if (pci) {
677         ACPI_INIT_TABLE(build_hpet());
678     }
679     ACPI_INIT_TABLE(build_srat());
680
681     u16 i, external_tables = qemu_cfg_acpi_additional_tables();
682
683     for (i = 0; i < external_tables; i++) {
684         u16 len = qemu_cfg_next_acpi_table_len();
685         void *addr = malloc_high(len);
686         if (!addr) {
687             warn_noalloc();
688             continue;
689         }
690         ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len));
691         if (tbl_idx == MAX_ACPI_TABLES) {
692             warn_noalloc();
693             break;
694         }
695     }
696
697     // Build final rsdt table
698     struct rsdt_descriptor_rev1 *rsdt;
699     size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx;
700     rsdt = malloc_high(rsdt_len);
701     if (!rsdt) {
702         warn_noalloc();
703         return;
704     }
705     memset(rsdt, 0, rsdt_len);
706     memcpy(rsdt->table_offset_entry, tables, sizeof(u32) * tbl_idx);
707     build_header((void*)rsdt, RSDT_SIGNATURE, rsdt_len, 1);
708
709     // Build rsdp pointer table
710     struct rsdp_descriptor *rsdp = malloc_fseg(sizeof(*rsdp));
711     if (!rsdp) {
712         warn_noalloc();
713         return;
714     }
715     memset(rsdp, 0, sizeof(*rsdp));
716     rsdp->signature = RSDP_SIGNATURE;
717     memcpy(rsdp->oem_id, CONFIG_APPNAME6, 6);
718     rsdp->rsdt_physical_address = cpu_to_le32((u32)rsdt);
719     rsdp->checksum -= checksum(rsdp, 20);
720     RsdpAddr = rsdp;
721     dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt);
722 }
723
724 u32
725 find_resume_vector(void)
726 {
727     dprintf(4, "rsdp=%p\n", RsdpAddr);
728     if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE)
729         return 0;
730     struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address;
731     dprintf(4, "rsdt=%p\n", rsdt);
732     if (!rsdt || rsdt->signature != RSDT_SIGNATURE)
733         return 0;
734     void *end = (void*)rsdt + rsdt->length;
735     int i;
736     for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) {
737         struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[i];
738         if (!fadt || fadt->signature != FACP_SIGNATURE)
739             continue;
740         dprintf(4, "fadt=%p\n", fadt);
741         struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl;
742         dprintf(4, "facs=%p\n", facs);
743         if (! facs || facs->signature != FACS_SIGNATURE)
744             return 0;
745         // Found it.
746         dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector);
747         return facs->firmware_waking_vector;
748     }
749     return 0;
750 }