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] [HVMLOADER] HVM loader initialises hyperc

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [HVMLOADER] HVM loader initialises hypercall shim and uses
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 04 Aug 2006 21:20:16 +0000
Delivery-date: Fri, 04 Aug 2006 14:22:58 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 49dcd838b7df72bfe66ab9233e360b52ceca3115
# Parent  7684f9032f9fb9521de665a277be23d52c87c2de
[HVMLOADER] HVM loader initialises hypercall shim and uses
it to interrogate Xen version information. Also add support
for HVM hypercall execution on 64-bit host.

Signed-off-by: Steven Smith <ssmith@xxxxxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 tools/firmware/Makefile                |    2 
 tools/firmware/hvmloader/Makefile      |    9 +
 tools/firmware/hvmloader/acpi_madt.c   |    4 
 tools/firmware/hvmloader/hvmloader.c   |  117 +++++++++++----------
 tools/firmware/hvmloader/hypercall.h   |  180 +++++++++++++++++++++++++++++++++
 tools/firmware/hvmloader/mp_tables.c   |    3 
 tools/firmware/hvmloader/util.c        |   96 +++++++++++++++++
 tools/firmware/hvmloader/util.h        |   19 +++
 xen/arch/x86/hvm/hvm.c                 |  136 ++++++++++++++++++++----
 xen/arch/x86/hvm/platform.c            |   14 ++
 xen/common/kernel.c                    |    7 +
 xen/include/asm-x86/guest_access.h     |    5 
 xen/include/asm-x86/hvm/guest_access.h |    3 
 xen/include/public/version.h           |    3 
 14 files changed, 510 insertions(+), 88 deletions(-)

diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/Makefile
--- a/tools/firmware/Makefile   Fri Aug 04 16:07:58 2006 +0100
+++ b/tools/firmware/Makefile   Fri Aug 04 20:30:12 2006 +0100
@@ -30,7 +30,7 @@ all:
 .PHONY: install
 install: all
        [ -d $(INSTALL_DIR) ] || install -d -m0755 $(INSTALL_DIR)
-       [ ! -e $(TARGET) ] || install -m0644 $(TARGET) $(INSTALL_DIR)
+       install -m0644 $(TARGET) $(INSTALL_DIR)
 
 .PHONY: clean
 clean: 
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Fri Aug 04 16:07:58 2006 +0100
+++ b/tools/firmware/hvmloader/Makefile Fri Aug 04 20:30:12 2006 +0100
@@ -42,12 +42,15 @@ CFLAGS  += $(DEFINES) -I. $(XENINC) -fno
 CFLAGS  += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
 LDFLAGS  = -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR)
 
+SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c
+OBJS = $(patsubst %.c,%.o,$(SRCS))
+
 .PHONY: all
 all: hvmloader
 
-hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c
-       $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c
-       $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o
+hvmloader: roms.h $(SRCS)
+       $(CC) $(CFLAGS) -c $(SRCS)
+       $(CC) $(LDFLAGS) -o hvmloader.tmp $(OBJS)
        $(OBJCOPY) hvmloader.tmp hvmloader
        rm -f hvmloader.tmp
 
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/acpi_madt.c
--- a/tools/firmware/hvmloader/acpi_madt.c      Fri Aug 04 16:07:58 2006 +0100
+++ b/tools/firmware/hvmloader/acpi_madt.c      Fri Aug 04 20:30:12 2006 +0100
@@ -20,12 +20,10 @@
 
 #include "../acpi/acpi2_0.h"
 #include "../acpi/acpi_madt.h"
-
+#include "util.h"
 #include <xen/hvm/hvm_info_table.h>
 
 #define NULL ((void*)0)
-
-extern int puts(const char *s);
 
 static struct hvm_info_table *table = NULL;
 
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Fri Aug 04 16:07:58 2006 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Fri Aug 04 20:30:12 2006 +0100
@@ -23,9 +23,13 @@
  */
 #include "roms.h"
 #include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "hypercall.h"
+#include "util.h"
+#include <xen/version.h>
 #include <xen/hvm/hvm_info_table.h>
 
 /* memory map */
