WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] rombios: Simplify 32-bit gateway and avoi

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] rombios: Simplify 32-bit gateway and avoid need for EBDA space.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 22 Jan 2009 13:05:20 -0800
Delivery-date: Thu, 22 Jan 2009 13:05:27 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1232641926 0
# Node ID b10fd9f4fe38c38069b140bf8689c5fc15cd595f
# Parent  d52921c18c3d0171bccb4651cca8412f2fff2dd9
rombios: Simplify 32-bit gateway and avoid need for EBDA space.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/rombios/32bitgateway.h |   18 -
 tools/firmware/rombios/32bitgateway.c |  458 ++++++++--------------------------
 tools/firmware/rombios/rombios.c      |    4 
 3 files changed, 120 insertions(+), 360 deletions(-)

diff -r d52921c18c3d -r b10fd9f4fe38 tools/firmware/rombios/32bitgateway.c
--- a/tools/firmware/rombios/32bitgateway.c     Thu Jan 22 11:21:43 2009 +0000
+++ b/tools/firmware/rombios/32bitgateway.c     Thu Jan 22 16:32:06 2009 +0000
@@ -19,8 +19,10 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
  * Copyright (C) IBM Corporation, 2006
+ * Copyright (c) 2008, Citrix Systems, Inc.
  *
  * Author: Stefan Berger <stefanb@xxxxxxxxxx>
+ * Author: Keir Fraser <keir.fraser@xxxxxxxxxx>
  */
 
 /*
@@ -34,384 +36,162 @@
  *  (4 bytes) even for uint16_t, so casting to 32bit from bcc is a good idea.
  */
 
-#define SEGMENT_OFFSET  0xf0000
-#define REAL_MODE_CODE_SEGMENT  0xf000
+/* At most 32 bytes in argument list to a 32-bit function. */
+#define MAX_ARG_BYTES 32
 
-#define START_PM_CODE  USE32
-#define END_PM_CODE    USE16
+#define REAL_MODE_CODE_OFFSET  0xf0000
 
-/* definition of used code/data segment descriptors */
-#define PM_NORMAL_CS (gdt_entry_pm_cs       - gdt_base)
+/* Definitions of code/data segment descriptors. */
+#define PM_32BIT_CS  (gdt_entry_pm_32bit_cs - gdt_base)
 #define PM_16BIT_CS  (gdt_entry_pm_16bit_cs - gdt_base)
 #define PM_32BIT_DS  (gdt_entry_pm_32bit_ds - gdt_base)
+#define PM_16BIT_DS  (gdt_entry_pm_16bit_ds - gdt_base)
 
-  ASM_START
+ASM_START
 
-    ; Switch into protected mode to allow access to 32 bit addresses.
-    ; This function allows switching into protected mode.
-    ; (the specs says big real mode, but that will not work)
+    .align 16
+gdt_base:
+    .word 0,0
+    .byte 0,0,0,0
+gdt_entry_pm_32bit_cs:
+    .word 0xffff, 0x0000
+    .byte 0x00, 0x9b, 0xcf, 0x00
+gdt_entry_pm_16bit_cs:
+    .word 0xffff, 0x0000
+    .byte REAL_MODE_CODE_OFFSET >> 16, 0x9b, 0x0, 0x0
+gdt_entry_pm_32bit_ds:
+    .word 0xffff, 0x0000
+    .byte 0x0, 0x93, 0xcf, 0x0
+gdt_entry_pm_16bit_ds:
+    .word 0xffff, 0x0000
+    .byte 0x0, 0x93, 0x0, 0x0
+gdt_entry_end:
+
+protmode_gdtdesc:
+    .word (gdt_entry_end - gdt_base) - 1
+    .long gdt_base | REAL_MODE_CODE_OFFSET
+
+realmode_gdtdesc:
+    .word 0xffff
+    .long 0x0
+
+Upcall:
+    ; Do an upcall into 32 bit space
     ;
-    ; preserves all registers and prepares cs, ds, es, ss for usage
-    ; in protected mode; while in prot.mode interrupts remain disabled
-switch_to_protmode:
+    ; Input:
+    ; bx: index of function to call
+    ; Ouput:
+    ; dx, ax: 32 bit result of call (even if 'void' is expected)
+
+    ; Save caller state, stack frame offsets listed below
+#define esp_off     0
+#define ss_off      4
+#define es_off      6
+#define ds_off      8
+#define flags_off   10
+#define retaddr_off 12
+#define args_off    14
+    pushf
     cli
+    push ds
+    push es
+    push ss
+    push esp
 
