Commit ab1e34add6735b5d2c1300426e8143399bc27dd8

Authored by bellard
1 parent 3b21e03e

moved ACPI table init to BIOS - preliminary SMM support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2170 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 113 additions and 379 deletions
hw/acpi.c
@@ -19,13 +19,11 @@ @@ -19,13 +19,11 @@
19 #include "vl.h" 19 #include "vl.h"
20 20
21 //#define DEBUG 21 //#define DEBUG
  22 +#define USE_SMM
22 23
23 /* i82731AB (PIIX4) compatible power management function */ 24 /* i82731AB (PIIX4) compatible power management function */
24 #define PM_FREQ 3579545 25 #define PM_FREQ 3579545
25 26
26 -/* XXX: make them variable */  
27 -#define PM_IO_BASE 0xb000  
28 -#define SMI_CMD_IO_ADDR 0xb040  
29 #define ACPI_DBG_IO_ADDR 0xb044 27 #define ACPI_DBG_IO_ADDR 0xb044
30 28
31 typedef struct PIIX4PMState { 29 typedef struct PIIX4PMState {
@@ -33,6 +31,8 @@ typedef struct PIIX4PMState { @@ -33,6 +31,8 @@ typedef struct PIIX4PMState {
33 uint16_t pmsts; 31 uint16_t pmsts;
34 uint16_t pmen; 32 uint16_t pmen;
35 uint16_t pmcntrl; 33 uint16_t pmcntrl;
  34 + uint8_t apmc;
  35 + uint8_t apms;
36 QEMUTimer *tmr_timer; 36 QEMUTimer *tmr_timer;
37 int64_t tmr_overflow_time; 37 int64_t tmr_overflow_time;
38 } PIIX4PMState; 38 } PIIX4PMState;
@@ -46,10 +46,6 @@ typedef struct PIIX4PMState { @@ -46,10 +46,6 @@ typedef struct PIIX4PMState {
46 46
47 #define SUS_EN (1 << 13) 47 #define SUS_EN (1 << 13)
48 48
49 -/* Note: only used for ACPI bios init. Could be deleted when ACPI init  
50 - is integrated in Bochs BIOS */  
51 -static PIIX4PMState *piix4_pm_state;  
52 -  
53 static uint32_t get_pmtmr(PIIX4PMState *s) 49 static uint32_t get_pmtmr(PIIX4PMState *s)
54 { 50 {
55 uint32_t d; 51 uint32_t d;
@@ -195,22 +191,50 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) @@ -195,22 +191,50 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
195 return val; 191 return val;
196 } 192 }
197 193
198 -static void smi_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) 194 +static void pm_smi_writeb(void *opaque, uint32_t addr, uint32_t val)
199 { 195 {
200 PIIX4PMState *s = opaque; 196 PIIX4PMState *s = opaque;
  197 + addr &= 1;
201 #ifdef DEBUG 198 #ifdef DEBUG
202 - printf("SMI cmd val=0x%02x\n", val); 199 + printf("pm_smi_writeb addr=0x%x val=0x%02x\n", addr, val);
203 #endif 200 #endif
204 - switch(val) {  
205 - case 0xf0: /* ACPI disable */  
206 - s->pmcntrl &= ~SCI_EN;  
207 - break;  
208 - case 0xf1: /* ACPI enable */  
209 - s->pmcntrl |= SCI_EN;  
210 - break; 201 + if (addr == 0) {
  202 + s->apmc = val;
  203 +#ifdef USE_SMM
  204 + cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
  205 +#else
  206 + /* emulation of what the SMM BIOS should do */
  207 + switch(val) {
  208 + case 0xf0: /* ACPI disable */
  209 + s->pmcntrl &= ~SCI_EN;
  210 + break;
  211 + case 0xf1: /* ACPI enable */
  212 + s->pmcntrl |= SCI_EN;
  213 + break;
  214 + }
  215 +#endif
  216 + } else {
  217 + s->apms = val;
211 } 218 }
212 } 219 }
213 220
  221 +static uint32_t pm_smi_readb(void *opaque, uint32_t addr)
  222 +{
  223 + PIIX4PMState *s = opaque;
  224 + uint32_t val;
  225 +
  226 + addr &= 1;
  227 + if (addr == 0) {
  228 + val = s->apmc;
  229 + } else {
  230 + val = s->apms;
  231 + }
  232 +#ifdef DEBUG
  233 + printf("pm_smi_readb addr=0x%x val=0x%02x\n", addr, val);
  234 +#endif
  235 + return val;
  236 +}
  237 +
214 static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val) 238 static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
215 { 239 {
216 #if defined(DEBUG) 240 #if defined(DEBUG)
@@ -218,17 +242,81 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val) @@ -218,17 +242,81 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
218 #endif 242 #endif
219 } 243 }
220 244
221 -/* XXX: we still add it to the PIIX3 and we count on the fact that  
222 - OSes are smart enough to accept this strange configuration */ 245 +static void pm_io_space_update(PIIX4PMState *s)
  246 +{
  247 + uint32_t pm_io_base;
  248 +
  249 + if (s->dev.config[0x80] & 1) {
  250 + pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40));
  251 + pm_io_base &= 0xfffe;
  252 +
  253 + /* XXX: need to improve memory and ioport allocation */
  254 +#if defined(DEBUG)
  255 + printf("PM: mapping to 0x%x\n", pm_io_base);
  256 +#endif
  257 + register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);
  258 + register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);
  259 + register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);
  260 + register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s);
  261 + }
  262 +}
  263 +
  264 +static void pm_write_config(PCIDevice *d,
  265 + uint32_t address, uint32_t val, int len)
  266 +{
  267 + pci_default_write_config(d, address, val, len);
  268 + if (address == 0x80)
  269 + pm_io_space_update((PIIX4PMState *)d);
  270 +}
  271 +
  272 +static void pm_save(QEMUFile* f,void *opaque)
  273 +{
  274 + PIIX4PMState *s = opaque;
  275 +
  276 + pci_device_save(&s->dev, f);
  277 +
  278 + qemu_put_be16s(f, &s->pmsts);
  279 + qemu_put_be16s(f, &s->pmen);
  280 + qemu_put_be16s(f, &s->pmcntrl);
  281 + qemu_put_8s(f, &s->apmc);
  282 + qemu_put_8s(f, &s->apms);
  283 + qemu_put_timer(f, s->tmr_timer);
  284 + qemu_put_be64s(f, &s->tmr_overflow_time);
  285 +}
  286 +
  287 +static int pm_load(QEMUFile* f,void* opaque,int version_id)
  288 +{
  289 + PIIX4PMState *s = opaque;
  290 + int ret;
  291 +
  292 + if (version_id > 1)
  293 + return -EINVAL;
  294 +
  295 + ret = pci_device_load(&s->dev, f);
  296 + if (ret < 0)
  297 + return ret;
  298 +
  299 + qemu_get_be16s(f, &s->pmsts);
  300 + qemu_get_be16s(f, &s->pmen);
  301 + qemu_get_be16s(f, &s->pmcntrl);
  302 + qemu_get_8s(f, &s->apmc);
  303 + qemu_get_8s(f, &s->apms);
  304 + qemu_get_timer(f, s->tmr_timer);
  305 + qemu_get_be64s(f, &s->tmr_overflow_time);
  306 +
  307 + pm_io_space_update(s);
  308 +
  309 + return 0;
  310 +}
  311 +