+#define HYPERCALL_PHYSICAL_ADDRESS     0x00080000
 #define VGABIOS_PHYSICAL_ADDRESS       0x000C0000
 #define        VMXASSIST_PHYSICAL_ADDRESS      0x000D0000
 #define        ROMBIOS_PHYSICAL_ADDRESS        0x000F0000
@@ -75,65 +79,14 @@ extern void create_mp_tables(void);
 extern void create_mp_tables(void);
 struct hvm_info_table *get_hvm_info_table(void);
 
-static inline void
-outw(unsigned short addr, unsigned short val)
-{
-        __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline void
-outb(unsigned short addr, unsigned char val)
-{
-        __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline unsigned char
-inb(unsigned short addr)
-{
-        unsigned char val;
-
-        __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
-        return val;
-}
-
-void *
-memcpy(void *dest, const void *src, unsigned n)
-{
-       int t0, t1, t2;
-
-       __asm__ __volatile__(
-               "cld\n"
-               "rep; movsl\n"
-               "testb $2,%b4\n"
-               "je 1f\n"
-               "movsw\n"
-               "1: testb $1,%b4\n"
-               "je 2f\n"
-               "movsb\n"
-               "2:"
-               : "=&c" (t0), "=&D" (t1), "=&S" (t2)
-               : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
-               : "memory"
-       );
-       return dest;
-}
-
-int
-puts(const char *s)
-{
-       while (*s)
-               outb(0xE9, *s++);
-       return 0;
-}
-
-int
+static int
 cirrus_check(void)
 {
        outw(0x3C4, 0x9206);
        return inb(0x3C5) == 0x12;
 }
 
-int
+static int
 vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
 {
         int eax;
@@ -147,7 +100,7 @@ vmmcall(int function, int edi, int esi, 
         return eax;
 }
 
-int
+static int
 check_amd(void)
 {
        char id[12];
@@ -162,12 +115,68 @@ check_amd(void)
        return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
 }
 
+static void
+cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
+{
+       __asm__ __volatile__(
+               "cpuid"
+               : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+               : "0" (idx) );
+}
+
+static void
+wrmsr(uint32_t idx, uint64_t v)
+{
+       __asm__ __volatile__(
+               "wrmsr"
+               : : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) );
+}
+
+static void
+init_hypercalls(void)
+{
+       uint32_t eax, ebx, ecx, edx;
+       unsigned long i;
+       char signature[13], number[13];
+       xen_extraversion_t extraversion;
+
+       cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
+
+       *(uint32_t *)(signature + 0) = ebx;
+       *(uint32_t *)(signature + 4) = ecx;
+       *(uint32_t *)(signature + 8) = edx;
+       signature[12] = '\0';
+
+       if (strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002)) {
+               puts("FATAL: Xen hypervisor not detected\n");
+               __asm__ __volatile__( "ud2" );
+       }
+
+       cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
+
+       puts("Detected Xen v");
+       puts(itoa(number, eax >> 16));
+       puts(".");
+       puts(itoa(number, eax & 0xffff));
+
+       cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
+
+       for (i = 0; i < eax; i++)
+               wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i);
+
+       hypercall_xen_version(XENVER_extraversion, extraversion);
+       puts(extraversion);
+       puts("\n");
+}
+
 int
 main(void)
 {
        struct hvm_info_table *t = get_hvm_info_table();
 
        puts("HVM Loader\n");
+
+       init_hypercalls();
 
        puts("Loading ROMBIOS ...\n");
        memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios));
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/mp_tables.c
--- a/tools/firmware/hvmloader/mp_tables.c      Fri Aug 04 16:07:58 2006 +0100
+++ b/tools/firmware/hvmloader/mp_tables.c      Fri Aug 04 20:30:12 2006 +0100
@@ -93,7 +93,8 @@ typedef   signed long int64_t;
 
 #define INTR_MAX_NR            16
 