-    ; have to fix the stack for proper return address in 32 bit mode
-    push WORD #(REAL_MODE_CODE_SEGMENT>>12)    ;extended return address
-    push bp                                    ;pop@A1
-    mov bp, sp
-    push eax                                   ;pop@A2
-    mov eax, 2[bp]                             ; fix return address
-    rol eax, #16
-    mov 2[bp], eax
+    ; Find the 32-bit function address via a table lookup
+    push si
+    rol bx, #2
+    mov si, #jmptable
+    seg cs
+    mov eax, dword ptr [si+bx]
+    pop si
+    push eax
 
-    mov eax, esp
-    ror eax, #16                               ; hi(esp)
-
-    push bx                                    ; preserve before function call
-    push cx
-    push dx
-
-    push ax                                    ; prepare stack for
-    push es                                    ; call
-    push ds
-    push cs
-    push ss
-    call _store_segment_registers
-    add sp, #10                                        ; pop ax,es-ss
-
-    pop dx                                     ; restore after function call
-    pop cx
-    pop bx
-
-    ; calculate protected-mode esp from ss:sp
+    ; Calculate protected-mode esp from ss:sp
     and esp, #0xffff
     xor eax, eax
     mov ax, ss
-    rol eax, #4
-    add eax, esp
-    mov esp, eax
+    shl eax, #4
+    add esp, eax
 
+    ; Switch to protected mode
     seg cs
-    lgdt my_gdtdesc                            ; switch to own table
-
+    lgdt protmode_gdtdesc
     mov eax, cr0
-    or al, #0x1                                ; protected mode 'on'
+    or al, #0x1  ; protected mode on
     mov cr0, eax
-
-    jmpf DWORD (SEGMENT_OFFSET | switch_to_protmode_goon_1), #PM_NORMAL_CS
-
-    START_PM_CODE
-
-switch_to_protmode_goon_1:
-    mov ax, #PM_32BIT_DS                       ; 32 bit segment that allows
-    mov ds, ax                                 ; to reach all 32 bit
-    mov es, ax                                 ; addresses
+    jmpf DWORD (REAL_MODE_CODE_OFFSET|upcall1), #PM_32BIT_CS
+upcall1:
+    USE32
+    mov ax, #PM_32BIT_DS
+    mov ds, ax
+    mov es, ax
     mov ss, ax
 
-    pop eax                                    ;@A2
-    pop bp                                     ;@A1
-    ret
+    ; Marshal arguments and call 32-bit function
+    pop eax
+    mov ecx, #MAX_ARG_BYTES/4
+upcall2:
+    push MAX_ARG_BYTES-4+args_off[esp]
+    loop upcall2
+    call eax
+    add esp, #MAX_ARG_BYTES
+    mov ecx, eax  ; Result in ecx
 
-    END_PM_CODE
+    ; Restore real-mode stack pointer
+    xor eax, eax
+    mov ax, ss_off[esp]
+    shl eax, 4
+    sub esp, eax
+    mov bx, ax    ; Real-mode ss in bx
 
-
-
-    .align 16
-gdt_base:
-    ; see Intel SW Dev. Manuals section 3.4.5, Volume 3 for meaning of bits
-    .word 0,0
-    .byte 0,0,0,0
-
-gdt_entry_pm_cs:
-    ; 32 bit code segment for protected mode
-    .word 0xffff, 0x0000
-    .byte 0x00, 0x9b, 0xcf, 0x00
-
-gdt_entry_pm_16bit_cs:
-    ; temp. 16 bit code segment used while in protected mode
-    .word 0xffff, 0x0000
-    .byte SEGMENT_OFFSET >> 16, 0x9b, 0x0, 0x0
-
-gdt_entry_pm_32bit_ds:
-    ; (32 bit) data segment (r/w) reaching all possible areas in 32bit memory
-    ; 4kb granularity
-    .word 0xffff, 0x0000
-    .byte 0x0, 0x93, 0xcf, 0x0
-gdt_entry_end:
-
-my_gdtdesc:
-    .word (gdt_entry_end - gdt_base) - 1
-    .long gdt_base | SEGMENT_OFFSET
-
-
-realmode_gdtdesc:                              ;to be used in real mode
-    .word 0xffff
-    .long 0x0
-
-
-
-switch_to_realmode:
-    ; Implementation of switching from protected mode to real mode
-    ; prepares cs, es, ds, ss to be used in real mode
-    ; spills   eax
-    START_PM_CODE
-
-    ; need to fix up the stack to return in 16 bit mode
-    ; currently the 32 bit return address is on the stack
-    pop eax
-    push ax
-
-    push bx                                    ;pop@1
-    push si                                    ;pop@2
-
-    call _ebda_ss_offset32                     ; get the offset of the ss
-    mov bx, ax                                 ; entry within the ebda.
-
-    jmpf switch_to_realmode_goon_1, #PM_16BIT_CS
-
-    END_PM_CODE
-
-switch_to_realmode_goon_1:
+    ; Return to real mode
+    jmpf upcall3, #PM_16BIT_CS
+upcall3:
+    USE16
+    mov ax, #PM_16BIT_DS
+    mov ds, ax
+    mov es, ax
+    mov ss, ax
     mov eax, cr0
