Signed-off-by: Gleb Natapov <[EMAIL PROTECTED]> --- bios/acpi-dsdt.dsl | 33 ++++++++++++++++++----- bios/rombios.c | 35 +++++++++++++++++++++++++ bios/rombios32.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 130 insertions(+), 12 deletions(-)
diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl index 577b3fe..02f53a1 100755 --- a/bios/acpi-dsdt.dsl +++ b/bios/acpi-dsdt.dsl @@ -65,6 +65,32 @@ DefinitionBlock ( gen_processor(14, E) } + /* + * S3 (suspend-to-ram), S4 (suspend-to-disc) and S5 (power-off) type codes: + * must match piix4 emulation. + */ + Name (\_S3, Package (0x04) + { + 0x01, /* PM1a_CNT.SLP_TYP */ + 0x01, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + Name (\_S4, Package (0x04) + { + Zero, /* PM1a_CNT.SLP_TYP */ + Zero, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + Name (\_S5, Package (0x04) + { + Zero, /* PM1a_CNT.SLP_TYP */ + Zero, /* PM1b_CNT.SLP_TYP */ + Zero, /* reserved */ + Zero /* reserved */ + }) + Scope (\) { /* Debug Output */ @@ -626,13 +652,6 @@ DefinitionBlock ( } } - /* S5 = power off state */ - Name (_S5, Package (4) { - 0x00, // PM1a_CNT.SLP_TYP - 0x00, // PM2a_CNT.SLP_TYP - 0x00, // reserved - 0x00, // reserved - }) Scope (\_GPE) { diff --git a/bios/rombios.c b/bios/rombios.c index 529f3bd..5c75043 100644 --- a/bios/rombios.c +++ b/bios/rombios.c @@ -2198,6 +2198,32 @@ debugger_off() outb(0xfedc, 0x00); } +void +s3_resume() +{ + Bit32u s3_wakeup_vector; + Bit8u s3_resume_flag; + + s3_resume_flag = read_byte(0x40, 0xb0); + s3_wakeup_vector = read_dword(0x40, 0xb2); + + BX_INFO("S3 resume called %x 0x%lx\n", s3_resume_flag, s3_wakeup_vector); + if (s3_resume_flag != 0xFE || !s3_wakeup_vector) + return; + + write_byte(0x40, 0xb0, 0); + + /* setup wakeup vector */ + write_word(0x40, 0xb6, (s3_wakeup_vector & 0xF)); /* IP */ + write_word(0x40, 0xb8, (s3_wakeup_vector >> 4)); /* CS */ + + BX_INFO("S3 resume jump to %x:%x\n", *(Bit16u*)0x04b8, *(Bit16u*)0x04b6); +ASM_START + mov sp, #0 ;; disable tpr patching on boot CPU + jmpf [0x04b6] +ASM_END +} + #if BX_USE_ATADRV // --------------------------------------------------------------------------- @@ -10036,6 +10062,10 @@ rombios32_05: ;; init the stack pointer mov esp, #0x00080000 + ;; pass pointer to s3_resume_flag and s3_resume_vector to rombios32 + push #0x04b0 + push #0x04b2 + ;; call rombios32 code mov eax, #0x00040000 call eax @@ -10424,6 +10454,9 @@ normal_post: rep stosw + ;; Save shutdown status + mov 0x04b0, bl + call _log_bios_start ;; set all interrupts to default handler @@ -10634,6 +10667,8 @@ post_default_ints: mov ax, #0xe000 call rom_scan + call _s3_resume + #if BX_ELTORITO_BOOT call _interactive_bootkey #endif // BX_ELTORITO_BOOT diff --git a/bios/rombios32.c b/bios/rombios32.c index a91b155..3833878 100755 --- a/bios/rombios32.c +++ b/bios/rombios32.c @@ -213,6 +213,20 @@ void *memmove(void *d1, const void *s1, size_t len) return d1; } +int memcmp(const void *s1, const void *s2, size_t len) +{ + const int8_t *p1 = s1; + const int8_t *p2 = s2; + + while (len--) { + int r = *p1++ - *p2++; + if(r) + return r; + } + + return 0; +} + size_t strlen(const char *s) { const char *s1; @@ -568,7 +582,6 @@ void ram_probe(void) ebda_cur_addr = ((*(uint16_t *)(0x40e)) << 4) + 0x380; BX_INFO("ebda_cur_addr: 0x%08lx\n", ebda_cur_addr); #endif - setup_mtrr(); } /****************************************************/ @@ -756,7 +769,7 @@ static void bios_shadow_init(PCIDevice *d) { int v; - if (find_bios_table_area() < 0) + if (bios_table_cur_addr == 0) return; /* remap the BIOS to shadow RAM an keep it read/write while we @@ -1528,7 +1541,7 @@ void acpi_bios_init(void) memset(facs, 0, sizeof(*facs)); memcpy(facs->signature, "FACS", 4); facs->length = cpu_to_le32(sizeof(*facs)); - + BX_INFO("Firmware waking vector %p\n", &facs->firmware_waking_vector); /* DSDT */ memcpy(dsdt, AmlCode, sizeof(AmlCode)); @@ -2099,9 +2112,40 @@ void smbios_init(void) BX_INFO("SMBIOS table addr=0x%08lx\n", (unsigned long)start); } -void rombios32_init(void) +static uint32_t find_resume_vector(void) +{ + unsigned long addr; + + if (bios_table_cur_addr == 0) + return 0; + + for (addr = bios_table_cur_addr; addr < bios_table_end_addr; addr++) { + if (!memcmp((void*)addr, "RSD PTR ", 8)) { + struct rsdp_descriptor *rsdp = (void*)addr; + struct rsdt_descriptor_rev1 *rsdt = (void*)rsdp->rsdt_physical_address; + struct fadt_descriptor_rev1 *fadt = (void*)rsdt->table_offset_entry[0]; + struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; + return facs->firmware_waking_vector; + } + } + + return 0; +} + +static void find_440fx(PCIDevice *d) { - BX_INFO("Starting rombios32\n"); + uint16_t vendor_id, device_id; + + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + + if (vendor_id == 0x8086 && device_id == 0x1237) + i440_pcidev = *d; +} + +void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag) +{ + BX_INFO("Starting rombios32 %p %p %x\n", s3_resume_vector, shutdown_flag, *shutdown_flag); init_smp_msrs(); @@ -2111,10 +2155,30 @@ void rombios32_init(void) ram_probe(); + setup_mtrr(); + cpu_probe(); smp_probe(); + if (find_bios_table_area() < 0) + return; + + if (*shutdown_flag == 0xfe) { + *s3_resume_vector = find_resume_vector(); + if (!*s3_resume_vector) { + BX_INFO("This is S3 resume but wakeup vector is NULL\n"); + } else { + BX_INFO("S3 resume vector %p\n", *s3_resume_vector); + /* redirect bios read access to RAM */ + pci_for_each_device(find_440fx); + bios_lock_shadow_ram(); /* bios is already copied */ + return; + } + } + + uuid_probe(); + pci_bios_init(); if (bios_table_cur_addr != 0) { -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html