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] Stack pal call emulation implemented. (by Tristan Gingol

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Stack pal call emulation implemented. (by Tristan Gingold)
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 03 Dec 2005 12:04:25 +0000
Delivery-date: Sat, 03 Dec 2005 12:07:06 +0000
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 djm@xxxxxxxxxxxxxxx
# Node ID eae5812f33f140ef14012776af502534b3655de3
# Parent  97de0e776d8b69d1c1e6db781eabacf03a5c504f
Stack pal call emulation implemented. (by Tristan Gingold)
PAL_HALT emulation added: stop machine if dom0, shutdown domain otherwise.

diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/linux-xen/unaligned.c
--- a/xen/arch/ia64/linux-xen/unaligned.c       Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/linux-xen/unaligned.c       Fri Dec  2 18:12:11 2005
@@ -378,7 +378,7 @@
     if (ridx >= sof) {
         /* read of out-of-frame register returns an undefined value; 0 in our 
case.  */
         DPRINT("ignoring read from r%lu; only %lu registers are allocated!\n", 
r1, sof);
-        panic("wrong stack register number");
+        panic("wrong stack register number (iip=%p)\n", regs->cr_iip);
     }
 
     if (ridx < sor)
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c   Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/vmx/vmx_process.c   Fri Dec  2 18:12:11 2005
@@ -53,8 +53,6 @@
 #define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
 
 
-extern struct ia64_sal_retval pal_emulator_static(UINT64);
-extern struct ia64_sal_retval 
sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
 extern void rnat_consumption (VCPU *vcpu);
 #define DOMN_PAL_REQUEST    0x110000
 
@@ -110,14 +108,15 @@
        }
 #endif
        if (iim == d->arch.breakimm) {
-               struct ia64_sal_retval x;
+               struct ia64_pal_retval y;
+               struct sal_ret_values x;
                switch (regs->r2) {
                    case FW_HYPERCALL_PAL_CALL:
                        //printf("*** PAL hypercall: index=%d\n",regs->r28);
                        //FIXME: This should call a C routine
-                       x = pal_emulator_static(VCPU(v, vgr[12]));
-                       regs->r8 = x.status; regs->r9 = x.v0;
-                       regs->r10 = x.v1; regs->r11 = x.v2;
+                       y = pal_emulator_static(VCPU(v, vgr[12]));
+                       regs->r8 = y.status; regs->r9 = y.v0;
+                       regs->r10 = y.v1; regs->r11 = y.v2;
 #if 0
                        if (regs->r8)
                                printk("Failed vpal emulation, with 
index:0x%lx\n",
@@ -131,8 +130,8 @@
                                         sal_param[2], sal_param[3],
                                         sal_param[4], sal_param[5],
                                         sal_param[6], sal_param[7]);
-                       regs->r8 = x.status; regs->r9 = x.v0;
-                       regs->r10 = x.v1; regs->r11 = x.v2;
+                       regs->r8 = x.r8; regs->r9 = x.r9;
+                       regs->r10 = x.r10; regs->r11 = x.r11;
 #if 0
                        if (regs->r8)
                                printk("Failed vsal emulation, with 
index:0x%lx\n",
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c        Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/xen/dom_fw.c        Fri Dec  2 18:12:11 2005
@@ -18,7 +18,7 @@
 
 #include <asm/dom_fw.h>
 
-struct ia64_boot_param *dom_fw_init(struct domain *, char *,int,char *,int);
+static struct ia64_boot_param *dom_fw_init(struct domain *, char *,int,char 
*,int);
 extern unsigned long domain_mpa_to_imva(struct domain *,unsigned long mpaddr);
 extern struct domain *dom0;
 extern unsigned long dom0_start;
@@ -56,13 +56,22 @@
 
 
 // builds a hypercall bundle at domain physical address
-void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr, unsigned 
long hypercall,unsigned long ret)
+static void dom_fw_hypercall_patch(struct domain *d, unsigned long paddr, 
unsigned long hypercall,unsigned long ret)
 {
        unsigned long imva;
 
-       if (d == dom0) paddr += dom0_start;
        imva = domain_mpa_to_imva(d,paddr);
        build_hypercall_bundle(imva,d->arch.breakimm,hypercall,ret);
+}
+
+static void dom_fw_pal_hypercall_patch(struct domain *d, unsigned long paddr)
+{
+       unsigned long *imva;
+
+       imva = (unsigned long *)domain_mpa_to_imva(d,paddr);
+
+       build_pal_hypercall_bundles (imva, d->arch.breakimm,
+                                     FW_HYPERCALL_PAL_CALL);
 }
 
 
@@ -154,8 +163,6 @@
        tp->day = days + 1;
        return 1;
 }
-
-extern struct ia64_pal_retval pal_emulator_static (unsigned long);
 
 /* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
 
@@ -293,11 +300,6 @@
        long status = -1;
 
        if (running_on_sim) return pal_emulator_static(index);
-       if (index >= PAL_COPY_PAL) {
-               // build_hypercall_bundle needs to be modified to generate
-               // a second bundle that conditionally does a br.ret
-               panic("xen_pal_emulator: stacked calls not supported!!\n");
-       }
        printk("xen_pal_emulator: index=%d\n",index);
        // pal code must be mapped by a TR when pal is called, however
        // calls are rare enough that we will map it lazily rather than
@@ -390,9 +392,26 @@
            case PAL_VM_TR_READ:        /* FIXME: vcpu_get_tr?? */
                printk("PAL_VM_TR_READ NOT IMPLEMENTED, IGNORED!\n");
                break;
-           case PAL_HALT_INFO:         /* inappropriate info for guest? */
-               printk("PAL_HALT_INFO NOT IMPLEMENTED, IGNORED!\n");
-               break;
+           case PAL_HALT_INFO:
+               {
+                   /* 1000 cycles to enter/leave low power state,
+                      consumes 10 mW, implemented and cache/TLB coherent.  */
+                   unsigned long res = 1000UL | (1000UL << 16) | (10UL << 32)
+                           | (1UL << 61) | (1UL << 60);
+                   if (copy_to_user ((void *)in1, &res, sizeof (res)))
+                           status = PAL_STATUS_EINVAL;    
+                   else
+                           status = PAL_STATUS_SUCCESS;
+               }
+               break;
+           case PAL_HALT:
+                   if (current->domain == dom0) {
+                           printf ("Domain0 halts the machine\n");
+                           (*efi.reset_system)(EFI_RESET_SHUTDOWN,0,0,NULL);
+                   }
+                   else
+                           domain_shutdown (current->domain, 0);
+                   break;
            default:
                printk("xen_pal_emulator: UNIMPLEMENTED PAL CALL %d!!!!\n",
                                index);
@@ -400,6 +419,7 @@
        }
        return ((struct ia64_pal_retval) {status, r9, r10, r11});
 }
