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-ia64-devel

[Xen-ia64-devel] [rfc 02/15] physical mode SAL calls

To: xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-ia64-devel] [rfc 02/15] physical mode SAL calls
From: Simon Horman <horms@xxxxxxxxxxxx>
Date: Fri, 17 Aug 2007 15:50:44 +0900
Delivery-date: Fri, 17 Aug 2007 00:41:13 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ia64-devel-request@lists.xensource.com?subject=help>
List-id: Discussion of the ia64 port of Xen <xen-ia64-devel.lists.xensource.com>
List-post: <mailto:xen-ia64-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ia64-devel>, <mailto:xen-ia64-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070817065042.645546902@xxxxxxxxxxxx>
Sender: xen-ia64-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: quilt/0.46-1
Currently the EFI code will fall back to making real mode calls if the call
to map the EFI code fails. Unfortunately this only takes into account EFI
calls, but if EFI calls are made in physical mode SAL calls also need to be
made in physical mode. On a Tiger2 at least, forcing EFI to stay in
physical mode caues the boot to oops in a SAL call.

This patch changes things around by adding code to allow SAL calls to be
made in physical mode. I then makes this the path that is allways followed
- that is SAL calls are always physical with this patch.

This patch fixes things up so that physical SAL calls are made when
physical EFI calls are in operation, and virtual SAL calls when virtual EFI
calls are in poration. 

Curiously on my Tiger2, it seems that having SAL always physical, regadless
of if EFI is physical or virtual, actually works.

Signed-Off-By: Simon Horman <horms@xxxxxxxxxxxx>

Index: xen-ia64-unstable-14854/xen/arch/ia64/linux-xen/Makefile
===================================================================
--- xen-ia64-unstable-14854.orig/xen/arch/ia64/linux-xen/Makefile       
2007-04-17 11:00:28.000000000 +0900
+++ xen-ia64-unstable-14854/xen/arch/ia64/linux-xen/Makefile    2007-04-17 
11:44:03.000000000 +0900
@@ -10,6 +10,7 @@ obj-y += mm_contig.o
 obj-y += pal.o
 obj-y += process-linux-xen.o
 obj-y += sal.o
+obj-y += sal_stub.o
 obj-y += setup.o
 obj-y += smpboot.o
 obj-y += smp.o
Index: xen-ia64-unstable-14854/xen/arch/ia64/linux-xen/efi.c
===================================================================
--- xen-ia64-unstable-14854.orig/xen/arch/ia64/linux-xen/efi.c  2007-04-17 
11:44:03.000000000 +0900
+++ xen-ia64-unstable-14854/xen/arch/ia64/linux-xen/efi.c       2007-04-17 
11:44:13.000000000 +0900
@@ -418,6 +418,9 @@ efi_init (void)
        efi_char16_t *c16;
        u64 efi_desc_size;
        char *cp, vendor[100] = "unknown";
+#ifdef XEN
+       int phys_efi = 0;
+#endif
        int i;
 
        /* it's too early to be able to use the standard kernel command line 
support... */
@@ -434,6 +437,11 @@ efi_init (void)
                        max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
                } else if (memcmp(cp, "min_addr=", 9) == 0) {
                        min_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp));
+#ifdef XEN
+               } else if (memcmp(cp, "phys_efi", 8) == 0) {
+                       phys_efi = 1;
+                       cp+=8;
+#endif
                } else {
                        while (*cp != ' ' && *cp)
                                ++cp;
@@ -527,7 +535,15 @@ efi_init (void)
 #endif
 
        efi_map_pal_code();
+#ifndef XEN
        efi_enter_virtual_mode();
+#else
+       if (phys_efi)
+               printk("Forcing EFI to stay in physical mode\n");
+       else
+               efi_enter_virtual_mode();
+#endif
+
 }
 
 void
@@ -600,6 +616,9 @@ efi_enter_virtual_mode (void)
        efi.set_variable = virt_set_variable;
        efi.get_next_high_mono_count = virt_get_next_high_mono_count;
        efi.reset_system = virt_reset_system;
