Commit ab1e34add6735b5d2c1300426e8143399bc27dd8
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 | } | ... | ... |