qemu-devel@nongnu.org
[Top] [All Lists]

[Qemu-devel] Re: [Bochs-developers] [PATCH 2/6] Add S3 state to DSDT. Ha

Subject: [Qemu-devel] Re: [Bochs-developers] [PATCH 2/6] Add S3 state to DSDT. Handle resumeevent in the BIOS.
From: "Sebastian Herbszt"
Date: Thu, 30 Oct 2008 23:41:28 +0100
Gleb Natapov wrote:
diff --git a/bios/rombios.c b/bios/rombios.c
index 88eac04..46996fa 100644
--- a/bios/rombios.c
+++ b/bios/rombios.c
@@ -2198,6 +2198,31 @@ 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 */

Any reason not to use 0040h:0067h instead?

+    BX_INFO("S3 resume jump to %x:%x\n", *(Bit16u*)0x04b8, *(Bit16u*)0x04b6);
+ASM_START
+    jmpf [0x04b6]
+ASM_END
+}
+
#if BX_USE_ATADRV

// ---------------------------------------------------------------------------
@@ -10005,6 +10030,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
@@ -10383,6 +10412,9 @@ normal_post:
  rep
    stosw

+  ;; Save shutdown status
+  mov 0x04b0, bl
+
  call _log_bios_start

  ;; set all interrupts to default handler
@@ -10593,6 +10625,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 f0daf15..ff84f80 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;
@@ -644,7 +658,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
@@ -1461,7 +1475,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));

@@ -2011,9 +2025,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)
{
-    BX_INFO("Starting rombios32\n");
+    unsigned long addr;
+
+    if (bios_table_cur_addr == 0)
+        return 0;

BX_USE_EBDA_TABLES case

+
+    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;
+        }
+    }
+

RSDP is on a 16-byte boundary

+    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 == 0x8086 && device_id == 0x1237)
+        i440_pcidev = *d;

Please use PCI_VENDOR_ID_INTEL and PCI_DEVICE_ID_INTEL_82441.

+}
+
+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);

Maybe make it two lines and explain the values for the log:

BX_INFO("Starting rombios32\n");
BX_INFO("s3_resume_vector=%p ... \n", s3_resume_vector, ...


#ifdef BX_QEMU
    qemu_cfg_port = qemu_cfg_port_probe();
@@ -2025,6 +2070,24 @@ void rombios32_init(void)

    smp_probe();

+    if (find_bios_table_area() < 0)
+        return;

It should not return if BX_USE_EBDA_TABLES is defined.
Is there a need to return at all?

+
+    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 */

bios_shadow_init() is called in pci_bios_init(). Why do we need to lock it here?

+            return;
+        }
+    }
+
+    uuid_probe();
+
    pci_bios_init();

    if (bios_table_cur_addr != 0) {


rombios32.c r1.32 got:

   smp_probe();

   pci_bios_init();

   if (bios_table_cur_addr != 0) {

       mptable_init();

       uuid_probe();

The patch should remove uuid_probe() from the if-case.

- Sebastian



<Prev in Thread] Current Thread [Next in Thread>