-    and al, #0xfe                              ; protected mode 'off'
+    and al, #0xfe ; protected mode off
     mov cr0, eax
-
-    jmpf switch_to_realmode_goon_2, #REAL_MODE_CODE_SEGMENT
-
-switch_to_realmode_goon_2:
-
-    ; get orig. 'ss' without using the stack (no 'call'!)
-    xor eax, eax                       ; clear upper 16 bits (and lower)
-    mov ax, #0x40                      ; where is the ebda located?
-    mov ds, ax
-    mov si, #0xe
-    seg ds
-    mov ax, [si]                       ; ax = segment of ebda
-
-    mov ds, ax                         ; segment of ebda
-    seg ds
-    mov ax, [bx]                       ; stack segment - bx has been set above
-    mov ss, ax
-
-    ; from esp and ss calculate real-mode sp
-    rol eax, #4
-    sub esp, eax
-
-    push dx                            ;preserve before call(s)
-    push cx
-    push bx
-
-    call _get_register_ds              ; get orig. 'ds'
-    mov ds, ax
-    call _get_register_es              ; get orig. 'es'
-    mov es, ax
-    call _get_register_esp_hi          ; fix the upper 16 bits of esp
-    ror esp, #16
-    mov sp, ax
-    rol esp, #16
-
-    pop bx
-    pop cx
-    pop dx
-
+    jmpf upcall4, #REAL_MODE_CODE_OFFSET>>4
+upcall4:
     seg cs
     lgdt realmode_gdtdesc
 
-    sti                                                ; allow interrupts
+    ; Restore real-mode ss
+    mov ss, bx
 
-    pop si                                     ;@2
-    pop bx                                     ;@1
+    ; Convert result into dx:ax format
+    mov eax, ecx
+    ror eax, #16
+    mov dx, ax
+    ror eax, #16
 
+    ; Restore caller state and return
+    pop esp
+    pop bx ; skip ss
+    pop es
+    pop ds
+    popf
     ret