+
 
 #define NFUNCPTRS 20
 
@@ -607,7 +627,7 @@
        return;
 }
 
-struct ia64_boot_param *
+static struct ia64_boot_param *
 dom_fw_init (struct domain *d, char *args, int arglen, char *fw_mem, int 
fw_mem_size)
 {
        efi_system_table_t *efi_systab;
@@ -615,7 +635,6 @@
        efi_config_table_t *efi_tables;
        struct ia64_sal_systab *sal_systab;
        efi_memory_desc_t *efi_memmap, *md;
-       unsigned long *pal_desc, *sal_desc;
        struct ia64_sal_desc_entry_point *sal_ed;
        struct ia64_boot_param *bp;
        unsigned long *pfn;
@@ -623,7 +642,7 @@
        char *cp, *cmd_line, *fw_vendor;
        int i = 0;
        unsigned long maxmem = (d->max_pages - d->arch.sys_pgnr) * PAGE_SIZE;
-       unsigned long start_mpaddr = ((d==dom0)?dom0_start:0);
+       const unsigned long start_mpaddr = ((d==dom0)?dom0_start:0);
 
 #      define MAKE_MD(typ, attr, start, end, abs)      \       
        do {                                            \
@@ -646,13 +665,6 @@
 */
        memset(fw_mem, 0, fw_mem_size);
 
-#ifdef USE_PAL_EMULATOR
-       pal_desc = (unsigned long *) &pal_emulator_static;
-#else
-       pal_desc = (unsigned long *) &xen_pal_emulator;
-#endif
-       sal_desc = (unsigned long *) &sal_emulator;
-
        cp = fw_mem;
        efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
        efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
@@ -695,7 +707,7 @@
 #define EFI_HYPERCALL_PATCH(tgt,call) do { \
     
dom_efi_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call); \
     tgt = dom_pa(pfn); \
-    *pfn++ = FW_HYPERCALL_##call##_PADDR + ((d==dom0)?dom0_start:0); \
+    *pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr; \
     *pfn++ = 0; \
     } while (0)
 