+#ifdef XEN
+       efi.mapped = 1;
+#endif
 }
 
 /*
Index: xen-ia64-unstable-14854/xen/arch/ia64/linux-xen/sal_stub.S
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ xen-ia64-unstable-14854/xen/arch/ia64/linux-xen/sal_stub.S  2007-04-17 
11:44:17.000000000 +0900
@@ -0,0 +1,100 @@
+/*
+ * SAL call stub.
+ *
+ * Copyright (C) 2006 Simon Horman <horms@xxxxxxxxxxxx>
+ *
+ * Based heavily on arch/ia64/kernel/efi_stub.S
+ *
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ *     David Mosberger <davidm@xxxxxxxxxx>
+ *
+ * This stub allows us to make PAL calls in physical mode with interrupts
+ * turned off. This is needed to make PAL calls if EFI has not been
+ * maped using SetVirtualMap() for one reason or another
+ */
+
+/*
+ * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System
+ * Abstraction Layer Specification", revision 2.6e).  Note that
+ * psr.dfl and psr.dfh MUST be cleared, despite what this manual says.
+ * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call
+ * (the br.ia instruction fails unless psr.dfl and psr.dfh are
+ * cleared).  Fortunately, SAL promises not to touch the floating
+ * point regs, so at least we don't have to save f2-f127.
+ */
+#define PSR_BITS_TO_CLEAR                                              \
+       (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT |         \
+        IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED |        \
+        IA64_PSR_DFL | IA64_PSR_DFH)
+
+#define PSR_BITS_TO_SET                                                        
\
+       (IA64_PSR_BN)
+
+#include <asm/processor.h>
+#include <asm/asmmacro.h>
+
+/*
+ * Inputs:
+ *     in0 = address of function descriptor of SAL routine
+ *     in1..in8 = arguments to routine
+ *
+ * Outputs:
+ *     r8..r11 = return
+ */
+
+GLOBAL_ENTRY(sal_call_phys)
+       .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(9)
+       alloc loc1=ar.pfs,9,8,8,0
+       ld8 r2=[in0],8                  // load SAL function's entry point
+       mov loc0=rp                     // save return pointer
+       .body
+       ;;
+       mov loc2=gp                     // save global pointer
+       mov loc4=ar.rsc                 // save RSE configuration
+       mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
+       ;;
+#ifdef XEN
+       dep r2=0,r2,60,4                // __pa
+#else
+       dep r2=0,r2,61,3                // __pa
+#endif
+       ld8 gp=[in0]                    // load EFI function's global pointer
+       movl r16=PSR_BITS_TO_CLEAR
+       mov loc3=psr
+       movl r17=PSR_BITS_TO_SET
+       ;;
+       or loc3=loc3,r17
+       mov b6=r2
+       ;;
+#ifdef XEN
+       dep gp=0,gp,60,4                // __pa
+#else
+       dep gp=0,gp,61,3                // __pa
+#endif
+       andcm r16=loc3,r16
+       br.call.sptk.many rp=ia64_switch_mode_phys
+.ret0: mov out0=in1
+       mov out1=in2
+       mov out2=in3
+       mov out3=in4
+       mov out4=in5
+       mov out5=in6
+       mov out6=in7
+       mov out7=in8
+       mov loc5=r19
+       mov loc6=r20
+       ;;
+       br.call.sptk.many rp=b6         // call the SAL function
+       ;;
+       mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
+       mov r16=loc3
+       mov r19=loc5
+       mov r20=loc6
+.ret1: br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual         
;;
+.ret2: mov ar.rsc=loc4                 // restore RSE configuration
+       mov ar.pfs = loc1               // restore register stack
+       mov rp=loc0                     // retore return pointer
+       mov gp=loc2                     // retore global pointer
+       br.ret.sptk.many rp
+END(sal_call_phys)
+
Index: xen-ia64-unstable-14854/xen/include/asm-ia64/linux-xen/linux/efi.h
===================================================================
--- xen-ia64-unstable-14854.orig/xen/include/asm-ia64/linux-xen/linux/efi.h     
2007-04-17 11:44:03.000000000 +0900
+++ xen-ia64-unstable-14854/xen/include/asm-ia64/linux-xen/linux/efi.h  
2007-04-17 11:44:03.000000000 +0900
@@ -273,6 +273,7 @@ extern struct efi {
        efi_get_next_high_mono_count_t *get_next_high_mono_count;
        efi_reset_system_t *reset_system;
        efi_set_virtual_address_map_t *set_virtual_address_map;
+       unsigned mapped;
 } efi;
 
 static inline int
Index: xen-ia64-unstable-14854/xen/include/asm-ia64/linux/asm/sal.h
===================================================================
--- xen-ia64-unstable-14854.orig/xen/include/asm-ia64/linux/asm/sal.h   
2007-04-17 11:00:35.000000000 +0900
+++ xen-ia64-unstable-14854/xen/include/asm-ia64/linux/asm/sal.h        
2007-04-17 11:44:17.000000000 +0900
@@ -45,9 +45,34 @@
 
 extern spinlock_t sal_lock;
 
+struct ia64_sal_retval {
+       /*
+        * A zero status value indicates call completed without error.
+        * A negative status value indicates reason of call failure.
+        * A positive status value indicates success but an
+        * informational value should be printed (e.g., "reboot for
+        * change to take effect").
+        */
+       s64 status;
+       u64 v0;
+       u64 v1;
+       u64 v2;
+};
+
+typedef struct ia64_sal_retval (*ia64_sal_handler) (u64, ...);
+
 /* SAL spec _requires_ eight args for each call. */
+struct ia64_sal_retval sal_call_phys(ia64_sal_handler ia64_sal, ...);
+
+#ifdef XEN
+#define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7)                     \
+       result = efi.mapped ?                                           \
+                (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7) :                 \
+                sal_call_phys(ia64_sal,a0,a1,a2,a3,a4,a5,a6,a7);
+#else
 #define __SAL_CALL(result,a0,a1,a2,a3,a4,a5,a6,a7)     \
-       result = (*ia64_sal)(a0,a1,a2,a3,a4,a5,a6,a7)
+       result = (*ia64_sal)(ia64_sal,a0,a1,a2,a3,a4,a5,a6,a7);
+#endif
 
 # define SAL_CALL(result,args...) do {                         \
        unsigned long __ia64_sc_flags;                          \
@@ -95,22 +120,6 @@ extern spinlock_t sal_lock;
 
 #define SAL_UPDATE_PAL                 0x01000020
 
-struct ia64_sal_retval {
-       /*
-        * A zero status value indicates call completed without error.
-        * A negative status value indicates reason of call failure.
-        * A positive status value indicates success but an
-        * informational value should be printed (e.g., "reboot for
-        * change to take effect").
-        */
-       s64 status;
-       u64 v0;
-       u64 v1;
-       u64 v2;
-};
-
-typedef struct ia64_sal_retval (*ia64_sal_handler) (u64, ...);
-
 enum {
        SAL_FREQ_BASE_PLATFORM = 0,
        SAL_FREQ_BASE_INTERVAL_TIMER = 1,

-- 

-- 
Horms
  H: http://www.vergenet.net/~horms/
  W: http://www.valinux.co.jp/en/


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