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

Reply via email to