223 void piix4_pm_init(PCIBus *bus, int devfn) 312 void piix4_pm_init(PCIBus *bus, int devfn)
224 { 313 {
225 PIIX4PMState *s; 314 PIIX4PMState *s;
226 uint8_t *pci_conf; 315 uint8_t *pci_conf;
227 - uint32_t pm_io_base;  
228 316
229 s = (PIIX4PMState *)pci_register_device(bus, 317 s = (PIIX4PMState *)pci_register_device(bus,
230 "PM", sizeof(PIIX4PMState), 318 "PM", sizeof(PIIX4PMState),
231 - devfn, NULL, NULL); 319 + devfn, NULL, pm_write_config);
232 pci_conf = s->dev.config; 320 pci_conf = s->dev.config;
233 pci_conf[0x00] = 0x86; 321 pci_conf[0x00] = 0x86;
234 pci_conf[0x01] = 0x80; 322 pci_conf[0x01] = 0x80;
@@ -241,15 +329,11 @@ void piix4_pm_init(PCIBus *bus, int devfn) @@ -241,15 +329,11 @@ void piix4_pm_init(PCIBus *bus, int devfn)
241 pci_conf[0x0e] = 0x00; // header_type 329 pci_conf[0x0e] = 0x00; // header_type
242 pci_conf[0x3d] = 0x01; // interrupt pin 1 330 pci_conf[0x3d] = 0x01; // interrupt pin 1
243 331
244 - pm_io_base = PM_IO_BASE;  
245 - pci_conf[0x40] = pm_io_base | 1;  
246 - pci_conf[0x41] = pm_io_base >> 8;  
247 - register_ioport_write(pm_io_base, 64, 2, pm_ioport_writew, s);  
248 - register_ioport_read(pm_io_base, 64, 2, pm_ioport_readw, s);  
249 - register_ioport_write(pm_io_base, 64, 4, pm_ioport_writel, s);  
250 - register_ioport_read(pm_io_base, 64, 4, pm_ioport_readl, s); 332 + pci_conf[0x40] = 0x01; /* PM io base read only bit */
251 333
252 - register_ioport_write(SMI_CMD_IO_ADDR, 1, 1, smi_cmd_writeb, s); 334 + register_ioport_write(0xb2, 2, 1, pm_smi_writeb, s);
  335 + register_ioport_read(0xb2, 2, 1, pm_smi_readb, s);
  336 +
253 register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s); 337 register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
254 338
255 /* XXX: which specification is used ? The i82731AB has different 339 /* XXX: which specification is used ? The i82731AB has different
@@ -260,356 +344,6 @@ void piix4_pm_init(PCIBus *bus, int devfn) @@ -260,356 +344,6 @@ void piix4_pm_init(PCIBus *bus, int devfn)
260 (serial_hds[1] != NULL ? 0x90 : 0); 344 (serial_hds[1] != NULL ? 0x90 : 0);
261 345
262 s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s); 346 s->tmr_timer = qemu_new_timer(vm_clock, pm_tmr_timer, s);
263 - piix4_pm_state = s;  
264 -}  
265 -  
266 -/* ACPI tables */  
267 -/* XXX: move them in the Bochs BIOS ? */  
268 -  
269 -/*************************************************/  
270 -  
271 -/* Table structure from Linux kernel (the ACPI tables are under the  
272 - BSD license) */  
273 -  
274 -#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \  
275 - uint8_t signature [4]; /* ACPI signature (4 ASCII characters) */\  
276 - uint32_t length; /* Length of table, in bytes, including header */\  
277 - uint8_t revision; /* ACPI Specification minor version # */\  
278 - uint8_t checksum; /* To make sum of entire table == 0 */\  
279 - uint8_t oem_id [6]; /* OEM identification */\  
280 - uint8_t oem_table_id [8]; /* OEM table identification */\  
281 - uint32_t oem_revision; /* OEM revision number */\  
282 - uint8_t asl_compiler_id [4]; /* ASL compiler vendor ID */\  
283 - uint32_t asl_compiler_revision; /* ASL compiler revision number */  
284 -  
285 -  
286 -struct acpi_table_header /* ACPI common table header */  
287 -{  
288 - ACPI_TABLE_HEADER_DEF  
289 -};  
290 -  
291 -struct rsdp_descriptor /* Root System Descriptor Pointer */  
292 -{  
293 - uint8_t signature [8]; /* ACPI signature, contains "RSD PTR " */  
294 - uint8_t checksum; /* To make sum of struct == 0 */  
295 - uint8_t oem_id [6]; /* OEM identification */  
296 - uint8_t revision; /* Must be 0 for 1.0, 2 for 2.0 */  
297 - uint32_t rsdt_physical_address; /* 32-bit physical address of RSDT */  
298 - uint32_t length; /* XSDT Length in bytes including hdr */  
299 - uint64_t xsdt_physical_address; /* 64-bit physical address of XSDT */  
300 - uint8_t extended_checksum; /* Checksum of entire table */  
301 - uint8_t reserved [3]; /* Reserved field must be 0 */  
302 -};  
303 347
304 -/*  
305 - * ACPI 1.0 Root System Description Table (RSDT)  
306 - */  
307 -struct rsdt_descriptor_rev1  
308 -{  
309 - ACPI_TABLE_HEADER_DEF /* ACPI common table header */  
310 - uint32_t table_offset_entry [2]; /* Array of pointers to other */  
311 - /* ACPI tables */  
312 -};  
313 -  
314 -/*  
315 - * ACPI 1.0 Firmware ACPI Control Structure (FACS)  
316 - */  
317 -struct facs_descriptor_rev1  
318 -{  
319 - uint8_t signature[4]; /* ACPI Signature */  
320 - uint32_t length; /* Length of structure, in bytes */  
321 - uint32_t hardware_signature; /* Hardware configuration signature */  
322 - uint32_t firmware_waking_vector; /* ACPI OS waking vector */  
323 - uint32_t global_lock; /* Global Lock */  
324 - uint32_t S4bios_f : 1; /* Indicates if S4BIOS support is present */  
325 - uint32_t reserved1 : 31; /* Must be 0 */  
326 - uint8_t resverved3 [40]; /* Reserved - must be zero */  
327 -};  
328 -  
329 -  
330 -/*  
331 - * ACPI 1.0 Fixed ACPI Description Table (FADT)  
332 - */  
333 -struct fadt_descriptor_rev1  
334 -{  
335 - ACPI_TABLE_HEADER_DEF /* ACPI common table header */  
336 - uint32_t firmware_ctrl; /* Physical address of FACS */  
337 - uint32_t dsdt; /* Physical address of DSDT */  
338 - uint8_t model; /* System Interrupt Model */  
339 - uint8_t reserved1; /* Reserved */  
340 - uint16_t sci_int; /* System vector of SCI interrupt */  
341 - uint32_t smi_cmd; /* Port address of SMI command port */  
342 - uint8_t acpi_enable; /* Value to write to smi_cmd to enable ACPI */  
343 - uint8_t acpi_disable; /* Value to write to smi_cmd to disable ACPI */  
344 - uint8_t S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */  
345 - uint8_t reserved2; /* Reserved - must be zero */  
346 - uint32_t pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */  
347 - uint32_t pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */  
348 - uint32_t pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */  
349 - uint32_t pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */  
350 - uint32_t pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */  
351 - uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */  
352 - uint32_t gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */  
353 - uint32_t gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */  
354 - uint8_t pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */  
355 - uint8_t pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */  
356 - uint8_t pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */  
357 - uint8_t pm_tmr_len; /* Byte Length of ports at pm_tm_blk */  
358 - uint8_t gpe0_blk_len; /* Byte Length of ports at gpe0_blk */  
359 - uint8_t gpe1_blk_len; /* Byte Length of ports at gpe1_blk */  
360 - uint8_t gpe1_base; /* Offset in gpe model where gpe1 events start */  
361 - uint8_t reserved3; /* Reserved */  
362 - uint16_t plvl2_lat; /* Worst case HW latency to enter/exit C2 state */  
363 - uint16_t plvl3_lat; /* Worst case HW latency to enter/exit C3 state */  
364 - uint16_t flush_size; /* Size of area read to flush caches */  
365 - uint16_t flush_stride; /* Stride used in flushing caches */  
366 - uint8_t duty_offset; /* Bit location of duty cycle field in p_cnt reg */  
367 - uint8_t duty_width; /* Bit width of duty cycle field in p_cnt reg */  
368 - uint8_t day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */  
369 - uint8_t mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */  
370 - uint8_t century; /* Index to century in RTC CMOS RAM */  
371 - uint8_t reserved4; /* Reserved */  
372 - uint8_t reserved4a; /* Reserved */  
373 - uint8_t reserved4b; /* Reserved */  
374 -#if 0  
375 - uint32_t wb_invd : 1; /* The wbinvd instruction works properly */  
376 - uint32_t wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */  
377 - uint32_t proc_c1 : 1; /* All processors support C1 state */  
378 - uint32_t plvl2_up : 1; /* C2 state works on MP system */  
379 - uint32_t pwr_button : 1; /* Power button is handled as a generic feature */  
380 - uint32_t sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */  
381 - uint32_t fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */  
382 - uint32_t rtcs4 : 1; /* RTC wakeup stat not possible from S4 */  
383 - uint32_t tmr_val_ext : 1; /* The tmr_val width is 32 bits (0 = 24 bits) */  
384 - uint32_t reserved5 : 23; /* Reserved - must be zero */  
385 -#else  
386 - uint32_t flags;  
387 -#endif  
388 -};  
389 -  
390 -/*  
391 - * MADT values and structures  
392 - */  
393 -  
394 -/* Values for MADT PCATCompat */  
395 -  
396 -#define DUAL_PIC 0  
397 -#define MULTIPLE_APIC 1  
398 -  
399 -  
400 -/* Master MADT */  
401 -  
402 -struct multiple_apic_table  
403 -{  
404 - ACPI_TABLE_HEADER_DEF /* ACPI common table header */  
405 - uint32_t local_apic_address; /* Physical address of local APIC */  
406 -#if 0  
407 - uint32_t PCATcompat : 1; /* A one indicates system also has dual 8259s */  
408 - uint32_t reserved1 : 31;  
409 -#else  
410 - uint32_t flags;  
411 -#endif  
412 -};  
413 -  
414 -  
415 -/* Values for Type in APIC_HEADER_DEF */  
416 -  
417 -#define APIC_PROCESSOR 0  
418 -#define APIC_IO 1  
419 -#define APIC_XRUPT_OVERRIDE 2  
420 -#define APIC_NMI 3  
421 -#define APIC_LOCAL_NMI 4  
422 -#define APIC_ADDRESS_OVERRIDE 5  
423 -#define APIC_IO_SAPIC 6  
424 -#define APIC_LOCAL_SAPIC 7  
425 -#define APIC_XRUPT_SOURCE 8  
426 -#define APIC_RESERVED 9 /* 9 and greater are reserved */  
427 -  
428 -/*  
429 - * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)  
430 - */  
431 -#define APIC_HEADER_DEF /* Common APIC sub-structure header */\  
432 - uint8_t type; \  
433 - uint8_t length;  
434 -  
435 -/* Sub-structures for MADT */  
436 -  
437 -struct madt_processor_apic  
438 -{  
439 - APIC_HEADER_DEF  
440 - uint8_t processor_id; /* ACPI processor id */  
441 - uint8_t local_apic_id; /* Processor's local APIC id */  
442 -#if 0  
443 - uint32_t processor_enabled: 1; /* Processor is usable if set */  
444 - uint32_t reserved2 : 31; /* Reserved, must be zero */  
445 -#else  
446 - uint32_t flags;  
447 -#endif  
448 -};  
449 -  
450 -struct madt_io_apic  
451 -{  
452 - APIC_HEADER_DEF  
453 - uint8_t io_apic_id; /* I/O APIC ID */  
454 - uint8_t reserved; /* Reserved - must be zero */  
455 - uint32_t address; /* APIC physical address */  
456 - uint32_t interrupt; /* Global system interrupt where INTI  
457 - * lines start */  
458 -};  
459 -  
460 -#include "acpi-dsdt.hex"  
461 -  
462 -static int acpi_checksum(const uint8_t *data, int len)  
463 -{  
464 - int sum, i;  
465 - sum = 0;  
466 - for(i = 0; i < len; i++)  
467 - sum += data[i];  
468 - return (-sum) & 0xff;  
469 -}  
470 -  
471 -static void acpi_build_table_header(struct acpi_table_header *h,  
472 - char *sig, int len)  
473 -{  
474 - memcpy(h->signature, sig, 4);  
475 - h->length = cpu_to_le32(len);  
476 - h->revision = 0;  
477 - memcpy(h->oem_id, "QEMU ", 6);  
478 - memcpy(h->oem_table_id, "QEMU", 4);  
479 - memcpy(h->oem_table_id + 4, sig, 4);  
480 - h->oem_revision = cpu_to_le32(1);  
481 - memcpy(h->asl_compiler_id, "QEMU", 4);  
482 - h->asl_compiler_revision = cpu_to_le32(1);  
483 - h->checksum = acpi_checksum((void *)h, len);  
484 -}  
485 -  
486 -#define ACPI_TABLES_BASE 0x000e8000  
487 -  
488 -/* base_addr must be a multiple of 4KB */  
489 -void acpi_bios_init(void)  
490 -{  
491 - struct rsdp_descriptor *rsdp;  
492 - struct rsdt_descriptor_rev1 *rsdt;  
493 - struct fadt_descriptor_rev1 *fadt;  
494 - struct facs_descriptor_rev1 *facs;  
495 - struct multiple_apic_table *madt;  
496 - uint8_t *dsdt;  
497 - uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr;  
498 - uint32_t pm_io_base, acpi_tables_size, madt_addr, madt_size;  
499 - int i;  
500 -  
501 - /* compute PCI I/O addresses */  
502 - pm_io_base = (piix4_pm_state->dev.config[0x40] |  
503 - (piix4_pm_state->dev.config[0x41] << 8)) & ~0x3f;  
504 -  
505 - base_addr = ACPI_TABLES_BASE;  
506 -  
507 - /* reserve memory space for tables */  
508 - addr = base_addr;  
509 - rsdp = (void *)(phys_ram_base + addr);  
510 - addr += sizeof(*rsdp);  
511 -  
512 - rsdt_addr = addr;  
513 - rsdt = (void *)(phys_ram_base + addr);  
514 - addr += sizeof(*rsdt);  
515 -  
516 - fadt_addr = addr;  
517 - fadt = (void *)(phys_ram_base + addr);  
518 - addr += sizeof(*fadt);  
519 -  
520 - /* XXX: FACS should be in RAM */  
521 - addr = (addr + 63) & ~63; /* 64 byte alignment for FACS */  
522 - facs_addr = addr;  
523 - facs = (void *)(phys_ram_base + addr);  
524 - addr += sizeof(*facs);  
525 -  
526 - dsdt_addr = addr;  
527 - dsdt = (void *)(phys_ram_base + addr);  
528 - addr += sizeof(AmlCode);  
529 -  
530 - addr = (addr + 7) & ~7;  
531 - madt_addr = addr;  
532 - madt_size = sizeof(*madt) +  
533 - sizeof(struct madt_processor_apic) * smp_cpus +  
534 - sizeof(struct madt_io_apic);  
535 - madt = (void *)(phys_ram_base + addr);  
536 - addr += madt_size;  
537 -  
538 - acpi_tables_size = addr - base_addr;  
539 -  
540 - cpu_register_physical_memory(base_addr, acpi_tables_size,  
541 - base_addr | IO_MEM_ROM);  
542 -  
543 - /* RSDP */  
544 - memset(rsdp, 0, sizeof(*rsdp));  
545 - memcpy(rsdp->signature, "RSD PTR ", 8);  
546 - memcpy(rsdp->oem_id, "QEMU ", 6);  
547 - rsdp->rsdt_physical_address = cpu_to_le32(rsdt_addr);  
548 - rsdp->checksum = acpi_checksum((void *)rsdp, 20);  
549 -  
550 - /* RSDT */  
551 - rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);  
552 - rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);  
553 - acpi_build_table_header((struct acpi_table_header *)rsdt,  
554 - "RSDT", sizeof(*rsdt));  
555 -  
556 - /* FADT */  
557 - memset(fadt, 0, sizeof(*fadt));  
558 - fadt->firmware_ctrl = cpu_to_le32(facs_addr);  
559 - fadt->dsdt = cpu_to_le32(dsdt_addr);  
560 - fadt->model = 1;  
561 - fadt->reserved1 = 0;  
562 - fadt->sci_int = cpu_to_le16(piix4_pm_state->dev.config[0x3c]);  
563 - fadt->smi_cmd = cpu_to_le32(SMI_CMD_IO_ADDR);  
564 - fadt->acpi_enable = 0xf1;  
565 - fadt->acpi_disable = 0xf0;  
566 - fadt->pm1a_evt_blk = cpu_to_le32(pm_io_base);  
567 - fadt->pm1a_cnt_blk = cpu_to_le32(pm_io_base + 0x04);  
568 - fadt->pm_tmr_blk = cpu_to_le32(pm_io_base + 0x08);  
569 - fadt->pm1_evt_len = 4;  
570 - fadt->pm1_cnt_len = 2;  
571 - fadt->pm_tmr_len = 4;  
572 - fadt->plvl2_lat = cpu_to_le16(50);  
573 - fadt->plvl3_lat = cpu_to_le16(50);  
574 - fadt->plvl3_lat = cpu_to_le16(50);  
575 - /* WBINVD + PROC_C1 + PWR_BUTTON + SLP_BUTTON + FIX_RTC */  
576 - fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 4) | (1 << 5) | (1 << 6));  
577 - acpi_build_table_header((struct acpi_table_header *)fadt, "FACP",  
578 - sizeof(*fadt));  
579 -  
580 - /* FACS */  
581 - memset(facs, 0, sizeof(*facs));  
582 - memcpy(facs->signature, "FACS", 4);  
583 - facs->length = cpu_to_le32(sizeof(*facs));  
584 -  
585 - /* DSDT */  
586 - memcpy(dsdt, AmlCode, sizeof(AmlCode));  
587 -  
588 - /* MADT */  
589 - {  
590 - struct madt_processor_apic *apic;  
591 - struct madt_io_apic *io_apic;  
592 -  
593 - memset(madt, 0, madt_size);  
594 - madt->local_apic_address = cpu_to_le32(0xfee00000);  
595 - madt->flags = cpu_to_le32(1);  
596 - apic = (void *)(madt + 1);  
597 - for(i=0;i<smp_cpus;i++) {  
598 - apic->type = APIC_PROCESSOR;  
599 - apic->length = sizeof(*apic);  
600 - apic->processor_id = i;  
601 - apic->local_apic_id = i;  
602 - apic->flags = cpu_to_le32(1);  
603 - apic++;  
604 - }  
605 - io_apic = (void *)apic;  
606 - io_apic->type = APIC_IO;  
607 - io_apic->length = sizeof(*io_apic);  
608 - io_apic->io_apic_id = smp_cpus;  
609 - io_apic->address = cpu_to_le32(0xfec00000);  
610 - io_apic->interrupt = cpu_to_le32(0);  
611 -  
612 - acpi_build_table_header((struct acpi_table_header *)madt,  
613 - "APIC", madt_size);  
614 - } 348 + register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s);
615 } 349 }