@@ -783,12 +795,10 @@
 
        /* fill in an entry point: */
        sal_ed->type = SAL_DESC_ENTRY_POINT;
-#define FW_HYPERCALL_PATCH(tgt,call,ret) do { \
-    
dom_fw_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call,ret); \
-    tgt = FW_HYPERCALL_##call##_PADDR + ((d==dom0)?dom0_start:0); \
-    } while (0)
-       FW_HYPERCALL_PATCH(sal_ed->pal_proc,PAL_CALL,0);
-       FW_HYPERCALL_PATCH(sal_ed->sal_proc,SAL_CALL,1);
+       sal_ed->pal_proc = FW_HYPERCALL_PAL_CALL_PADDR + start_mpaddr;
+       dom_fw_pal_hypercall_patch (d, sal_ed->pal_proc);
+       sal_ed->sal_proc = FW_HYPERCALL_SAL_CALL_PADDR + start_mpaddr;
+       dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
        sal_ed->gp = 0;  // will be ignored
 
        for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c     Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/xen/hypercall.c     Fri Dec  2 18:12:11 2005
@@ -18,8 +18,6 @@
 #include <public/sched.h>
 
 extern unsigned long translate_domain_mpaddr(unsigned long);
-extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
-extern struct ia64_sal_retval 
sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
 
 unsigned long idle_when_pending = 0;
 unsigned long pal_halt_light_count = 0;
@@ -28,8 +26,7 @@
 ia64_hypercall (struct pt_regs *regs)
 {
        struct vcpu *v = (struct domain *) current;
-       struct ia64_sal_retval x;
-       struct ia64_pal_retval y;
+       struct sal_ret_values x;
        unsigned long *tv, *tc;
        int pi;
 
@@ -62,25 +59,33 @@
                                pal_halt_light_count++;
                                do_sched_op(SCHEDOP_yield);
                        }
-                       //break;
+                       regs->r8 = 0;
+                       regs->r9 = 0;
+                       regs->r10 = 0;
+                       regs->r11 = 0;
                }
-               else if (regs->r28 >= PAL_COPY_PAL) {   /* FIXME */
-                       printf("stacked PAL hypercalls not supported\n");
-                       regs->r8 = -1;
-                       break;
+               else {
+                       struct ia64_pal_retval y;
+
+                       if (regs->r28 >= PAL_COPY_PAL)
+                               y = xen_pal_emulator
+                                       (regs->r28, vcpu_get_gr (v, 33),
+                                        vcpu_get_gr (v, 34),
+                                        vcpu_get_gr (v, 35));
+                       else
+                               y = xen_pal_emulator(regs->r28,regs->r29,
+                                                    regs->r30,regs->r31);
+                       regs->r8 = y.status; regs->r9 = y.v0;
+                       regs->r10 = y.v1; regs->r11 = y.v2;
                }
-               else y = xen_pal_emulator(regs->r28,regs->r29,
-                                               regs->r30,regs->r31);
-               regs->r8 = y.status; regs->r9 = y.v0;
-               regs->r10 = y.v1; regs->r11 = y.v2;
                break;
            case FW_HYPERCALL_SAL_CALL:
                x = sal_emulator(vcpu_get_gr(v,32),vcpu_get_gr(v,33),
                        vcpu_get_gr(v,34),vcpu_get_gr(v,35),
                        vcpu_get_gr(v,36),vcpu_get_gr(v,37),
                        vcpu_get_gr(v,38),vcpu_get_gr(v,39));
-               regs->r8 = x.status; regs->r9 = x.v0;
-               regs->r10 = x.v1; regs->r11 = x.v2;
+               regs->r8 = x.r8; regs->r9 = x.r9;
+               regs->r10 = x.r10; regs->r11 = x.r11;
                break;
            case FW_HYPERCALL_EFI_RESET_SYSTEM:
                printf("efi.reset_system called ");
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/xen/privop.c
--- a/xen/arch/ia64/xen/privop.c        Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/xen/privop.c        Fri Dec  2 18:12:11 2005
@@ -10,6 +10,7 @@
 #include <asm/vcpu.h>
 #include <asm/processor.h>
 #include <asm/delay.h> // Debug only
+#include <asm/dom_fw.h>
 //#include <debug.h>
 
 long priv_verbose=0;
@@ -53,6 +54,39 @@
        
        *imva++ = bundle.i64[0]; *imva = bundle.i64[1];
 }