-
-    ASM_END
-
-/*
- * Helper function to get the offset of the reg_ss within the ebda struct
- * Only 'C' can tell the offset.
- */
-Bit16u
-ebda_ss_offset32()
-{
-    ASM_START
-    START_PM_CODE                              // need to have this
-    ASM_END                                    // compiled for protected mode
-    return &EbdaData->upcall.reg_ss;           // 'C' knows the offset!
-    ASM_START
-    END_PM_CODE
-    ASM_END
-}
-
-/*
- * Two often-used functions
- */
-Bit16u
-read_word_from_ebda(offset)
-    Bit16u offset;
-{
-       Bit16u ebda_seg = read_word(0x0040, 0x000E);
-       return read_word(ebda_seg, offset);
-}
-
-Bit32u
-read_dword_from_ebda(offset)
-    Bit16u offset;
-{
-       Bit16u ebda_seg = read_word(0x0040, 0x000E);
-       return read_dword(ebda_seg, offset);
-}
-
-/*
- * Store registers in the EBDA; used to keep the registers'
- * content in a well-defined place during protected mode execution
- */
-  void
-store_segment_registers(ss, cs, ds, es, esp_hi)
-  Bit16u ss, cs, ds, es, esp_hi;
-{
-       Bit16u ebda_seg = read_word(0x0040, 0x000E);
-       write_word(ebda_seg, &EbdaData->upcall.reg_ss, ss);
-       write_word(ebda_seg, &EbdaData->upcall.reg_cs, cs);
-       write_word(ebda_seg, &EbdaData->upcall.reg_ds, ds);
-       write_word(ebda_seg, &EbdaData->upcall.reg_es, es);
-       write_word(ebda_seg, &EbdaData->upcall.esp_hi, esp_hi);
-}
-
-
-  void
-store_returnaddress(retaddr)
-   Bit16u retaddr;
-{
-       Bit16u ebda_seg = read_word(0x0040, 0x000E);
-       write_word(ebda_seg, &EbdaData->upcall.retaddr, retaddr);
-}
-
-Bit16u
-get_returnaddress()
-{
-       return read_word_from_ebda(&EbdaData->upcall.retaddr);
-}
-
-/*
- * get the segment register 'cs' value from the EBDA
- */
-Bit16u
-get_register_cs()
-{
-       return read_word_from_ebda(&EbdaData->upcall.reg_cs);
-}
-
-/*
- * get the segment register 'ds' value from the EBDA
- */
-Bit16u
-get_register_ds()
-{
-       return read_word_from_ebda(&EbdaData->upcall.reg_ds);
-}
-
-/*
- * get the segment register 'es' value from the EBDA
- */
-Bit16u
-get_register_es()
-{
-       return read_word_from_ebda(&EbdaData->upcall.reg_es);
-}
-
-/*
- * get the upper 16 bits of the esp from the EBDA
- */
-Bit16u
-get_register_esp_hi()
-{
-       return read_word_from_ebda(&EbdaData->upcall.esp_hi);
-}
-
-
-
-/********************************************************/
-
-
-ASM_START
-
-Upcall:
-       ; do the upcall into 32 bit space
-       ; clear the stack frame so that 32 bit space sees all the parameters
-       ; on the stack as if they were prepared for it
-       ; ---> take the 16 bit return address off the stack and remember it
-       ;
-       ; Input:
-       ; bx: index of function to call
-       ; Ouput:
-       ; dx, ax: 32 bit result of call (even if 'void' is expected)
-
-       push bp                         ;pop @1
-       mov bp, sp
-       push si                         ;pop @2
-
-       mov ax, 2[bp]                   ; 16 bit return address
-       push ax
-       call _store_returnaddress       ; store away
-       pop ax
-
-       rol bx, #2
-       mov si, #jmptable
-       seg cs
-       mov eax, dword ptr [si+bx]      ; address to call from table
-
-       pop si                          ;@2
-       pop bp                          ;@1
-
-       add sp, #2                      ; remove 16bit return address from stack
-
-       call switch_to_protmode
-       START_PM_CODE
-
-       call eax                        ; call 32bit function
-       push eax                        ; preserve result
-
-       call switch_to_realmode         ; back to realmode
-       END_PM_CODE
-
-       pop eax                         ; get result
-
-       push word 0x0000                ; placeholder for 16 bit return address
-       push bp
-       mov bp,sp
-       push eax                        ; preserve work register
-
-       call _get_returnaddress
-       mov 2[bp], ax                   ; 16bit return address onto stack
-
-       pop eax
-       pop bp
-
-       ror eax, #16                    ; result into dx/ax
-       mov dx, ax                      ; hi(res) -> dx
-       ror eax, #16
-
-       ret
-
 
 /* macro for functions to declare their call into 32bit space */
 MACRO DoUpcall
-       mov bx, #?1
-       jmp Upcall
+    mov bx, #?1
+    jmp Upcall
 MEND
-
 
 ASM_END
 
 #include "32bitprotos.h"
-#include "32bitgateway.h"
-
 #include "tcgbios.c"
 
 Bit32u get_s3_waking_vector()
 {
-       ASM_START
-       DoUpcall(IDX_GET_S3_WAKING_VECTOR)
-       ASM_END
+    ASM_START
+    DoUpcall(IDX_GET_S3_WAKING_VECTOR)
+    ASM_END
 }
diff -r d52921c18c3d -r b10fd9f4fe38 tools/firmware/rombios/32bitgateway.h
--- a/tools/firmware/rombios/32bitgateway.h     Thu Jan 22 11:21:43 2009 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#ifndef GATEWAY
-#define GATEWAY
-
-#include "32bitprotos.h"
-
-void test_gateway();
-
-/* extension for the EBDA */
-typedef struct {
-  Bit16u reg_ss;
-  Bit16u reg_cs;
-  Bit16u reg_ds;
-  Bit16u reg_es;
-  Bit16u esp_hi;
-  Bit16u retaddr;
-} upcall_t;
-
-#endif
diff -r d52921c18c3d -r b10fd9f4fe38 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Thu Jan 22 11:21:43 2009 +0000
+++ b/tools/firmware/rombios/rombios.c  Thu Jan 22 16:32:06 2009 +0000
@@ -726,7 +726,7 @@ typedef struct {
     } cdemu_t;
 #endif // BX_ELTORITO_BOOT
 
-#include "32bitgateway.h"
+#include "32bitprotos.h"
 
   // for access to EBDA area
   //     The EBDA structure should conform to
@@ -752,8 +752,6 @@ typedef struct {
     // El Torito Emulation data
     cdemu_t cdemu;
 #endif // BX_ELTORITO_BOOT
-
-    upcall_t upcall;
     } ebda_data_t;
 
   #define EBDA_CMOS_SHUTDOWN_STATUS_OFFSET 1

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] rombios: Simplify 32-bit gateway and avoid need for EBDA space., Xen patchbot-unstable <=