qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [Bochs-developers] [PATCH v4 2/5] Preserve memory conte


From: Gleb Natapov
Subject: [Qemu-devel] Re: [Bochs-developers] [PATCH v4 2/5] Preserve memory content duringSMM init.
Date: Tue, 18 Nov 2008 10:27:46 +0200

On Tue, Nov 18, 2008 at 09:46:28AM +0200, Gleb Natapov wrote:
> > SMBASE is not relocated. If i don't mistake smm_init() should be run on S3
> > resume and we would need something like
> >
> > pci_for_each_device(find_piix4pm)
> > if (piix4pm_pcidev)
> >    smm_init();
> >
> > in the resume path in rombios32.c.
> >
> Yes, you are right. I'll add it.
> 
What about this? (fixed version of 1/5 patch)


diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index 19ac2f9..280a05e 100644
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -531,11 +531,29 @@ DefinitionBlock (
         }
     }
 
-    /* S5 = power off state */
-    Name (_S5, Package (4) {
-        0x00, // PM1a_CNT.SLP_TYP
-        0x00, // PM2a_CNT.SLP_TYP
-        0x00, // reserved
-        0x00, // reserved
+    /*
+     * S3 (suspend-to-ram), S4 (suspend-to-disk) 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 */
     })
 }
diff --git a/bios/acpi-dsdt.hex b/bios/acpi-dsdt.hex
index 6bc6268..6088b18 100644
--- a/bios/acpi-dsdt.hex
+++ b/bios/acpi-dsdt.hex
@@ -1,22 +1,22 @@
 /*
  * 
  * Intel ACPI Component Architecture
- * ASL Optimizing Compiler version 20060912 [Nov 25 2006]
+ * ASL Optimizing Compiler version 20061109 [May 15 2007]
  * Copyright (C) 2000 - 2006 Intel Corporation
  * Supports ACPI Specification Revision 3.0a
  * 
- * Compilation of "acpi-dsdt.dsl" - Sun Sep 14 10:27:40 2008
+ * Compilation of "acpi-dsdt.dsl" - Mon Oct 27 10:37:05 2008
  * 
  * C source code output
  *
  */
-unsigned char AmlCode[] =
+const unsigned char AmlCode[] =
 {
-    0x44,0x53,0x44,0x54,0xC9,0x07,0x00,0x00,  /* 00000000    "DSDT...." */
-    0x01,0x0E,0x42,0x58,0x50,0x43,0x00,0x00,  /* 00000008    "..BXPC.." */
+    0x44,0x53,0x44,0x54,0xE1,0x07,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x01,0x24,0x42,0x58,0x50,0x43,0x00,0x00,  /* 00000008    ".$BXPC.." */
     0x42,0x58,0x44,0x53,0x44,0x54,0x00,0x00,  /* 00000010    "BXDSDT.." */
     0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
-    0x12,0x09,0x06,0x20,0x10,0x1C,0x5C,0x00,  /* 00000020    "... ..\." */
+    0x09,0x11,0x06,0x20,0x10,0x1C,0x5C,0x00,  /* 00000020    "... ..\." */
     0x5B,0x80,0x44,0x42,0x47,0x5F,0x01,0x0B,  /* 00000028    "[.DBG_.." */
     0x44,0xB0,0x0A,0x04,0x5B,0x81,0x0B,0x44,  /* 00000030    "D...[..D" */
     0x42,0x47,0x5F,0x03,0x44,0x42,0x47,0x4C,  /* 00000038    "BG_.DBGL" */
@@ -260,6 +260,9 @@ unsigned char AmlCode[] =
     0x8B,0x68,0x01,0x54,0x4D,0x50,0x5F,0x82,  /* 000007A8    ".h.TMP_." */
     0x54,0x4D,0x50,0x5F,0x60,0x76,0x60,0x70,  /* 000007B0    "TMP_`v`p" */
     0x60,0x50,0x52,0x51,0x33,0x08,0x5F,0x53,  /* 000007B8    "`PRQ3._S" */
-    0x35,0x5F,0x12,0x06,0x04,0x00,0x00,0x00,  /* 000007C0    "5_......" */
+    0x33,0x5F,0x12,0x06,0x04,0x01,0x01,0x00,  /* 000007C0    "3_......" */
+    0x00,0x08,0x5F,0x53,0x34,0x5F,0x12,0x06,  /* 000007C8    ".._S4_.." */
+    0x04,0x00,0x00,0x00,0x00,0x08,0x5F,0x53,  /* 000007D0    "......_S" */
+    0x35,0x5F,0x12,0x06,0x04,0x00,0x00,0x00,  /* 000007D8    "5_......" */
     0x00,
 };
diff --git a/bios/rombios.c b/bios/rombios.c
index 9255b89..a34c6b2 100644
--- a/bios/rombios.c
+++ b/bios/rombios.c
@@ -1917,6 +1917,11 @@ shutdown_status_panic(status)
   BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status);
 }
 
+void s3_resume_panic()
+{
+  BX_PANIC("Returned from s3_resume.\n");
+}
+
 //--------------------------------------------------------------------------
 // print_bios_banner
 //   displays a the bios version