-extern int puts(const char *); /* for printing */
+#include "util.h"
+
 extern int get_vcpu_nr(void);  /* for the guest's VCPU count */
 
 /*
diff -r 7684f9032f9f -r 49dcd838b7df xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Fri Aug 04 16:07:58 2006 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Fri Aug 04 20:30:12 2006 +0100
@@ -28,6 +28,7 @@
 #include <xen/domain.h>
 #include <xen/domain_page.h>
 #include <xen/hypercall.h>
+#include <xen/guest_access.h>
 #include <asm/current.h>
 #include <asm/io.h>
 #include <asm/shadow.h>
@@ -46,7 +47,8 @@
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <public/hvm/hvm_info_table.h>
-#include <xen/guest_access.h>
+#include <public/version.h>
+#include <public/memory.h>
 
 int hvm_enabled = 0;
 
@@ -305,55 +307,139 @@ void hvm_print_line(struct vcpu *v, cons
        pbuf[(*index)++] = c;
 }
 
-#if defined(__i386__)
-
 typedef unsigned long hvm_hypercall_t(
     unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
-#define HYPERCALL(x) [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x
+
+#define HYPERCALL(x)                                        \
+    [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x
+#define HYPERCALL_COMPAT32(x)                               \
+    [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x ## _compat32
+
+#if defined(__i386__)
+
 static hvm_hypercall_t *hvm_hypercall_table[] = {
-    HYPERCALL(mmu_update),
     HYPERCALL(memory_op),
     HYPERCALL(multicall),
-    HYPERCALL(update_va_mapping),
-    HYPERCALL(event_channel_op_compat),
     HYPERCALL(xen_version),
-    HYPERCALL(grant_table_op),
     HYPERCALL(event_channel_op),
     HYPERCALL(hvm_op)
 };
-#undef HYPERCALL
 
 void hvm_do_hypercall(struct cpu_user_regs *pregs)
 {
-    if ( ring_3(pregs) )
+    if ( unlikely(ring_3(pregs)) )
     {
         pregs->eax = -EPERM;
         return;
     }
 
-    if ( pregs->eax > ARRAY_SIZE(hvm_hypercall_table) ||
-         !hvm_hypercall_table[pregs->eax] )
+    if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] )
     {
         DPRINTK("HVM vcpu %d:%d did a bad hypercall %d.\n",
                 current->domain->domain_id, current->vcpu_id,
                 pregs->eax);
         pregs->eax = -ENOSYS;
+        return;
+    }
+
+    pregs->eax = hvm_hypercall_table[pregs->eax](
+        pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
+}
+
+#else /* defined(__x86_64__) */
+
+static long do_memory_op_compat32(int cmd, XEN_GUEST_HANDLE(void) arg)
+{
+    extern long do_add_to_physmap(struct xen_add_to_physmap *xatp);
+    long rc;
+
+    switch ( cmd )
+    {
+    case XENMEM_add_to_physmap:
+    {
+        struct {
+            domid_t domid;
+            uint32_t space;
+            uint32_t idx;
+            uint32_t gpfn;
+        } u;
+        struct xen_add_to_physmap h;
+
+        if ( copy_from_guest(&u, arg, 1) )
+            return -EFAULT;
+
+        h.domid = u.domid;
+        h.space = u.space;
+        h.idx = u.idx;
+        h.gpfn = u.gpfn;
+
+        this_cpu(guest_handles_in_xen_space) = 1;
+        rc = do_memory_op(cmd, guest_handle_from_ptr(&h, void));
+        this_cpu(guest_handles_in_xen_space) = 0;
+
+        break;
+    }
+
+    default:
+        DPRINTK("memory_op %d.\n", cmd);
+        rc = -ENOSYS;
+        break;
+    }
+
+    return rc;
+}
+
+static hvm_hypercall_t *hvm_hypercall64_table[NR_hypercalls] = {
+    HYPERCALL(memory_op),
+    HYPERCALL(xen_version),
+    HYPERCALL(hvm_op),
+    HYPERCALL(event_channel_op)
+};
+
+static hvm_hypercall_t *hvm_hypercall32_table[NR_hypercalls] = {
+    HYPERCALL_COMPAT32(memory_op),
+    HYPERCALL(xen_version),
+    HYPERCALL(hvm_op),
+    HYPERCALL(event_channel_op)
+};
+
+void hvm_do_hypercall(struct cpu_user_regs *pregs)
+{
+    if ( unlikely(ring_3(pregs)) )
+    {
+        pregs->rax = -EPERM;
+        return;
+    }
+
+    pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */
+    if ( (pregs->rax >= NR_hypercalls) || !hvm_hypercall64_table[pregs->rax] )
+    {
+        DPRINTK("HVM vcpu %d:%d did a bad hypercall %ld.\n",
+                current->domain->domain_id, current->vcpu_id,
+                pregs->rax);
+        pregs->rax = -ENOSYS;
+        return;
+    }
+
+    if ( current->domain->arch.ops->guest_paging_levels == PAGING_L4 )
+    {
+        pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
+                                                       pregs->rsi,
+                                                       pregs->rdx,
+                                                       pregs->r10,
+                                                       pregs->r8);
     }
     else
     {
-        pregs->eax = hvm_hypercall_table[pregs->eax](
-            pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
-    }
-}
-
-#else /* __x86_64__ */
-
-void hvm_do_hypercall(struct cpu_user_regs *pregs)
-{
-    printk("not supported yet!\n");
-}
-
-#endif
+        pregs->eax = hvm_hypercall32_table[pregs->eax]((uint32_t)pregs->ebx,
+                                                       (uint32_t)pregs->ecx,
+                                                       (uint32_t)pregs->edx,
+                                                       (uint32_t)pregs->esi,
+                                                       (uint32_t)pregs->edi);
+    }
+}
+
+#endif /* defined(__x86_64__) */
 
 /* Initialise a hypercall transfer page for a VMX domain using
    paravirtualised drivers. */
