aboutsummaryrefslogtreecommitdiff
path: root/extras
diff options
context:
space:
mode:
authorKarim Raslan <karim.allah.ahmed@gmail.com>2014-08-08 16:47:33 +0100
committerIan Campbell <ian.campbell@citrix.com>2014-09-08 12:15:49 +0100
commitabc465b15c341035e6a398e34a108be63035cfc2 (patch)
tree7463251f3eacfb4f09dc5015bf0eafc7edc0bbab /extras
parent7b4afdbe8199a85c4a187d4ee3763b09606df121 (diff)
mini-os: arm: add header files
Adds header files for future ARM support. Based on work by Karim Allah Ahmed. Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com> Signed-off-by: Thomas Leonard <talex5@gmail.com> Acked-by: Julien Grall <julien.grall@linaro.org> Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Diffstat (limited to 'extras')
-rw-r--r--extras/mini-os/include/arm/arch_endian.h7
-rw-r--r--extras/mini-os/include/arm/arch_limits.h9
-rw-r--r--extras/mini-os/include/arm/arch_mm.h38
-rw-r--r--extras/mini-os/include/arm/arch_sched.h19
-rwxr-xr-xextras/mini-os/include/arm/arch_spinlock.h36
-rw-r--r--extras/mini-os/include/arm/arm32/arch_wordsize.h1
-rw-r--r--extras/mini-os/include/arm/gic.h1
-rw-r--r--extras/mini-os/include/arm/hypercall-arm.h98
-rw-r--r--extras/mini-os/include/arm/os.h216
-rw-r--r--extras/mini-os/include/arm/traps.h20
-rw-r--r--extras/mini-os/include/hypervisor.h2
-rw-r--r--extras/mini-os/include/mm.h2
-rw-r--r--extras/mini-os/include/types.h10
13 files changed, 454 insertions, 5 deletions
diff --git a/extras/mini-os/include/arm/arch_endian.h b/extras/mini-os/include/arm/arch_endian.h
new file mode 100644
index 0000000000..07716837e4
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_endian.h
@@ -0,0 +1,7 @@
+#ifndef ARCH_ENDIAN_H
+#error "Do not include arch_endian by itself, include endian.h"
+#else
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+#endif
diff --git a/extras/mini-os/include/arm/arch_limits.h b/extras/mini-os/include/arm/arch_limits.h
new file mode 100644
index 0000000000..bae99e1592
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_limits.h
@@ -0,0 +1,9 @@
+#ifndef __ARCH_LIMITS_H__
+#define __ARCH_LIMITS_H__
+
+#include <mm.h>
+
+#define __STACK_SIZE_PAGE_ORDER 2
+#define __STACK_SIZE (4 * PAGE_SIZE)
+
+#endif
diff --git a/extras/mini-os/include/arm/arch_mm.h b/extras/mini-os/include/arm/arch_mm.h
new file mode 100644
index 0000000000..085d4e5bc4
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_mm.h
@@ -0,0 +1,38 @@
+#ifndef _ARCH_MM_H_
+#define _ARCH_MM_H_
+
+typedef uint64_t paddr_t;
+
+extern char _text, _etext, _erodata, _edata, _end, __bss_start;
+extern int _boot_stack[];
+extern int _boot_stack_end[];
+extern uint32_t physical_address_offset; /* Add this to a virtual address to get the physical address (wraps at 4GB) */
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#define L1_PAGETABLE_SHIFT 12
+
+#define to_phys(x) (((paddr_t)(x)+physical_address_offset) & 0xffffffff)
+#define to_virt(x) ((void *)(((x)-physical_address_offset) & 0xffffffff))
+
+#define PFN_UP(x) (unsigned long)(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
+#define PFN_DOWN(x) (unsigned long)((x) >> L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x) ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
+#define PHYS_PFN(x) (unsigned long)((x) >> L1_PAGETABLE_SHIFT)
+
+#define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt)))
+#define virt_to_mfn(_virt) (PFN_DOWN(to_phys(_virt)))
+#define mfn_to_virt(_mfn) (to_virt(PFN_PHYS(_mfn)))
+#define pfn_to_virt(_pfn) (to_virt(PFN_PHYS(_pfn)))
+
+#define mfn_to_pfn(x) (x)
+#define pfn_to_mfn(x) (x)
+
+#define virtual_to_mfn(_virt) virt_to_mfn(_virt)
+
+// FIXME
+#define map_frames(f, n) (NULL)
+
+#endif
diff --git a/extras/mini-os/include/arm/arch_sched.h b/extras/mini-os/include/arm/arch_sched.h
new file mode 100644
index 0000000000..de3ac02bab
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_sched.h
@@ -0,0 +1,19 @@
+#ifndef __ARCH_SCHED_H__
+#define __ARCH_SCHED_H__
+
+#include "arch_limits.h"
+
+static inline struct thread* get_current(void)
+{
+ struct thread **current;
+ unsigned long sp;
+ __asm__ __volatile__ ("mov %0, sp":"=r"(sp));
+ current = (void *)(unsigned long)(sp & ~(__STACK_SIZE-1));
+ return *current;
+}
+
+void __arch_switch_threads(unsigned long *prevctx, unsigned long *nextctx);
+
+#define arch_switch_threads(prev,next) __arch_switch_threads(&(prev)->sp, &(next)->sp)
+
+#endif /* __ARCH_SCHED_H__ */
diff --git a/extras/mini-os/include/arm/arch_spinlock.h b/extras/mini-os/include/arm/arch_spinlock.h
new file mode 100755
index 0000000000..dccb9fc5dc
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_spinlock.h
@@ -0,0 +1,36 @@
+#ifndef __ARCH_ASM_SPINLOCK_H
+#define __ARCH_ASM_SPINLOCK_H
+
+#include "os.h"
+
+#define ARCH_SPIN_LOCK_UNLOCKED { 1 }
+
+/*
+ * Simple spin lock operations. There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+
+#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0)
+#define arch_spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
+
+static inline void _raw_spin_unlock(spinlock_t *lock)
+{
+ xchg(&lock->slock, 1);
+}
+
+static inline int _raw_spin_trylock(spinlock_t *lock)
+{
+ return xchg(&lock->slock, 0) != 0 ? 1 : 0;
+}
+
+static inline void _raw_spin_lock(spinlock_t *lock)
+{
+ volatile int was_locked;
+ do {
+ was_locked = xchg(&lock->slock, 0) == 0 ? 1 : 0;
+ } while(was_locked);
+}
+
+#endif
diff --git a/extras/mini-os/include/arm/arm32/arch_wordsize.h b/extras/mini-os/include/arm/arm32/arch_wordsize.h
new file mode 100644
index 0000000000..b47eee944a
--- /dev/null
+++ b/extras/mini-os/include/arm/arm32/arch_wordsize.h
@@ -0,0 +1 @@
+#define __WORDSIZE 32
diff --git a/extras/mini-os/include/arm/gic.h b/extras/mini-os/include/arm/gic.h
new file mode 100644
index 0000000000..cead2e51c0
--- /dev/null
+++ b/extras/mini-os/include/arm/gic.h
@@ -0,0 +1 @@
+void gic_init(void);
diff --git a/extras/mini-os/include/arm/hypercall-arm.h b/extras/mini-os/include/arm/hypercall-arm.h
new file mode 100644
index 0000000000..26ac9f8eb0
--- /dev/null
+++ b/extras/mini-os/include/arm/hypercall-arm.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * hypercall-arm.h
+ *
+ * Copied from XenLinux.
+ *
+ * Copyright (c) 2002-2004, K A Fraser
+ *
+ * 64-bit updates:
+ * Benjamin Liu <benjamin.liu@intel.com>
+ * Jun Nakajima <jun.nakajima@intel.com>
+ *
+ * This file may be 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 __HYPERCALL_ARM_H__
+#define __HYPERCALL_ARM_H__
+
+#include <xen/xen.h>
+#include <xen/sched.h>
+#include <xen/xsm/flask_op.h>
+#include <mini-os/mm.h>
+
+int
+HYPERVISOR_sched_op(
+ int cmd, void *arg);
+
+static inline int
+HYPERVISOR_shutdown(
+ unsigned int reason)
+{
+ struct sched_shutdown shutdown = { .reason = reason };
+ HYPERVISOR_sched_op(SCHEDOP_shutdown, &shutdown);
+}
+
+int
+HYPERVISOR_memory_op(
+ unsigned int cmd, void *arg);
+
+int
+HYPERVISOR_event_channel_op(
+ int cmd, void *op);
+
+int
+HYPERVISOR_xen_version(
+ int cmd, void *arg);
+
+int
+HYPERVISOR_console_io(
+ int cmd, int count, char *str);
+
+int
+HYPERVISOR_physdev_op(
+ void *physdev_op);
+
+int
+HYPERVISOR_grant_table_op(
+ unsigned int cmd, void *uop, unsigned int count);
+
+int
+HYPERVISOR_vcpu_op(
+ int cmd, int vcpuid, void *extra_args);
+
+int
+HYPERVISOR_sysctl(
+ unsigned long op);
+
+int
+HYPERVISOR_domctl(
+ unsigned long op);
+
+int
+HYPERVISOR_hvm_op(
+ unsigned long op, void *arg);
+
+int
+HYPERVISOR_xsm_op(
+ struct xen_flask_op *);
+
+#endif /* __HYPERCALL_ARM_H__ */
diff --git a/extras/mini-os/include/arm/os.h b/extras/mini-os/include/arm/os.h
new file mode 100644
index 0000000000..6a1cc37e88
--- /dev/null
+++ b/extras/mini-os/include/arm/os.h
@@ -0,0 +1,216 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+#ifndef __ASSEMBLY__
+
+#include <mini-os/hypervisor.h>
+#include <mini-os/types.h>
+#include <mini-os/compiler.h>
+#include <mini-os/kernel.h>
+#include <xen/xen.h>
+
+void arch_fini(void);
+void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
+
+extern void *device_tree;
+
+#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined instruction; will call our fault handler. */
+
+#define smp_processor_id() 0
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+extern shared_info_t *HYPERVISOR_shared_info;
+
+// disable interrupts
+static inline void local_irq_disable(void) {
+ __asm__ __volatile__("cpsid i":::"memory");
+}
+
+// enable interrupts
+static inline void local_irq_enable(void) {
+ __asm__ __volatile__("cpsie i":::"memory");
+}
+
+#define local_irq_save(x) { \
+ __asm__ __volatile__("mrs %0, cpsr;cpsid i":"=r"(x)::"memory"); \
+}
+
+#define local_irq_restore(x) { \
+ __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory"); \
+}
+
+#define local_save_flags(x) { \
+ __asm__ __volatile__("mrs %0, cpsr":"=r"(x)::"memory"); \
+}
+
+static inline int irqs_disabled(void) {
+ int x;
+ local_save_flags(x);
+ return x & 0x80;
+}
+
+/* We probably only need "dmb" here, but we'll start by being paranoid. */
+#define mb() __asm__("dsb":::"memory");
+#define rmb() __asm__("dsb":::"memory");
+#define wmb() __asm__("dsb":::"memory");
+
+/************************** arm *******************************/
+#ifdef __INSIDE_MINIOS__
+#if defined (__arm__)
+#define xchg(ptr,v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST)
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ *
+ * This operation is atomic.
+ * If you need a memory barrier, use synch_test_and_clear_bit instead.
+ */
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+ uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
+ uint8_t bit = 1 << (nr & 7);
+ uint8_t orig;
+
+ orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_RELAXED);
+
+ return (orig & bit) != 0;
+}
+
+/**
+ * Atomically set a bit and return the old value.
+ * Similar to test_and_clear_bit.
+ */
+static __inline__ int test_and_set_bit(int nr, volatile void *base)
+{
+ uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
+ uint8_t bit = 1 << (nr & 7);
+ uint8_t orig;
+
+ orig = __atomic_fetch_or(byte, bit, __ATOMIC_RELAXED);
+
+ return (orig & bit) != 0;
+}
+
+/**
+ * Test whether a bit is set. */
+static __inline__ int test_bit(int nr, const volatile unsigned long *addr)
+{
+ const uint8_t *ptr = (const uint8_t *) addr;
+ return ((1 << (nr & 7)) & (ptr[nr >> 3])) != 0;
+}
+
+/**
+ * Atomically set a bit in memory (like test_and_set_bit but discards result).
+ */
+static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+{
+ test_and_set_bit(nr, addr);
+}
+
+/**
+ * Atomically clear a bit in memory (like test_and_clear_bit but discards result).
+ */
+static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+{
+ test_and_clear_bit(nr, addr);
+}
+
+/**
+ * __ffs - find first (lowest) set bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static __inline__ unsigned long __ffs(unsigned long word)
+{
+ int clz;
+
+ /* xxxxx10000 = word
+ * xxxxx01111 = word - 1
+ * 0000011111 = word ^ (word - 1)
+ * 4 = 31 - clz(word ^ (word - 1))
+ */
+
+ __asm__ (
+ "sub r0, %[word], #1\n"
+ "eor r0, r0, %[word]\n"
+ "clz %[clz], r0\n":
+ /* Outputs: */
+ [clz] "=r"(clz):
+ /* Inputs: */
+ [word] "r"(word):
+ /* Clobbers: */
+ "r0");
+
+ return 31 - clz;
+}
+
+#else /* ifdef __arm__ */
+#error "Unsupported architecture"
+#endif
+#endif /* ifdef __INSIDE_MINIOS */
+
+/********************* common arm32 and arm64 ****************************/
+
+/* If *ptr == old, then store new there (and return new).
+ * Otherwise, return the old value.
+ * Atomic. */
+#define synch_cmpxchg(ptr, old, new) \
+({ __typeof__(*ptr) stored = old; \
+ __atomic_compare_exchange_n(ptr, &stored, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \
+})
+
+/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ int synch_test_and_clear_bit(int nr, volatile void *addr)
+{
+ uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
+ uint8_t bit = 1 << (nr & 7);
+ uint8_t orig;
+
+ orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST);
+
+ return (orig & bit) != 0;
+}
+
+/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ int synch_test_and_set_bit(int nr, volatile void *base)
+{
+ uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
+ uint8_t bit = 1 << (nr & 7);
+ uint8_t orig;
+
+ orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST);
+
+ return (orig & bit) != 0;
+}
+
+/* As set_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ void synch_set_bit(int nr, volatile void *addr)
+{
+ synch_test_and_set_bit(nr, addr);
+}
+
+/* As clear_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ void synch_clear_bit(int nr, volatile void *addr)
+{
+ synch_test_and_clear_bit(nr, addr);
+}
+
+/* As test_bit, but with a following memory barrier. */
+static __inline__ int synch_test_bit(int nr, volatile void *addr)
+{
+ int result;
+ result = test_bit(nr, addr);
+ barrier();
+ return result;
+}
+
+#endif /* not assembly */
+
+#endif
diff --git a/extras/mini-os/include/arm/traps.h b/extras/mini-os/include/arm/traps.h
new file mode 100644
index 0000000000..704df22bda
--- /dev/null
+++ b/extras/mini-os/include/arm/traps.h
@@ -0,0 +1,20 @@
+#ifndef _TRAPS_H_
+#define _TRAPS_H_
+
+struct pt_regs {
+ unsigned long r0;
+ unsigned long r1;
+ unsigned long r2;
+ unsigned long r3;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long r11;
+ unsigned long r12;
+};
+
+#endif
diff --git a/extras/mini-os/include/hypervisor.h b/extras/mini-os/include/hypervisor.h
index a62cb78463..21b3566a2e 100644
--- a/extras/mini-os/include/hypervisor.h
+++ b/extras/mini-os/include/hypervisor.h
@@ -18,6 +18,8 @@
#include <hypercall-x86_32.h>
#elif defined(__x86_64__)
#include <hypercall-x86_64.h>
+#elif defined(__arm__) || defined(__aarch64__)
+#include <hypercall-arm.h>
#else
#error "Unsupported architecture"
#endif
diff --git a/extras/mini-os/include/mm.h b/extras/mini-os/include/mm.h
index a177251c4b..f57d8ab9e3 100644
--- a/extras/mini-os/include/mm.h
+++ b/extras/mini-os/include/mm.h
@@ -29,6 +29,8 @@
#include <xen/arch-x86_32.h>
#elif defined(__x86_64__)
#include <xen/arch-x86_64.h>
+#elif defined(__arm__) || defined(__aarch64__)
+#include <xen/arch-arm.h>
#else
#error "Unsupported architecture"
#endif
diff --git a/extras/mini-os/include/types.h b/extras/mini-os/include/types.h
index 93356fe750..be9f1d3d96 100644
--- a/extras/mini-os/include/types.h
+++ b/extras/mini-os/include/types.h
@@ -27,7 +27,7 @@ typedef unsigned char u_char;
typedef unsigned int u_int;
typedef unsigned long u_long;
#endif
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
typedef long long quad_t;
typedef unsigned long long u_quad_t;
#elif defined(__x86_64__)
@@ -39,10 +39,10 @@ typedef unsigned long u_quad_t;
#include <limits.h>
#include <stdint.h>
#else
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
typedef unsigned int uintptr_t;
typedef int intptr_t;
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) || defined(__aarch64__)
typedef unsigned long uintptr_t;
typedef long intptr_t;
#endif /* __i386__ || __x86_64__ */
@@ -52,10 +52,10 @@ typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) || defined(__aarch64__)
typedef signed long int64_t;
typedef unsigned long uint64_t;
#endif