@@ -2198,6 +2203,33 @@ debugger_off()
   outb(0xfedc, 0x00);
 }
 
+int
+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 0;
+
+    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", (s3_wakeup_vector >> 4),
+                   (s3_wakeup_vector & 0xF));
+ASM_START
+    jmpf [0x04b6]
+ASM_END
+    return 1;
+}
+
 #if BX_USE_ATADRV
 
 // ---------------------------------------------------------------------------
@@ -9081,6 +9113,15 @@ retf_post_0x467:
   mov ss, [0x469]
   retf
 
+s3_post:
+#if BX_ROMBIOS32
+  call rombios32_init
+#endif
+  call _s3_resume
+  mov bl, #0x00
+  and ax, ax
+  jz normal_post
+  call _s3_resume_panic
 
 ;--------------------
 eoi_both_pics:
@@ -10005,6 +10046,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
@@ -10375,6 +10420,12 @@ normal_post:
   mov  ds, ax
   mov  ss, ax
 
+  ;; Save shutdown status
+  mov 0x04b0, bl
+
+  cmp bl, #0xfe
+  jz s3_post
+
   ;; zero out BIOS data area (40:00..40:ff)
   mov  es, ax
   mov  cx, #0x0080 ;; 128 words
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 38cfe06..dfb7c88 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -180,6 +180,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;
@@ -625,7 +639,7 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int 
irq_num)
     return (irq_num + slot_addend) & 3;
 }
 
-static int find_bios_table_area(void)
+static void find_bios_table_area(void)
 {
     unsigned long addr;
     for(addr = 0xf0000; addr < 0x100000; addr += 16) {
@@ -634,17 +648,17 @@ static int find_bios_table_area(void)
             bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 
4);
             BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
                     bios_table_cur_addr, bios_table_end_addr);
-            return 0;
+            return;
         }
     }
-    return -1;
+    return;
 }
 
 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
@@ -747,6 +761,18 @@ static void smm_init(PCIDevice *d)
 }
 #endif
 
+static void piix4_pm_enable(PCIDevice *d)
+{
+        /* PIIX4 Power Management device (for ACPI) */
+        pci_config_writel(d, 0x40, PM_IO_BASE | 1);
+        pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
+        pci_config_writel(d, 0x90, SMB_IO_BASE | 1);
+        pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
+#ifdef BX_USE_SMM
+        smm_init(d);
+#endif
+}
+
 static void pci_bios_init_device(PCIDevice *d)
 {
     int class;
@@ -837,15 +863,9 @@ static void pci_bios_init_device(PCIDevice *d)
     if (vendor_id == PCI_VENDOR_ID_INTEL && device_id == 
PCI_DEVICE_ID_INTEL_82371AB_3) {
         /* PIIX4 Power Management device (for ACPI) */
         pm_io_base = PM_IO_BASE;
-        pci_config_writel(d, 0x40, pm_io_base | 1);
-        pci_config_writeb(d, 0x80, 0x01); /* enable PM io space */
         smb_io_base = SMB_IO_BASE;
-        pci_config_writel(d, 0x90, smb_io_base | 1);
-        pci_config_writeb(d, 0xd2, 0x09); /* enable SMBus io space */
         pm_sci_int = pci_config_readb(d, PCI_INTERRUPT_LINE);
-#ifdef BX_USE_SMM
-        smm_init(d);
-#endif
+        piix4_pm_enable(d);
         acpi_enabled = 1;
     }
 }
@@ -1460,6 +1480,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));
@@ -2010,9 +2031,59 @@ 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, start, end;
+
+#ifdef BX_USE_EBDA_TABLES
+    start = align(ebda_cur_addr, 16);
+    end = 0xa000 << 4;
+#else
+    if (bios_table_cur_addr == 0)
+        return 0;
+    start = align(bios_table_cur_addr, 16);
+    end = bios_table_end_addr;
+#endif
+
+    for (addr = start; addr < end; addr += 16) {
+        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)
+{
+    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 == PCI_VENDOR_ID_INTEL && device_id == 
PCI_DEVICE_ID_INTEL_82441)
+        i440_pcidev = *d;
+}
+
+static void reinit_piix4_pm(PCIDevice *d)
+{
+    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 == PCI_VENDOR_ID_INTEL && device_id == 
PCI_DEVICE_ID_INTEL_82371AB_3)
+        piix4_pm_enable(d);
+}
+
+void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
 {
     BX_INFO("Starting rombios32\n");
+    BX_INFO("Shutdown flag %x\n", *shutdown_flag);
 
 #ifdef BX_QEMU
     qemu_cfg_port = qemu_cfg_port_probe();
@@ -2024,6 +2095,22 @@ void rombios32_init(void)
 
     smp_probe();
 
+    find_bios_table_area();
+
+    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 */
+            pci_for_each_device(reinit_piix4_pm);
+        }
+        return;
+    }
+
     pci_bios_init();
 
     if (bios_table_cur_addr != 0) {
--
                        Gleb.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]