+
+void build_pal_hypercall_bundles(UINT64 *imva, UINT64 brkimm, UINT64 hypnum)
+{
+       extern unsigned long pal_call_stub[];
+       IA64_BUNDLE bundle;
+       INST64_A5 slot_a5;
+       INST64_M37 slot_m37;
+
+       /* The source of the hypercall stub is the pal_call_stub function
+          defined in xenasm.S.  */
+
+       /* Copy the first bundle and patch the hypercall number.  */
+       bundle.i64[0] = pal_call_stub[0];
+       bundle.i64[1] = pal_call_stub[1];
+       slot_a5.inst = bundle.slot0;
+       slot_a5.imm7b = hypnum;
+       slot_a5.imm9d = hypnum >> 7;
+       slot_a5.imm5c = hypnum >> 16;
+       bundle.slot0 = slot_a5.inst;
+       imva[0] = bundle.i64[0];
+       imva[1] = bundle.i64[1];
+       
+       /* Copy the second bundle and patch the hypercall vector.  */
+       bundle.i64[0] = pal_call_stub[2];
+       bundle.i64[1] = pal_call_stub[3];
+       slot_m37.inst = bundle.slot0;
+       slot_m37.imm20a = brkimm;
+       slot_m37.i = brkimm >> 20;
+       bundle.slot0 = slot_m37.inst;
+       imva[2] = bundle.i64[0];
+       imva[3] = bundle.i64[1];
+}
+
 
 /**************************************************************************
 Privileged operation emulation routines
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c       Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/xen/process.c       Fri Dec  2 18:12:11 2005
@@ -33,8 +33,6 @@
 #include <xen/multicall.h>
 
 extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64);
-extern struct ia64_sal_retval pal_emulator_static(UINT64);
-extern struct ia64_sal_retval 
sal_emulator(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
 
 extern unsigned long dom0_start, dom0_size;
 
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/xen/xenasm.S
--- a/xen/arch/ia64/xen/xenasm.S        Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/xen/xenasm.S        Fri Dec  2 18:12:11 2005
@@ -516,3 +516,27 @@
        br.ret.sptk.few rp
        ;;
 END(vhpt_insert)
+
+//  These instructions are copied in the domains.
+//  This is the virtual PAL, which simply does an hypercall.
+//  The size is 2 bunldes (32 Bytes).  It handles both static and stacked
+//    convention.
+//  If you modify this code, you have to modify dom_fw.h (for the size) and
+//   dom_fw_pal_hypercall_patch.
+GLOBAL_ENTRY(pal_call_stub)
+       {
+        .mii
+       addl r2=0x1000,r0       //  Hypercall number (Value is patched).
+       mov r9=256
+       ;; 
+       cmp.gtu p7,p8=r9,r28            /* r32 <= 255? */
+       }
+       {
+        .mbb
+       break 0x1000    //  Hypercall vector (Value is patched).
+(p7)   br.cond.sptk.few rp
+(p8)   br.ret.sptk.few rp
+       }
+END(pal_call_stub)
+
+
diff -r 97de0e776d8b -r eae5812f33f1 xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c       Fri Dec  2 16:27:22 2005
+++ b/xen/arch/ia64/xen/xenmisc.c       Fri Dec  2 18:12:11 2005
@@ -141,10 +141,12 @@
     //memset(percpu_info, 0, sizeof(percpu_info));
 }
 
