[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVMLOADER] HVM loader initialises hypercall shim and uses
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |