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 19 #include "vl.h"
20 20  
21 21 //#define DEBUG
  22 +#define USE_SMM
22 23  
23 24 /* i82731AB (PIIX4) compatible power management function */
24 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 27 #define ACPI_DBG_IO_ADDR 0xb044
30 28  
31 29 typedef struct PIIX4PMState {
... ... @@ -33,6 +31,8 @@ typedef struct PIIX4PMState {
33 31 uint16_t pmsts;
34 32 uint16_t pmen;
35 33 uint16_t pmcntrl;
  34 + uint8_t apmc;
  35 + uint8_t apms;
36 36 QEMUTimer *tmr_timer;
37 37 int64_t tmr_overflow_time;
38 38 } PIIX4PMState;
... ... @@ -46,10 +46,6 @@ typedef struct PIIX4PMState {
46 46  
47 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 49 static uint32_t get_pmtmr(PIIX4PMState *s)
54 50 {
55 51 uint32_t d;
... ... @@ -195,22 +191,50 @@ static uint32_t pm_ioport_readl(void *opaque, uint32_t addr)
195 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 196 PIIX4PMState *s = opaque;
  197 + addr &= 1;
201 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 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 238 static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
215 239 {
216 240 #if defined(DEBUG)
... ... @@ -218,17 +242,81 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val)
218 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 312 void piix4_pm_init(PCIBus *bus, int devfn)
224 313 {
225 314 PIIX4PMState *s;
226 315 uint8_t *pci_conf;
227   - uint32_t pm_io_base;
228 316  
229 317 s = (PIIX4PMState *)pci_register_device(bus,
230 318 "PM", sizeof(PIIX4PMState),
231   - devfn, NULL, NULL);
  319 + devfn, NULL, pm_write_config);
232 320 pci_conf = s->dev.config;
233 321 pci_conf[0x00] = 0x86;
234 322 pci_conf[0x01] = 0x80;
... ... @@ -241,15 +329,11 @@ void piix4_pm_init(PCIBus *bus, int devfn)
241 329 pci_conf[0x0e] = 0x00; // header_type
242 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 337 register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s);
254 338  
255 339 /* XXX: which specification is used ? The i82731AB has different
... ... @@ -260,356 +344,6 @@ void piix4_pm_init(PCIBus *bus, int devfn)
260 344 (serial_hds[1] != NULL ? 0x90 : 0);
261 345  
262 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 }
... ...