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

[Xen-devel] [PATCH 3/4] rombios interface for HVM S3


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Juergen Keil <jk@xxxxxxxx>
  • Date: Mon, 2 Jun 2008 15:45:38 +0200 (CEST)
  • Delivery-date: Mon, 02 Jun 2008 06:46:48 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

"Ke, Liping" wrote:

> This patch has no change.
>
> [PATCH 3/4] rombios interface for HVM S3
>  - add S3 package in ACPI DSDT table. Guest OS will get S3 value from
> this package and write the value to PM1A control register to trigger S3
> suspend.
>  - Add S3 resume logic in rombios post code. the CMOS shutdown register
>   is used to indicate if this is a S3 resume.
> - if it is s3 resume, rombios will get wakeup vector from ACPI FACS
>   table and jump to wakeup vector.

Has anyone tested this with an AMD cpu?  I suspect that the code was
tested with Intel CPUs; and reading old mailing list messages, it seems
to  be able to s3resume both linux and windows hvm guests on intel vtd.

With an amd64 x2 cpu (using an opensolaris dom0), the hvm bios seems
to hang in rombios.c when I use "xm trigger domain s3resume", here:

    /* get x_firmware_waking_vector */
    s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+24));


Matching the CS:IP (f000:1692) listed in the xen console's register
dump with the xen.hg/tools/firmware/rombios/rombios.txt file,
we're at this instruction:

06098                                           ! 1816
06099                                           ! 1817
06100                                           ! 1818     s3_wakeup_vector = 
*((Bit16u*)(0xEA000 
+0x10 +24));
06101                                           ! Debug: eq unsigned short = 
[+$EA028] to 
unsigned short s3_wakeup_vector = [S+4-4] (used reg = )
06102 1692   67      A1     000EA028            mov     ax,[$EA028]


Any address >= 0x10000 (e.g. 0x000EA028) hangs in the bios
on my box.  0xfffe works ok  -  that doesn't use the
67 prefix byte and uses a 16 bit address.



>   Per ACPI spec, the wakeup vector
>   jumping must be the forms CS:IP, in which CS=(wakeup vector>>4)
>   IP=(wakeup vector)&0xF, for example, for vector=0x12345,
>   CS:IP=0x1234:0x5


Hmm, the current code in s3_resume() reads a 16-bit value from
the FACS wakeup vector fields (see rombios.c, lines 2317 / 2342).
A vector like 0x12345 wouldn't work at this time, because it
gets truncated to 0x2345!

I'd say we need to load at least a 20-bit value from
ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+12 (and the
x_firmware_waking_vector is supposed to be a 64-bit
physical address, so that proably needs more changes).

  2314  void
  2315  s3_resume()
  2316  {
  2317      Bit16u s3_wakeup_vector;
  ...
  2338      /* get x_firmware_waking_vector */
  2339      s3_wakeup_vector = 
*((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+24));
  2340      if (s3_wakeup_vector == 0){
  2341          /* get firmware_waking_vector */
  2342          s3_wakeup_vector = 
*((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+12));
  2343          if (s3_wakeup_vector == 0){
  2344              goto s3_out;
  2345          }
  2346      }
  2347  
  2348      /* setup wakeup vector */
  2349      s3_wakeup_ip = s3_wakeup_vector & 0xF;
  2350      s3_wakeup_cs = s3_wakeup_vector >> 4;



Another thing that looks strange is that s3_wakeup_ip / s3_wakeup_cs
must be copied from segment #0000 to #f000 (lines 2353-2359).
I'd say the s3_resume code could corrupt some random 4-bytes
in the lower 64 kbyte segment:


(DS = #0x0000 at this point ->)
  
  2348      /* setup wakeup vector */
  2349      s3_wakeup_ip = s3_wakeup_vector & 0xF;
  2350      s3_wakeup_cs = s3_wakeup_vector >> 4;
  2351
  2352  ASM_START
  2353      mov bx, [_s3_wakeup_cs]
  2354      mov dx, [_s3_wakeup_ip]
  2355
  2356      mov ax, #0xF000
  2357      mov ds, ax
  2358      mov [_s3_wakeup_cs], bx
  2359      mov [_s3_wakeup_ip], dx
  2360      jmpf [_s3_wakeup_ip]



For now I'm using the attached patch.  It doesn't
hang any more in the bios on s3resume, and the
standard firmware_waking_vector can point anywere
in memory below 1MB.  And it doesn't write
to 0000:_s3_wakeup_{cs,ip} any more.
For unknown reasons, HVM S3 resume hangs in the bios when trying to load
the x_firmware_waking_vector from absolute address 0xEA01C (it hangs for
access to address 0x10000, but doesn't hang for 0xfffe).

diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c
+++ b/tools/firmware/rombios/rombios.c
@@ -2311,10 +2311,31 @@
 #define ACPI_FACS_OFFSET 0x10
 /* S3 resume status in CMOS 0Fh shutdown status byte*/
 
+Bit32u facs_get32(offs)
+Bit16u offs;
+{
+ASM_START
+  push bp
+  mov  bp, sp
+
+    push ds
+    mov ax, #(ACPI_FACS_ADDRESS >> 4)
+    mov ds, ax
+
+    mov bx, 4[bp]
+    mov ax, [bx]
+    mov dx, 2[bx]
+    pop ds
+
+  pop  bp
+ASM_END
+}
+
+
 void 
 s3_resume()
 {
-    Bit16u s3_wakeup_vector;
+    Bit32u s3_wakeup_vector;
     extern Bit16u s3_wakeup_ip;
     extern Bit16u s3_wakeup_cs;
     extern Bit8u s3_resume_flag;
@@ -2330,19 +2351,14 @@
     }
     s3_resume_flag = 0;
 
-ASM_START
-    mov ax, #0x0
-    mov ds, ax
-ASM_END
-
     /* get x_firmware_waking_vector */
-    s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+24));
-    if (s3_wakeup_vector == 0){
+    s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+24);
+    if (!s3_wakeup_vector) {
         /* get firmware_waking_vector */
-        s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+12));
-        if (s3_wakeup_vector == 0){
+       s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+12);
+       if (!s3_wakeup_vector) {
             goto s3_out;
-        }
+       }
     }
 
     /* setup wakeup vector */
@@ -2350,13 +2366,6 @@
     s3_wakeup_cs = s3_wakeup_vector >> 4;
 
 ASM_START
-    mov bx, [_s3_wakeup_cs]
-    mov dx, [_s3_wakeup_ip]
-
-    mov ax, #0xF000
-    mov ds, ax
-    mov [_s3_wakeup_cs], bx
-    mov [_s3_wakeup_ip], dx
     jmpf [_s3_wakeup_ip]
 
 ; S3 data
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.