diff -r 7684f9032f9f -r 49dcd838b7df xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c       Fri Aug 04 16:07:58 2006 +0100
+++ b/xen/arch/x86/hvm/platform.c       Fri Aug 04 20:30:12 2006 +0100
@@ -1034,17 +1034,31 @@ void handle_mmio(unsigned long va, unsig
     }
 }
 
+DEFINE_PER_CPU(int, guest_handles_in_xen_space);
+
 /* Note that copy_{to,from}_user_hvm don't set the A and D bits on
    PTEs, and require the PTE to be writable even when they're only
    trying to read from it.  The guest is expected to deal with
    this. */
 unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len)
 {
+    if ( this_cpu(guest_handles_in_xen_space) )
+    {
+        memcpy(to, from, len);
+        return 0;
+    }
+
     return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT);
 }
 
 unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len)
 {
+    if ( this_cpu(guest_handles_in_xen_space) )
+    {
+        memcpy(to, from, len);
+        return 0;
+    }
+
     return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN);
 }
 
diff -r 7684f9032f9f -r 49dcd838b7df xen/common/kernel.c
--- a/xen/common/kernel.c       Fri Aug 04 16:07:58 2006 +0100
+++ b/xen/common/kernel.c       Fri Aug 04 20:30:12 2006 +0100
@@ -217,6 +217,13 @@ long do_xen_version(int cmd, XEN_GUEST_H
         return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
     }
 
+    case XENVER_guest_handle:
+    {
+        if ( copy_to_guest(arg, (char *)current->domain->handle,
+                           sizeof(current->domain->handle)) )
+            return -EFAULT;
+        return 0;
+    }    
     }
 
     return -ENOSYS;
diff -r 7684f9032f9f -r 49dcd838b7df xen/include/asm-x86/guest_access.h
--- a/xen/include/asm-x86/guest_access.h        Fri Aug 04 16:07:58 2006 +0100
+++ b/xen/include/asm-x86/guest_access.h        Fri Aug 04 20:30:12 2006 +0100
@@ -20,8 +20,11 @@
 /* Cast a guest handle to the specified type of handle. */
 #define guest_handle_cast(hnd, type) ({         \
     type *_x = (hnd).p;                         \
-    (XEN_GUEST_HANDLE(type)) { _x };                \
+    (XEN_GUEST_HANDLE(type)) { _x };            \
 })
+
+#define guest_handle_from_ptr(ptr, type)        \
+    ((XEN_GUEST_HANDLE(type)) { (type *)ptr })
 
 /*
  * Copy an array of objects to guest context via a guest handle,
diff -r 7684f9032f9f -r 49dcd838b7df xen/include/asm-x86/hvm/guest_access.h
--- a/xen/include/asm-x86/hvm/guest_access.h    Fri Aug 04 16:07:58 2006 +0100
+++ b/xen/include/asm-x86/hvm/guest_access.h    Fri Aug 04 20:30:12 2006 +0100
@@ -1,5 +1,8 @@
 #ifndef __ASM_X86_HVM_GUEST_ACCESS_H__
 #define __ASM_X86_HVM_GUEST_ACCESS_H__
+
+#include <xen/percpu.h>
+DECLARE_PER_CPU(int, guest_handles_in_xen_space);
 
 unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len);
 unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len);
diff -r 7684f9032f9f -r 49dcd838b7df xen/include/public/version.h
--- a/xen/include/public/version.h      Fri Aug 04 16:07:58 2006 +0100
+++ b/xen/include/public/version.h      Fri Aug 04 20:30:12 2006 +0100
@@ -57,6 +57,9 @@ typedef struct xen_feature_info xen_feat
 /* arg == NULL; returns host memory page size. */
 #define XENVER_pagesize 7
 
