From 77fedcb809bfd6884c6c0d5c5ac0670a93e0504a Mon Sep 17 00:00:00 2001 From: Julien Grall Date: Sun, 29 Mar 2015 21:10:13 +0100 Subject: [PATCH] Make Xen compiler for ARM64 --- sys/arm64/arm64/pmap.c | 20 ++++++ sys/arm64/conf/GENERIC | 1 + sys/arm64/include/intr.h | 14 ++++ sys/arm64/include/intr_machdep.h | 1 + sys/arm64/include/xen/hypercall.h | 56 ++++++++++++++++ sys/arm64/include/xen/synch_bitops.h | 52 +++++++++++++++ sys/arm64/include/xen/xen-os.h | 37 +++++++++++ sys/arm64/include/xen/xenfunc.h | 4 ++ sys/arm64/include/xen/xenvar.h | 14 ++++ sys/arm64/xen/hypercall.S | 93 +++++++++++++++++++++++++++ sys/conf/files.arm64 | 3 + sys/conf/options.arm64 | 1 + sys/dev/xen/control/control.c | 6 +- sys/dev/xen/grant_table/grant_table.c | 1 - 14 files changed, 299 insertions(+), 4 deletions(-) create mode 100644 sys/arm64/include/intr_machdep.h create mode 100644 sys/arm64/include/xen/hypercall.h create mode 100644 sys/arm64/include/xen/synch_bitops.h create mode 100644 sys/arm64/include/xen/xen-os.h create mode 100644 sys/arm64/include/xen/xenfunc.h create mode 100644 sys/arm64/include/xen/xenvar.h create mode 100644 sys/arm64/xen/hypercall.S diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 004b4a7656af..ab59e5e5972c 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -879,6 +879,26 @@ pmap_kextract(vm_offset_t va) * Low level mapping routines..... ***************************************************/ +/* + * Add a wired page to the kva. + * Note: not SMP coherent. + */ +PMAP_INLINE void +pmap_kenter(vm_offset_t va, vm_paddr_t pa) +{ + pt_entry_t *l3; + + KASSERT((pa & L3_OFFSET) == 0, + ("pmap_kenter: Invalid physical address")); + KASSERT((va & L3_OFFSET) == 0, + ("pmap_kenter: Invalid virtual address")); + l3 = pmap_l3(kernel_pmap, va); + KASSERT(l3 != NULL, ("Invalid page table, va: 0x%lx", va)); + pmap_load_store(l3, (pa & ~L3_OFFSET) | ATTR_AF | L3_PAGE | + ATTR_IDX(CACHED_MEMORY)); + PTE_SYNC(l3); +} + void pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm_paddr_t pa) { diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index 26ca51df86ac..5adaf6484125 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -24,6 +24,7 @@ ident GENERIC makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions NO_MODULES=1 # We don't yet support modules on arm64 +options XENHVM options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking diff --git a/sys/arm64/include/intr.h b/sys/arm64/include/intr.h index 1031c64b3ded..55994118354d 100644 --- a/sys/arm64/include/intr.h +++ b/sys/arm64/include/intr.h @@ -53,4 +53,18 @@ void arm_setup_ipihandler(driver_filter_t *, u_int); void arm_unmask_ipi(u_int); #endif +#ifdef XENHVM +#include +#define NUM_EVTCHN_INTS NR_EVENT_CHANNELS +#define FIRST_EVTCHN_INT 1024 + NUM_EVTCHN_INTS +#else +#define NUM_EVTCHN_INTS 0 +#endif + +/* TODO: Implement it */ +static inline u_int intr_next_cpu(void) +{ + return 0; +} + #endif /* _MACHINE_INTR_H */ diff --git a/sys/arm64/include/intr_machdep.h b/sys/arm64/include/intr_machdep.h new file mode 100644 index 000000000000..91e06a0f8fe6 --- /dev/null +++ b/sys/arm64/include/intr_machdep.h @@ -0,0 +1 @@ +#include diff --git a/sys/arm64/include/xen/hypercall.h b/sys/arm64/include/xen/hypercall.h new file mode 100644 index 000000000000..0e1e1cc59495 --- /dev/null +++ b/sys/arm64/include/xen/hypercall.h @@ -0,0 +1,56 @@ +#ifndef __MACHINE_XEN_HYPERCALL_H__ +#define __MACHINE_XEN_HYPERCALL_H__ + +#define CONFIG_XEN_COMPAT 0x030003 + +#include +#include + +int +HYPERVISOR_console_io(int cmd, unsigned int count, const char *str); + +int +HYPERVISOR_physdev_op(int cmd, void *arg); + +int +HYPERVISOR_sched_op(int cmd, void *arg); + +int +HYPERVISOR_xen_version(int cmd, void *arg); + +int +HYPERVISOR_grant_table_op(int cmd, void *uop, unsigned int count); + +int +HYPERVISOR_memory_op(unsigned int cmd, void *arg); + +int +HYPERVISOR_event_channel_op(unsigned int cmd, void *arg); + +static inline int +HYPERVISOR_multicall(multicall_entry_t *call_list, unsigned int nr_calls) +{ + panic("Xen multicall hypercall is not implemented on ARM\n"); + return -ENOSYS; +} + +int +HYPERVISOR_vcpu_op(int cmd, unsigned int vcpuid, void *extra_args); + +unsigned long +HYPERVISOR_hvm_op(int op, void *arg); + +int +privcmd_hypercall(long op, long a1, long a2, long a3, long a4, long a5); + +#endif /* __MACHINE_XEN_HYPERCALL_H__ */ + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff --git a/sys/arm64/include/xen/synch_bitops.h b/sys/arm64/include/xen/synch_bitops.h new file mode 100644 index 000000000000..b939611d00f3 --- /dev/null +++ b/sys/arm64/include/xen/synch_bitops.h @@ -0,0 +1,52 @@ +#ifndef __MACHINE_XEN_SYNCH_BITOPS_H__ +#define __MACHINE_XEN_SYNCH_BITOPS_H__ + +#include + +#define synch_cmpxchg(ptr, old, new) \ + __sync_val_compare_and_swap((ptr), (old), (new)) + +#define __bit_mask(b) (1UL << (b) % BITS_PER_LONG) +#define __bit_word(b) ((b) / BITS_PER_LONG) +#define __bit_addr(p, b) ((volatile u_long *)(p) + __bit_word(b)) + +#define synch_clear_bit(b, p) \ + atomic_clear_long(__bit_addr(p, b), __bit_mask(b)) + +#define synch_set_bit(b, p) \ + atomic_set_long(__bit_addr(p, b), __bit_mask(b)) + +static inline long +synch_test_and_clear_bit(long bit, void *p) +{ + long val; + long *var = p; + + var += bit / (sizeof(long) * NBBY); + bit %= sizeof(long) * NBBY; + bit = 1 << bit; + do { + val = *(volatile long *)var; + } while (atomic_cmpset_long(var, val, val & ~bit) == 0); + + return !!(val & bit); +} + +static inline long +synch_test_and_set_bit(long bit, void *p) +{ + long val; + long *var = p; + + var += bit / (sizeof(long) * NBBY); + bit %= sizeof(long) * NBBY; + bit = 1 << bit; + do { + val = *(volatile long *)var; + } while (atomic_cmpset_long(var, val, val | bit) == 0); + + return !!(val & bit); +} + +#endif /* __MACHINE_XEN_SYNCH_BITOPS_H__ */ + diff --git a/sys/arm64/include/xen/xen-os.h b/sys/arm64/include/xen/xen-os.h new file mode 100644 index 000000000000..a27650c35044 --- /dev/null +++ b/sys/arm64/include/xen/xen-os.h @@ -0,0 +1,37 @@ +#ifndef __MACHINE_XEN_XEN_OS_H__ +#define __MACHINE_XEN_XEN_OS_H__ + +#ifndef __ASSEMBLY__ + +/* This is a barrier for the compiler only, NOT the processor! */ +#define barrier() __asm__ __volatile__("": : :"memory") +#define cpu_relax() barrier() + +void *xen_pmap(vm_offset_t pa, vm_size_t size); +void xen_unmap(vm_offset_t va, vm_size_t size); + +#define __bit_mask(b) (1UL << (b) % BITS_PER_LONG) +#define __bit_word(b) ((b) / BITS_PER_LONG) +#define __bit_addr(p, b) ((volatile u_long *)(p) + __bit_word(b)) + +/* copied from sys/ofed/include/linux/bitops.h */ +#define test_bit(i, a) \ + !!(atomic_load_acq_long(&((volatile long *)(a))[(i)/BITS_PER_LONG]) &\ + 1 << ((i) % BITS_PER_LONG)) + +#define clear_bit(b, p) \ + atomic_clear_long(__bit_addr(p, b), __bit_mask(b)) + +#define set_bit(b, p) \ + atomic_set_long(__bit_addr(p, b), __bit_mask(b)) + +#define cpu_to_vcpu_id(cpu) cpu + +#define atomic_readandclear_xen_ulong(p) atomic_readandclear_64(p) +#define atomic_store_rel_xen_ulong(p, v) atomic_store_rel_64(p, v) + +void xen_early_init(void); + +#endif + +#endif /* __MACHINE_XEN_XEN_OS__ */ diff --git a/sys/arm64/include/xen/xenfunc.h b/sys/arm64/include/xen/xenfunc.h new file mode 100644 index 000000000000..8fbb98697489 --- /dev/null +++ b/sys/arm64/include/xen/xenfunc.h @@ -0,0 +1,4 @@ +#ifndef __MACHINE_XEN_XEN_FUNC_H__ +#define __MACHINE_XEN_XEN_FUNC_H__ + +#endif /* __MACHINE_XEN_XEN_FUNC_H__ */ diff --git a/sys/arm64/include/xen/xenvar.h b/sys/arm64/include/xen/xenvar.h new file mode 100644 index 000000000000..8d73c744329d --- /dev/null +++ b/sys/arm64/include/xen/xenvar.h @@ -0,0 +1,14 @@ +#ifndef __MACHINE_XEN_XENVAR_H__ +#define __MACHINE_XEN_XENVAR_H__ + +#define BITS_PER_LONG (NBBY * sizeof(long)) + +#define phys_to_machine_mapping_valid(pnf) (TRUE) +#define set_phys_to_machine(pfn, mfn) ((void)0) +#define vtomach(va) pmap_kextract((vm_offset_t)(va)) + +#define PFNTOMFN(pa) (pa) +#define MFNTOPFN(ma) (ma) +#define PT_UPDATES_FLUSH() ((void)0) + +#endif /* __MACHINE_XEN_XENVAR_H__ */ diff --git a/sys/arm64/xen/hypercall.S b/sys/arm64/xen/hypercall.S new file mode 100644 index 000000000000..f167af3075c9 --- /dev/null +++ b/sys/arm64/xen/hypercall.S @@ -0,0 +1,93 @@ +/****************************************************************************** + * hypercall.S + * + * Xen hypercall wrappers + * + * Stefano Stabellini , Citrix, 2012 + * + * 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. + */ + +/* + * The Xen hypercall calling convention is very similar to the procedure + * call standard for the ARM 64-bit architecture: the first parameter is + * passed in x0, the second in x1, the third in x2, the fourth in x3 and + * the fifth in x4. + * + * The hypercall number is passed in x16. + * + * The return value is in x0. + * + * The hvc ISS is required to be 0xEA1, that is the Xen specific ARM + * hypercall tag. + * + * Parameter structs passed to hypercalls are laid out according to + * the ARM 64-bit EABI standard. + */ + +#include +#include +__FBSDID("$FreeBSD$"); + +#define XEN_IMM 0xEA1 + +#define HYPERCALL_SIMPLE(hypercall) \ +ENTRY(HYPERVISOR_##hypercall) \ + mov x16, #__HYPERVISOR_##hypercall; \ + hvc XEN_IMM; \ + ret; \ +END(HYPERVISOR_##hypercall) + +#define HYPERCALL0 HYPERCALL_SIMPLE +#define HYPERCALL1 HYPERCALL_SIMPLE +#define HYPERCALL2 HYPERCALL_SIMPLE +#define HYPERCALL3 HYPERCALL_SIMPLE +#define HYPERCALL4 HYPERCALL_SIMPLE +#define HYPERCALL5 HYPERCALL_SIMPLE + + .text + +HYPERCALL2(xen_version); +HYPERCALL3(console_io); +HYPERCALL3(grant_table_op); +HYPERCALL2(sched_op); +HYPERCALL2(event_channel_op); +HYPERCALL2(hvm_op); +HYPERCALL2(memory_op); +HYPERCALL2(physdev_op); +HYPERCALL3(vcpu_op); +HYPERCALL1(tmem_op); +HYPERCALL2(multicall); + +ENTRY(privcmd_hypercall) + mov x16, x0 + mov x0, x1 + mov x1, x2 + mov x2, x3 + mov x3, x4 + mov x4, x5 + hvc XEN_IMM + ret +END(privcmd_call); diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 399a35ec0663..e273d84fcfc5 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -2,6 +2,8 @@ arm/arm/devmap.c standard arm/arm/generic_timer.c standard arm/arm/pmu.c standard +arm/xenvirt/xen-dt.c optional xenhvm +arm/xenvirt/xen-pmap.c optional xenhvm arm64/acpica/acpi_machdep.c optional acpi arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi @@ -53,6 +55,7 @@ arm64/arm64/vm_machdep.c standard arm64/cavium/thunder_pcie.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci +arm64/xen/hypercall.S optional xenhvm crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb dev/acpica/acpi_if.m optional acpi diff --git a/sys/conf/options.arm64 b/sys/conf/options.arm64 index bc42c825e4ce..9d9dbe7127a5 100644 --- a/sys/conf/options.arm64 +++ b/sys/conf/options.arm64 @@ -5,6 +5,7 @@ SOCDEV_PA opt_global.h SOCDEV_VA opt_global.h THUNDERX_PASS_1_1_ERRATA opt_global.h VFP opt_global.h +XENHVM opt_global.h # SoC Support SOC_CAVM_THUNDERX opt_soc.h diff --git a/sys/dev/xen/control/control.c b/sys/dev/xen/control/control.c index 40a42d7c20b0..e3e3fed7817d 100644 --- a/sys/dev/xen/control/control.c +++ b/sys/dev/xen/control/control.c @@ -187,7 +187,7 @@ xctrl_reboot() shutdown_nice(0); } -#ifndef __arm__ +#if !defined(__arm__) && !defined(__aarch64__) /* HVM mode suspension for x86 platform */ static void xctrl_suspend() @@ -287,7 +287,7 @@ xctrl_suspend() printf("System resumed after suspension\n"); } -#else /* __arm */ +#else /* __arm__ || __aarch64__ */ /* HVM suspend for ARM platform */ static void xctrl_suspend() @@ -295,7 +295,7 @@ xctrl_suspend() panic("xen/control: Suspend not handle for ARM platform!\n"); } -#endif /* !__arm__ */ +#endif /* !__arm__ && !__arch64__ */ static void xctrl_crash() diff --git a/sys/dev/xen/grant_table/grant_table.c b/sys/dev/xen/grant_table/grant_table.c index ab999d2e2149..65f34976f18a 100644 --- a/sys/dev/xen/grant_table/grant_table.c +++ b/sys/dev/xen/grant_table/grant_table.c @@ -13,7 +13,6 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_pmap.h" #include "opt_xen.h" #include -- 2.39.5