aboutsummaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-02-11 11:34:22 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2005-02-11 11:34:22 +0000
commitec0f4bdc22af71da6c69ddccc3445bc909c2ca6a (patch)
tree57c7c099e7c3f6d5072f31c08b8dedf687a24de1 /extras
parent4e88d35838b90820c4b7bdbf7ba2704ed9cf555f (diff)
downloadxen-ec0f4bdc22af71da6c69ddccc3445bc909c2ca6a.tar.gz
xen-ec0f4bdc22af71da6c69ddccc3445bc909c2ca6a.tar.bz2
xen-ec0f4bdc22af71da6c69ddccc3445bc909c2ca6a.zip
bitkeeper revision 1.1177.1.1 (420c983eSjbjDYGF-fYWrXw_L7qkLA)
Mini-OS cleanups. Bug fixes in x86_64 assembly code. Signed-off-by: keir.fraser@cl.cam.ac.uk
Diffstat (limited to 'extras')
-rw-r--r--extras/mini-os/Makefile42
-rw-r--r--extras/mini-os/h/hypervisor.h73
-rw-r--r--extras/mini-os/h/mm.h4
-rw-r--r--extras/mini-os/h/os.h160
-rw-r--r--extras/mini-os/head.S18
-rw-r--r--extras/mini-os/kernel.c17
-rw-r--r--extras/mini-os/lib/math.c4
-rw-r--r--extras/mini-os/minios-x86_32.lds (renamed from extras/mini-os/minios.lds)0
-rw-r--r--extras/mini-os/minios-x86_64.lds54
-rw-r--r--extras/mini-os/traps.c157
-rw-r--r--extras/mini-os/x86_32.S (renamed from extras/mini-os/entry.S)24
-rw-r--r--extras/mini-os/x86_64.S78
12 files changed, 406 insertions, 225 deletions
diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile
index 606454b6bb..56bc7f9e5f 100644
--- a/extras/mini-os/Makefile
+++ b/extras/mini-os/Makefile
@@ -2,31 +2,44 @@
CC := gcc
LD := ld
-# Linker should relocate monitor to this address
-MONITOR_BASE := 0xE0100000
+TARGET_ARCH := $(shell uname -m | sed -e s/i.86/x86_32/)
# NB. '-Wcast-qual' is nasty, so I omitted it.
-CFLAGS := -fno-builtin -O3 -Wall -Ih/ -Wredundant-decls
-CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline -ansi
+CFLAGS := -fno-builtin -O3 -Wall -Ih/ -Wredundant-decls -Wno-format
+CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
+
+ifeq ($(TARGET_ARCH),x86_32)
+CFLAGS += -m32 -march=i686
+LDFLAGS := -m elf_i386
+endif
+
+ifeq ($(TARGET_ARCH),x86_64)
+CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks
+CFLAGS += -fno-asynchronous-unwind-tables
+LDFLAGS := -m elf_x86_64
+endif
TARGET := mini-os
-LOBJS := lib/malloc.o lib/math.o lib/printf.o lib/string.o
-OBJS := entry.o kernel.o traps.o hypervisor.o mm.o events.o time.o ${LOBJS}
+OBJS := $(TARGET_ARCH).o
+OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
+OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
-HINTF := h/xen-public/xen.h
-HDRS := h/os.h h/types.h h/hypervisor.h h/mm.h h/events.h h/time.h h/lib.h
-HDRS += $(HINTF)
+OBJS := $(subst events.o,,$(OBJS))
+OBJS := $(subst hypervisor.o,,$(OBJS))
+OBJS := $(subst time.o,,$(OBJS))
+
+HDRS := $(wildcard h/*.h)
+HDRS += $(wildcard h/xen-public/*.h)
default: $(TARGET)
xen-public:
- [ -e h/xen-public] || ln -sf ../../../xen/include/public h/xen-public
+ [ -e h/xen-public ] || ln -sf ../../../xen/include/public h/xen-public
-$(TARGET): xen-public head.o $(OBJS)
- $(LD) -N -T minios.lds head.o $(OBJS) -o $@.elf
- objcopy -R .note -R .comment $@.elf $@
- gzip -f -9 -c $@ >$@.gz
+$(TARGET): xen-public $(OBJS)
+ $(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
+ gzip -f -9 -c $@.elf >$@.gz
clean:
find . -type f -name '*.o' | xargs rm -f
@@ -38,4 +51,3 @@ clean:
%.o: %.S $(HDRS) Makefile
$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
-
diff --git a/extras/mini-os/h/hypervisor.h b/extras/mini-os/h/hypervisor.h
index 3a127e1290..fee36d5b9c 100644
--- a/extras/mini-os/h/hypervisor.h
+++ b/extras/mini-os/h/hypervisor.h
@@ -36,13 +36,25 @@ void ack_hypervisor_event(unsigned int ev);
* Assembler stubs for hyper-calls.
*/
+#ifdef __i386__
+#define _a1 "b"
+#define _a2 "c"
+#define _a3 "d"
+#define _a4 "S"
+#else
+#define _a1 "D"
+#define _a2 "S"
+#define _a3 "d"
+#define _a4 "b"
+#endif
+
static __inline__ int HYPERVISOR_set_trap_table(trap_info_t *table)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_set_trap_table),
- "b" (table) : "memory" );
+ _a1 (table) : "memory" );
return ret;
}
@@ -55,7 +67,7 @@ static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req,
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_mmu_update),
- "b" (req), "c" (count), "d" (success_count) : "memory" );
+ _a1 (req), _a2 (count), _a3 (success_count) : "memory" );
return ret;
}
@@ -66,7 +78,7 @@ static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_set_gdt),
- "b" (frame_list), "c" (entries) : "memory" );
+ _a1 (frame_list), _a2 (entries) : "memory" );
return ret;
@@ -78,11 +90,12 @@ static __inline__ int HYPERVISOR_stack_switch(unsigned long ss, unsigned long es
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_stack_switch),
- "b" (ss), "c" (esp) : "memory" );
+ _a1 (ss), _a2 (esp) : "memory" );
return ret;
}
+#ifdef __i386__
static __inline__ int HYPERVISOR_set_callbacks(
unsigned long event_selector, unsigned long event_address,
unsigned long failsafe_selector, unsigned long failsafe_address)
@@ -91,11 +104,27 @@ static __inline__ int HYPERVISOR_set_callbacks(
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
- "b" (event_selector), "c" (event_address),
- "d" (failsafe_selector), "S" (failsafe_address) : "memory" );
+ _a1 (event_selector), _a2 (event_address),
+ _a3 (failsafe_selector), _a4 (failsafe_address) : "memory" );
+
+ return ret;
+}
+#else
+static __inline__ int HYPERVISOR_set_callbacks(
+ unsigned long event_address,
+ unsigned long failsafe_address,
+ unsigned long syscall_address)
+{
+ int ret;
+ __asm__ __volatile__ (
+ TRAP_INSTR
+ : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
+ _a1 (event_address), _a2 (failsafe_address),
+ _a3 (syscall_address) : "memory" );
return ret;
}
+#endif
static __inline__ int HYPERVISOR_fpu_taskswitch(void)
{
@@ -113,7 +142,7 @@ static __inline__ int HYPERVISOR_yield(void)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_yield) : "memory" );
+ _a1 (SCHEDOP_yield) : "memory" );
return ret;
}
@@ -124,7 +153,7 @@ static __inline__ int HYPERVISOR_block(void)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_block) : "memory" );
+ _a1 (SCHEDOP_block) : "memory" );
return ret;
}
@@ -135,7 +164,7 @@ static __inline__ int HYPERVISOR_shutdown(void)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
+ _a1 (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
: "memory" );
return ret;
@@ -147,7 +176,7 @@ static __inline__ int HYPERVISOR_reboot(void)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
+ _a1 (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
: "memory" );
return ret;
@@ -160,7 +189,7 @@ static __inline__ int HYPERVISOR_suspend(unsigned long srec)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
- "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
+ _a1 (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
"S" (srec) : "memory" );
return ret;
@@ -172,7 +201,7 @@ static __inline__ long HYPERVISOR_set_timer_op(void *timer_arg)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_set_timer_op),
- "b" (timer_arg) : "memory" );
+ _a1 (timer_arg) : "memory" );
return ret;
}
@@ -183,7 +212,7 @@ static __inline__ int HYPERVISOR_dom0_op(void *dom0_op)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_dom0_op),
- "b" (dom0_op) : "memory" );
+ _a1 (dom0_op) : "memory" );
return ret;
}
@@ -194,7 +223,7 @@ static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_set_debugreg),
- "b" (reg), "c" (value) : "memory" );
+ _a1 (reg), _a2 (value) : "memory" );
return ret;
}
@@ -205,7 +234,7 @@ static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_get_debugreg),
- "b" (reg) : "memory" );
+ _a1 (reg) : "memory" );
return ret;
}
@@ -217,7 +246,7 @@ static __inline__ int HYPERVISOR_update_descriptor(
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_update_descriptor),
- "b" (pa), "c" (word1), "d" (word2) : "memory" );
+ _a1 (pa), _a2 (word1), _a3 (word2) : "memory" );
return ret;
}
@@ -228,7 +257,7 @@ static __inline__ int HYPERVISOR_set_fast_trap(int idx)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap),
- "b" (idx) : "memory" );
+ _a1 (idx) : "memory" );
return ret;
}
@@ -239,7 +268,7 @@ static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
- "b" (dom_mem_op) : "memory" );
+ _a1 (dom_mem_op) : "memory" );
return ret;
}
@@ -250,7 +279,7 @@ static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_multicall),
- "b" (call_list), "c" (nr_calls) : "memory" );
+ _a1 (call_list), _a2 (nr_calls) : "memory" );
return ret;
}
@@ -262,7 +291,7 @@ static __inline__ int HYPERVISOR_update_va_mapping(
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping),
- "b" (page_nr), "c" (new_val), "d" (flags) : "memory" );
+ _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" );
return ret;
}
@@ -273,7 +302,7 @@ static __inline__ int HYPERVISOR_xen_version(int cmd)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_xen_version),
- "b" (cmd) : "memory" );
+ _a1 (cmd) : "memory" );
return ret;
}
@@ -284,7 +313,7 @@ static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str)
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_console_io),
- "b" (cmd), "c" (count), "d" (str) : "memory" );
+ _a1 (cmd), _a2 (count), _a3 (str) : "memory" );
return ret;
}
diff --git a/extras/mini-os/h/mm.h b/extras/mini-os/h/mm.h
index e12b56495d..5c6224db28 100644
--- a/extras/mini-os/h/mm.h
+++ b/extras/mini-os/h/mm.h
@@ -64,7 +64,11 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine)
return phys;
}
+#ifdef __x86_64__
+#define VIRT_START 0xFFFFFFFF00000000UL
+#else
#define VIRT_START 0xC0000000UL
+#endif
#define to_phys(x) ((unsigned long)(x)-VIRT_START)
#define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START))
diff --git a/extras/mini-os/h/os.h b/extras/mini-os/h/os.h
index cf15d92126..6a0447ca39 100644
--- a/extras/mini-os/h/os.h
+++ b/extras/mini-os/h/os.h
@@ -9,116 +9,108 @@
#define NULL 0
-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
- a mechanism by which the user can annotate likely branch directions and
- expect the blocks to be reordered appropriately. Define __builtin_expect
- to nothing for earlier compilers. */
-
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
#define __builtin_expect(x, expected_value) (x)
#endif
+#define unlikely(x) __builtin_expect((x),0)
-/*
- * These are the segment descriptors provided for us by the hypervisor.
- * For now, these are hardwired -- guest OSes cannot update the GDT
- * or LDT.
- *
- * It shouldn't be hard to support descriptor-table frobbing -- let me
- * know if the BSD or XP ports require flexibility here.
- */
-
+#define smp_processor_id() 0
+#define preempt_disable() ((void)0)
+#define preempt_enable() ((void)0)
-/*
- * these are also defined in xen-public/xen.h but can't be pulled in as
- * they are used in start of day assembly. Need to clean up the .h files
- * a bit more...
- */
+#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0))
-#ifndef FLAT_RING1_CS
-#define FLAT_RING1_CS 0x0819
-#define FLAT_RING1_DS 0x0821
-#define FLAT_RING3_CS 0x082b
-#define FLAT_RING3_DS 0x0833
+#ifndef __ASSEMBLY__
+#include <types.h>
#endif
+#include <xen-public/xen.h>
-#define __KERNEL_CS FLAT_RING1_CS
-#define __KERNEL_DS FLAT_RING1_DS
+#define __KERNEL_CS FLAT_KERNEL_CS
+#define __KERNEL_DS FLAT_KERNEL_DS
+#define __KERNEL_SS FLAT_KERNEL_SS
/* Everything below this point is not included by assembler (.S) files. */
#ifndef __ASSEMBLY__
-#include <types.h>
-#include <xen-public/xen.h>
+#define pt_regs xen_regs
-
-/* this struct defines the way the registers are stored on the
- stack during an exception or interrupt. */
-struct pt_regs {
- long ebx;
- long ecx;
- long edx;
- long esi;
- long edi;
- long ebp;
- long eax;
- int xds;
- int xes;
- long orig_eax;
- long eip;
- int xcs;
- long eflags;
- long esp;
- int xss;
-};
-
-/* some function prototypes */
void trap_init(void);
void dump_regs(struct pt_regs *regs);
-
-/*
- * STI/CLI equivalents. These basically set and clear the virtual
- * event_enable flag in teh shared_info structure. Note that when
- * the enable bit is set, there may be pending events to be handled.
- * We may therefore call into do_hypervisor_callback() directly.
+/*
+ * The use of 'barrier' in the following reflects their use as local-lock
+ * operations. Reentrancy must be prevented (e.g., __cli()) /before/ following
+ * critical operations are executed. All critical operations must complete
+ * /before/ reentrancy is permitted (e.g., __sti()). Alpha architecture also
+ * includes these barriers, for example.
*/
-#define unlikely(x) __builtin_expect((x),0)
-#define __save_flags(x) \
-do { \
- (x) = test_bit(EVENTS_MASTER_ENABLE_BIT, \
- &HYPERVISOR_shared_info->events_mask); \
- barrier(); \
+
+#define __cli() \
+do { \
+ vcpu_info_t *_vcpu; \
+ preempt_disable(); \
+ _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+ _vcpu->evtchn_upcall_mask = 1; \
+ preempt_enable_no_resched(); \
+ barrier(); \
+} while (0)
+
+#define __sti() \
+do { \
+ vcpu_info_t *_vcpu; \
+ barrier(); \
+ preempt_disable(); \
+ _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+ _vcpu->evtchn_upcall_mask = 0; \
+ barrier(); /* unmask then check (avoid races) */ \
+ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
+ force_evtchn_callback(); \
+ preempt_enable(); \
} while (0)
-#define __restore_flags(x) \
-do { \
- shared_info_t *_shared = HYPERVISOR_shared_info; \
- if (x) set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \
- barrier(); \
- if ( unlikely(_shared->events) && (x) ) do_hypervisor_callback(NULL); \
+#define __save_flags(x) \
+do { \
+ vcpu_info_t *_vcpu; \
+ _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+ (x) = _vcpu->evtchn_upcall_mask; \
} while (0)
-#define __cli() \
-do { \
- clear_bit(EVENTS_MASTER_ENABLE_BIT, &HYPERVISOR_shared_info->events_mask);\
- barrier(); \
+#define __restore_flags(x) \
+do { \
+ vcpu_info_t *_vcpu; \
+ barrier(); \
+ preempt_disable(); \
+ _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+ if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
+ barrier(); /* unmask then check (avoid races) */ \
+ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
+ force_evtchn_callback(); \
+ preempt_enable(); \
+ } else \
+ preempt_enable_no_resched(); \
} while (0)
-#define __sti() \
-do { \
- shared_info_t *_shared = HYPERVISOR_shared_info; \
- set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \
- barrier(); \
- if ( unlikely(_shared->events) ) do_hypervisor_callback(NULL); \
+#define safe_halt() ((void)0)
+
+#define __save_and_cli(x) \
+do { \
+ vcpu_info_t *_vcpu; \
+ preempt_disable(); \
+ _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+ (x) = _vcpu->evtchn_upcall_mask; \
+ _vcpu->evtchn_upcall_mask = 1; \
+ preempt_enable_no_resched(); \
+ barrier(); \
} while (0)
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(x) __save_and_cli(x)
-#define save_and_sti(x) __save_and_sti(x)
+#define local_irq_save(x) __save_and_cli(x)
+#define local_irq_restore(x) __restore_flags(x)
+#define local_save_flags(x) __save_flags(x)
+#define local_irq_disable() __cli()
+#define local_irq_enable() __sti()
+#define irqs_disabled() \
+ HYPERVISOR_shared_info->vcpu_data[smp_processor_id()].evtchn_upcall_mask
/* This is a barrier for the compiler only, NOT the processor! */
#define barrier() __asm__ __volatile__("": : :"memory")
diff --git a/extras/mini-os/head.S b/extras/mini-os/head.S
deleted file mode 100644
index 52eae8f818..0000000000
--- a/extras/mini-os/head.S
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <os.h>
-
-.globl _start, shared_info
-
-_start:
- cld
- lss stack_start,%esp
- push %esi
- call start_kernel
-
-stack_start:
- .long stack+8192, __KERNEL_DS
-
- /* Unpleasant -- the PTE that maps this page is actually overwritten */
- /* to map the real shared-info page! :-) */
- .org 0x1000
-shared_info:
- .org 0x2000
diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c
index a9f423c192..a794145e68 100644
--- a/extras/mini-os/kernel.c
+++ b/extras/mini-os/kernel.c
@@ -64,8 +64,8 @@ extern char shared_info[PAGE_SIZE];
static shared_info_t *map_shared_info(unsigned long pa)
{
- if ( HYPERVISOR_update_va_mapping((unsigned long)shared_info >> PAGE_SHIFT,
- pa | 3, UVMF_INVLPG) )
+ if ( HYPERVISOR_update_va_mapping(
+ (unsigned long)shared_info, pa | 3, UVMF_INVLPG) )
{
printk("Failed to map shared_info!!\n");
*(int*)0=0;
@@ -79,6 +79,9 @@ static shared_info_t *map_shared_info(unsigned long pa)
*/
void start_kernel(start_info_t *si)
{
+ static char hello[] = "Bootstrapping...\n";
+ (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
+
/* Copy the start_info struct to a globally-accessible area. */
memcpy(&start_info, si, sizeof(*si));
@@ -86,9 +89,15 @@ void start_kernel(start_info_t *si)
HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);
/* Set up event and failsafe callback addresses. */
+#ifdef __i386__
HYPERVISOR_set_callbacks(
__KERNEL_CS, (unsigned long)hypervisor_callback,
__KERNEL_CS, (unsigned long)failsafe_callback);
+#else
+ HYPERVISOR_set_callbacks(
+ (unsigned long)hypervisor_callback,
+ (unsigned long)failsafe_callback, 0);
+#endif
trap_init();
@@ -117,7 +126,7 @@ void start_kernel(start_info_t *si)
init_mm();
/* set up events */
- init_events();
+// init_events();
/*
* These need to be replaced with event-channel/control-interface
@@ -135,7 +144,7 @@ void start_kernel(start_info_t *si)
#endif
/* init time and timers */
- init_time();
+// init_time();
/* do nothing */
for ( ; ; ) HYPERVISOR_yield();
diff --git a/extras/mini-os/lib/math.c b/extras/mini-os/lib/math.c
index be08740965..8e97be6d18 100644
--- a/extras/mini-os/lib/math.c
+++ b/extras/mini-os/lib/math.c
@@ -96,14 +96,14 @@ union uu {
* (sizeof(long)*CHAR_BIT/2).
*/
#define HHALF(x) ((x) >> HALF_BITS)
-#define LHALF(x) ((x) & ((1 << HALF_BITS) - 1))
+#define LHALF(x) ((x) & ((1UL << HALF_BITS) - 1))
#define LHUP(x) ((x) << HALF_BITS)
/*
* Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
* section 4.3.1, pp. 257--259.
*/
-#define B (1 << HALF_BITS) /* digit base */
+#define B (1UL << HALF_BITS) /* digit base */
/* Combine two `digits' to make a single two-digit number. */
#define COMBINE(a, b) (((u_long)(a) << HALF_BITS) | (b))
diff --git a/extras/mini-os/minios.lds b/extras/mini-os/minios-x86_32.lds
index a53504e9a2..a53504e9a2 100644
--- a/extras/mini-os/minios.lds
+++ b/extras/mini-os/minios-x86_32.lds
diff --git a/extras/mini-os/minios-x86_64.lds b/extras/mini-os/minios-x86_64.lds
new file mode 100644
index 0000000000..71b61131b8
--- /dev/null
+++ b/extras/mini-os/minios-x86_64.lds
@@ -0,0 +1,54 @@
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0xFFFFFFFF00000000;
+ _text = .; /* Text and read-only data */
+ .text : {
+ *(.text)
+ *(.gnu.warning)
+ } = 0x9090
+
+ _etext = .; /* End of text section */
+
+ .rodata : { *(.rodata) *(.rodata.*) }
+
+ .data : { /* Data */
+ *(.data)
+ CONSTRUCTORS
+ }
+
+ _edata = .; /* End of data section */
+
+ . = ALIGN(8192); /* init_task */
+ .data.init_task : { *(.data.init_task) }
+
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ __bss_start = .; /* BSS */
+ .bss : {
+ *(.bss)
+ }
+ _end = . ;
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.text.exit)
+ *(.data.exit)
+ *(.exitcall.exit)
+ }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
diff --git a/extras/mini-os/traps.c b/extras/mini-os/traps.c
index c0ef335025..858c54d3f2 100644
--- a/extras/mini-os/traps.c
+++ b/extras/mini-os/traps.c
@@ -33,38 +33,38 @@ extern void do_exit(void);
void dump_regs(struct pt_regs *regs)
{
- int in_kernel = 1;
- unsigned long esp;
- unsigned short ss;
-
- esp = (unsigned long) (&regs->esp);
- ss = __KERNEL_DS;
- if (regs->xcs & 2) {
- in_kernel = 0;
- esp = regs->esp;
- ss = regs->xss & 0xffff;
- }
- printf("EIP: %04x:[<%08lx>]\n",
- 0xffff & regs->xcs, regs->eip);
- printf("EFLAGS: %08lx\n",regs->eflags);
- printf("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
- regs->eax, regs->ebx, regs->ecx, regs->edx);
- printf("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
- regs->esi, regs->edi, regs->ebp, esp);
- printf("ds: %04x es: %04x ss: %04x\n",
- regs->xds & 0xffff, regs->xes & 0xffff, ss);
- printf("\n");
+ int in_kernel = 1;
+ unsigned long esp;
+ unsigned short ss;
+
+ esp = (unsigned long) (&regs->esp);
+ ss = __KERNEL_DS;
+ if (regs->cs & 2) {
+ in_kernel = 0;
+ esp = regs->esp;
+ ss = regs->ss & 0xffff;
+ }
+ printf("EIP: %04x:[<%p>]\n",
+ 0xffff & regs->cs , regs->eip);
+ printf("EFLAGS: %p\n",regs->eflags);
+ printf("eax: %p ebx: %p ecx: %p edx: %p\n",
+ regs->eax, regs->ebx, regs->ecx, regs->edx);
+ printf("esi: %p edi: %p ebp: %p esp: %p\n",
+ regs->esi, regs->edi, regs->ebp, esp);
+ printf("ds: %04x es: %04x ss: %04x\n",
+ regs->ds & 0xffff, regs->es & 0xffff, ss);
+ printf("\n");
}
-static __inline__ void dump_code(unsigned eip)
+static __inline__ void dump_code(unsigned long eip)
{
- unsigned *ptr = (unsigned *)eip;
- int x;
-
- printk("Bytes at eip:\n");
- for (x = -4; x < 5; x++)
- printf("%x", ptr[x]);
+ unsigned *ptr = (unsigned *)eip;
+ int x;
+
+ printk("Bytes at eip:\n");
+ for (x = -4; x < 5; x++)
+ printf("%p", ptr[x]);
}
@@ -81,14 +81,14 @@ static __inline__ void dump_code(unsigned eip)
*/
static void __inline__ do_trap(int trapnr, char *str,
- struct pt_regs * regs, long error_code)
+ struct pt_regs * regs, long error_code)
{
- printk("FATAL: Unhandled Trap (see mini-os:traps.c)");
- printf("%d %s", trapnr, str);
- dump_regs(regs);
- dump_code(regs->eip);
+ printk("FATAL: Unhandled Trap (see mini-os:traps.c)");
+ printf("%d %s", trapnr, str);
+ dump_regs(regs);
+ dump_code(regs->eip);
- do_exit();
+ do_exit();
}
#define DO_ERROR(trapnr, str, name) \
@@ -104,38 +104,36 @@ void do_##name(struct pt_regs * regs, long error_code) \
}
DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
-DO_ERROR( 3, "int3", int3)
-DO_ERROR( 4, "overflow", overflow)
-DO_ERROR( 5, "bounds", bounds)
-DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
-DO_ERROR( 7, "device not available", device_not_available)
-DO_ERROR( 8, "double fault", double_fault)
-DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
-DO_ERROR(10, "invalid TSS", invalid_TSS)
-DO_ERROR(11, "segment not present", segment_not_present)
-DO_ERROR(12, "stack segment", stack_segment)
-DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR(18, "machine check", machine_check)
-
-void do_page_fault(struct pt_regs *regs, long error_code,
- unsigned long address)
+ DO_ERROR( 3, "int3", int3)
+ DO_ERROR( 4, "overflow", overflow)
+ DO_ERROR( 5, "bounds", bounds)
+ DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
+ DO_ERROR( 7, "device not available", device_not_available)
+ DO_ERROR( 8, "double fault", double_fault)
+ DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
+ DO_ERROR(10, "invalid TSS", invalid_TSS)
+ DO_ERROR(11, "segment not present", segment_not_present)
+ DO_ERROR(12, "stack segment", stack_segment)
+ DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
+ DO_ERROR(18, "machine check", machine_check)
+
+ void do_page_fault(struct pt_regs *regs, long error_code,
+ unsigned long address)
{
printk("Page fault\n");
- printk("Address: 0x%lx", address);
- printk("Error Code: 0x%lx", error_code);
- printk("eip: \t 0x%lx", regs->eip);
+ printk("Address: 0x%p", address);
+ printk("Error Code: 0x%p", error_code);
+ printk("eip: \t 0x%p", regs->eip);
do_exit();
}
void do_general_protection(struct pt_regs * regs, long error_code)
{
-
- HYPERVISOR_shared_info->events_mask = 0;
- printk("GPF\n");
- printk("Error Code: 0x%lx", error_code);
- dump_regs(regs);
- dump_code(regs->eip);
- do_exit();
+ printk("GPF\n");
+ printk("Error Code: 0x%p", error_code);
+ dump_regs(regs);
+ dump_code(regs->eip);
+ do_exit();
}
@@ -180,26 +178,29 @@ void do_spurious_interrupt_bug(struct pt_regs * regs,
* The 'privilege ring' field specifies the least-privileged ring that
* can trap to that vector using a software-interrupt instruction (INT).
*/
+#ifdef __x86_64__
+#define _P 0,
+#endif
static trap_info_t trap_table[] = {
- { 0, 0, __KERNEL_CS, (unsigned long)divide_error },
- { 1, 0, __KERNEL_CS, (unsigned long)debug },
- { 3, 3, __KERNEL_CS, (unsigned long)int3 },
- { 4, 3, __KERNEL_CS, (unsigned long)overflow },
- { 5, 3, __KERNEL_CS, (unsigned long)bounds },
- { 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
- { 7, 0, __KERNEL_CS, (unsigned long)device_not_available },
- { 8, 0, __KERNEL_CS, (unsigned long)double_fault },
- { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
- { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
- { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
- { 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
- { 13, 0, __KERNEL_CS, (unsigned long)general_protection },
- { 14, 0, __KERNEL_CS, (unsigned long)page_fault },
- { 15, 0, __KERNEL_CS, (unsigned long)spurious_interrupt_bug },
- { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
- { 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
- { 18, 0, __KERNEL_CS, (unsigned long)machine_check },
- { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
+ { 0, 0, __KERNEL_CS, _P (unsigned long)divide_error },
+ { 1, 0, __KERNEL_CS, _P (unsigned long)debug },
+ { 3, 3, __KERNEL_CS, _P (unsigned long)int3 },
+ { 4, 3, __KERNEL_CS, _P (unsigned long)overflow },
+ { 5, 3, __KERNEL_CS, _P (unsigned long)bounds },
+ { 6, 0, __KERNEL_CS, _P (unsigned long)invalid_op },
+ { 7, 0, __KERNEL_CS, _P (unsigned long)device_not_available },
+ { 8, 0, __KERNEL_CS, _P (unsigned long)double_fault },
+ { 9, 0, __KERNEL_CS, _P (unsigned long)coprocessor_segment_overrun },
+ { 10, 0, __KERNEL_CS, _P (unsigned long)invalid_TSS },
+ { 11, 0, __KERNEL_CS, _P (unsigned long)segment_not_present },
+ { 12, 0, __KERNEL_CS, _P (unsigned long)stack_segment },
+ { 13, 0, __KERNEL_CS, _P (unsigned long)general_protection },
+ { 14, 0, __KERNEL_CS, _P (unsigned long)page_fault },
+ { 15, 0, __KERNEL_CS, _P (unsigned long)spurious_interrupt_bug },
+ { 16, 0, __KERNEL_CS, _P (unsigned long)coprocessor_error },
+ { 17, 0, __KERNEL_CS, _P (unsigned long)alignment_check },
+ { 18, 0, __KERNEL_CS, _P (unsigned long)machine_check },
+ { 19, 0, __KERNEL_CS, _P (unsigned long)simd_coprocessor_error },
{ 0, 0, 0, 0 }
};
diff --git a/extras/mini-os/entry.S b/extras/mini-os/x86_32.S
index 8565caf745..d193b121bd 100644
--- a/extras/mini-os/entry.S
+++ b/extras/mini-os/x86_32.S
@@ -1,6 +1,26 @@
-
#include <os.h>
+.section __xen_guest
+ .asciz "XEN_VER=2.0,LOADER=generic,PT_MODE_WRITABLE"
+.text
+
+.globl _start, shared_info
+
+_start:
+ cld
+ lss stack_start,%esp
+ push %esi
+ call start_kernel
+
+stack_start:
+ .long stack+8192, __KERNEL_SS
+
+ /* Unpleasant -- the PTE that maps this page is actually overwritten */
+ /* to map the real shared-info page! :-) */
+ .org 0x1000
+shared_info:
+ .org 0x2000
+
ES = 0x20
ORIG_EAX = 0x24
EIP = 0x28
@@ -92,7 +112,7 @@ ENTRY(hypervisor_callback)
cmpl $ecrit,%eax
jb critical_region_fixup
11: push %esp
- call do_hypervisor_callback
+# call do_hypervisor_callback
add $4,%esp
movl HYPERVISOR_shared_info,%esi
xorl %eax,%eax
diff --git a/extras/mini-os/x86_64.S b/extras/mini-os/x86_64.S
new file mode 100644
index 0000000000..4a4708ddd5
--- /dev/null
+++ b/extras/mini-os/x86_64.S
@@ -0,0 +1,78 @@
+#include <os.h>
+
+.section __xen_guest
+ .asciz "XEN_VER=2.0,LOADER=generic,PT_MODE_WRITABLE"
+.text
+
+#define ENTRY(X) .globl X ; X :
+.globl _start, shared_info
+
+_start:
+ cld
+ movq stack_start(%rip),%rsp
+ movq %rsi,%rdi
+ call start_kernel
+
+stack_start:
+ .quad stack+8192
+
+ /* Unpleasant -- the PTE that maps this page is actually overwritten */
+ /* to map the real shared-info page! :-) */
+ .org 0x1000
+shared_info:
+ .org 0x2000
+
+ENTRY(hypervisor_callback)
+
+ENTRY(failsafe_callback)
+ iret
+
+ENTRY(divide_error)
+ pushq $0
+
+ENTRY(coprocessor_error)
+ pushq $0
+
+ENTRY(simd_coprocessor_error)
+ pushq $0
+
+ENTRY(device_not_available)
+ iret
+
+ENTRY(debug)
+ pushq $0
+
+ENTRY(int3)
+ pushq $0
+
+ENTRY(overflow)
+ pushq $0
+
+ENTRY(bounds)
+ pushq $0
+
+ENTRY(invalid_op)
+ pushq $0
+
+ENTRY(coprocessor_segment_overrun)
+ pushq $0
+
+ENTRY(double_fault)
+
+ENTRY(invalid_TSS)
+
+ENTRY(segment_not_present)
+
+ENTRY(stack_segment)
+
+ENTRY(general_protection)
+
+ENTRY(alignment_check)
+
+ENTRY(page_fault)
+
+ENTRY(machine_check)
+ pushq $0
+
+ENTRY(spurious_interrupt_bug)
+ pushq $0