+/* arg == xen_domain_handle_t. */
+#define XENVER_guest_handle 8
+
 #endif /* __XEN_PUBLIC_VERSION_H__ */
 
 /*
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/hypercall.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/hypercall.h      Fri Aug 04 20:30:12 2006 +0100
@@ -0,0 +1,180 @@
+/******************************************************************************
+ * hypercall.h
+ * 
+ * Copyright (c) 2002-2006, K A Fraser
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __HVMLOADER_HYPERCALL_H__
+#define __HVMLOADER_HYPERCALL_H__
+
+/*
+ * NB. Hypercall address needs to be relative to a linkage symbol for
+ * some version of ld to relocate the relative calls properly.
+ * Keep this in sync with HYPERCALL_PHYSICAL_ADDRESS in hvmloader.c!
+ */
+#define hypercall_pa "_start - 0x80000"
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+#define _hypercall0(type, name)                                                
\
+({                                                                     \
+       long __res;                                                     \
+       asm volatile (                                                  \
+               "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32)  \
+               : "=a" (__res)                                          \
+               :                                                       \
+               : "memory" );                                           \
+       (type)__res;                                                    \
+})
+
+#define _hypercall1(type, name, a1)                                    \
+({                                                                     \
+       long __res, __ign1;                                             \
+       asm volatile (                                                  \
+               "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32)  \
+               : "=a" (__res), "=b" (__ign1)                           \
+               : "1" ((long)(a1))                                      \
+               : "memory" );                                           \
+       (type)__res;                                                    \
+})
+
+#define _hypercall2(type, name, a1, a2)                                        
\
+({                                                                     \
+       long __res, __ign1, __ign2;                                     \
+       asm volatile (                                                  \
+               "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32)  \
+               : "=a" (__res), "=b" (__ign1), "=c" (__ign2)            \
+               : "1" ((long)(a1)), "2" ((long)(a2))                    \
+               : "memory" );                                           \
+       (type)__res;                                                    \
+})
+
+#define _hypercall3(type, name, a1, a2, a3)                            \
+({                                                                     \
+       long __res, __ign1, __ign2, __ign3;                             \
+       asm volatile (                                                  \
+               "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32)  \
+               : "=a" (__res), "=b" (__ign1), "=c" (__ign2),           \
+               "=d" (__ign3)                                           \
+               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
+               "3" ((long)(a3))                                        \
+               : "memory" );                                           \
+       (type)__res;                                                    \
+})
+
+#define _hypercall4(type, name, a1, a2, a3, a4)                                
\
+({                                                                     \
+       long __res, __ign1, __ign2, __ign3, __ign4;                     \
+       asm volatile (                                                  \
+               "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32)  \
+               : "=a" (__res), "=b" (__ign1), "=c" (__ign2),           \
+               "=d" (__ign3), "=S" (__ign4)                            \
+               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
+               "3" ((long)(a3)), "4" ((long)(a4))                      \
+               : "memory" );                                           \
+       (type)__res;                                                    \
+})
+
+#define _hypercall5(type, name, a1, a2, a3, a4, a5)                    \
+({                                                                     \
+       long __res, __ign1, __ign2, __ign3, __ign4, __ign5;             \
+       asm volatile (                                                  \
+               "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32)  \
+               : "=a" (__res), "=b" (__ign1), "=c" (__ign2),           \
+               "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)             \
+               : "1" ((long)(a1)), "2" ((long)(a2)),                   \
+               "3" ((long)(a3)), "4" ((long)(a4)),                     \
+               "5" ((long)(a5))                                        \
+               : "memory" );                                           \
+       (type)__res;                                                    \
+})
+
+static inline int
+hypercall_sched_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, sched_op, cmd, arg);
+}
+
+static inline int
+hypercall_memory_op(
+       unsigned int cmd, void *arg)
+{
+       return _hypercall2(int, memory_op, cmd, arg);
+}
+
+static inline int
+hypercall_multicall(
+       void *call_list, int nr_calls)
+{
+       return _hypercall2(int, multicall, call_list, nr_calls);
+}
+
+static inline int
+hypercall_event_channel_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, event_channel_op, cmd, arg);
+}
+
+static inline int
+hypercall_xen_version(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, xen_version, cmd, arg);
+}
+
+static inline int
+hypercall_console_io(
+       int cmd, int count, char *str)
+{
+       return _hypercall3(int, console_io, cmd, count, str);
+}
+
+static inline int
+hypercall_vm_assist(
+       unsigned int cmd, unsigned int type)
+{
+       return _hypercall2(int, vm_assist, cmd, type);
+}
+
+static inline int
+hypercall_vcpu_op(
+       int cmd, int vcpuid, void *extra_args)
+{
+       return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
+}
+
+static inline int
+hypercall_hvm_op(
+       int cmd, void *arg)
+{
+       return _hypercall2(int, hvm_op, cmd, arg);
+}
+
+#endif /* __HVMLOADER_HYPERCALL_H__ */
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/util.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/util.c   Fri Aug 04 20:30:12 2006 +0100
@@ -0,0 +1,96 @@
+/*
+ * util.c: Helper library functions for HVMLoader.
+ *
+ * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
+ * Copyright (c) 2005, International Business Machines Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "../acpi/acpi2_0.h"  /* for ACPI_PHYSICAL_ADDRESS */
+#include "util.h"
+
+void outw(uint16_t addr, uint16_t val)
+{
+       __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
+}
+
+void outb(uint16_t addr, uint8_t val)
+{
+       __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
+}
+
+uint8_t inb(uint16_t addr)
+{
+       uint8_t val;
+       __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
+       return val;
+}
+
+char *itoa(char *a, unsigned int i)
+{
+       unsigned int _i = i, x = 0;
+
+       do {
+               x++;
+               _i /= 10;
+       } while (_i != 0);
+
+       a += x;
+       *a-- = '\0';
+
+       do {
+               *a-- = (i % 10) + '0';
+               i /= 10;
+       } while (i != 0);
+
+       return a + 1;
+}
+
+int strcmp(const char *cs, const char *ct)
+{
+       signed char res;
+
+       while (((res = *cs - *ct++) == 0) && (*cs++ != '\0'))
+               continue;
+
+       return res;
+}
+
+void *memcpy(void *dest, const void *src, unsigned n)
+{
+       int t0, t1, t2;
+
+       __asm__ __volatile__(
+               "cld\n"
+               "rep; movsl\n"
+               "testb $2,%b4\n"
+               "je 1f\n"
+               "movsw\n"
+               "1: testb $1,%b4\n"
+               "je 2f\n"
+               "movsb\n"
+               "2:"
+               : "=&c" (t0), "=&D" (t1), "=&S" (t2)
+               : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
+               : "memory"
+       );
+       return dest;
+}
+
+void puts(const char *s)
+{
+       while (*s)
+               outb(0xE9, *s++);
+}
diff -r 7684f9032f9f -r 49dcd838b7df tools/firmware/hvmloader/util.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/firmware/hvmloader/util.h   Fri Aug 04 20:30:12 2006 +0100
@@ -0,0 +1,19 @@
+#ifndef __HVMLOADER_UTIL_H__
+#define __HVMLOADER_UTIL_H__
+
+/* I/O output */
+void outw(uint16_t addr, uint16_t val);
+void outb(uint16_t addr, uint8_t val);
+
+/* I/O input */
+uint8_t inb(uint16_t addr);
+
+/* String and memory functions */
+int strcmp(const char *cs, const char *ct);
+void *memcpy(void *dest, const void *src, unsigned n);
+char *itoa(char *a, unsigned int i);
+
+/* Debug output */
+void puts(const char *s);
+
+#endif /* __HVMLOADER_UTIL_H__ */

_______________________________________________
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] [HVMLOADER] HVM loader initialises hypercall shim and uses, Xen patchbot-unstable <=