+#if 0
 void free_page_type(struct pfn_info *page, unsigned int type)
 {
        dummy();
 }
+#endif
 
 ///////////////////////////////
 //// misc memory stuff
diff -r 97de0e776d8b -r eae5812f33f1 xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h     Fri Dec  2 16:27:22 2005
+++ b/xen/include/asm-ia64/dom_fw.h     Fri Dec  2 18:12:11 2005
@@ -35,6 +35,7 @@
  * rp=b0 indicates the return point.
  *
  * A single hypercall is used for all PAL calls.
+ * The hypercall stub is pal_call_stub (xenasm.S).  Its size is 2 bundles.
  */
 
 #define FW_HYPERCALL_PAL_CALL_INDEX    0x80UL
@@ -53,7 +54,7 @@
  * A single hypercall is used for all SAL calls.
  */
 
-#define FW_HYPERCALL_SAL_CALL_INDEX    0x81UL
+#define FW_HYPERCALL_SAL_CALL_INDEX    0x82UL
 #define FW_HYPERCALL_SAL_CALL_PADDR    
FW_HYPERCALL_PADDR(FW_HYPERCALL_SAL_CALL_INDEX)
 #define FW_HYPERCALL_SAL_CALL          0x1001UL
 
@@ -117,3 +118,12 @@
 #define FW_HYPERCALL_EFI_SET_VARIABLE_PADDR            
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_SET_VARIABLE_INDEX)
 #define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_PADDR        
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX)
 #define FW_HYPERCALL_EFI_RESET_SYSTEM_PADDR            
FW_HYPERCALL_PADDR(FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX)
+
+extern struct ia64_pal_retval xen_pal_emulator(UINT64,UINT64,UINT64,UINT64);
+extern struct sal_ret_values sal_emulator (long index, unsigned long in1, 
unsigned long in2, unsigned long in3, unsigned long in4, unsigned long in5, 
unsigned long in6, unsigned long in7);
+extern struct ia64_pal_retval pal_emulator_static (unsigned long);
+
+extern void build_pal_hypercall_bundles(unsigned long *imva, unsigned long 
brkimm, unsigned long hypnum);
+extern void build_hypercall_bundle(UINT64 *imva, UINT64 brkimm, UINT64 hypnum, 
UINT64 ret);
+
+
diff -r 97de0e776d8b -r eae5812f33f1 xen/include/asm-ia64/privop.h
--- a/xen/include/asm-ia64/privop.h     Fri Dec  2 16:27:22 2005
+++ b/xen/include/asm-ia64/privop.h     Fri Dec  2 18:12:11 2005
@@ -99,6 +99,11 @@
     IA64_INST inst;
     struct { unsigned long qp:6, r1:7, :14, x6:6, x3:3, :1, major:4; }; 
 } INST64_M36;
+
+typedef union U_INST64_M37 {
+    IA64_INST inst;
+    struct { unsigned long qp:6, imm20a:20,:1, x4:4,x2:2,x3:3, i:1, major:4; };
+} INST64_M37;
 
 typedef union U_INST64_M41 {
     IA64_INST inst;
@@ -190,6 +195,7 @@
     INST64_M33 M33;    // mov from cr
     INST64_M35 M35;    // mov to psr
     INST64_M36 M36;    // mov from psr
+    INST64_M37 M37;    // break.m
     INST64_M41 M41;    // translation cache insert
     INST64_M42 M42;    // mov to indirect reg/translation reg insert
     INST64_M43 M43;    // mov from indirect reg

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Stack pal call emulation implemented. (by Tristan Gingold), Xen patchbot -unstable <=