[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Mini-os updates from Grzegorz Milos.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 189c87adf876df8ed7b84afb5ac69e09465cdaf1 # Parent 287583627544a984c89ff5ec6b44ec2c73187838 Mini-os updates from Grzegorz Milos. diff -r 287583627544 -r 189c87adf876 extras/mini-os/Makefile --- a/extras/mini-os/Makefile Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/Makefile Wed Jul 6 10:46:29 2005 @@ -1,11 +1,12 @@ +debug ?= y -CC := gcc -LD := ld +include $(CURDIR)/../../Config.mk -TARGET_ARCH := $(shell uname -m | sed -e s/i.86/x86_32/) +# Set TARGET_ARCH +override TARGET_ARCH := $(XEN_TARGET_ARCH) # NB. '-Wcast-qual' is nasty, so I omitted it. -CFLAGS := -fno-builtin -O3 -Wall -Ih/ -Wredundant-decls -Wno-format +CFLAGS := -fno-builtin -Wall -Werror -Iinclude/ -Wredundant-decls -Wno-format CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline ifeq ($(TARGET_ARCH),x86_32) @@ -19,23 +20,25 @@ LDFLAGS := -m elf_x86_64 endif +ifeq ($(debug),y) +CFLAGS += -g +else +CFLAGS += -O3 +endif + TARGET := mini-os OBJS := $(TARGET_ARCH).o OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c)) -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) +HDRS := $(wildcard include/*.h) +HDRS += $(wildcard include/xen/*.h) default: $(TARGET) xen-public: - [ -e h/xen-public ] || ln -sf ../../../xen/include/public h/xen-public + [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen $(TARGET): xen-public $(OBJS) $(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf @@ -51,3 +54,4 @@ %.o: %.S $(HDRS) Makefile $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@ + diff -r 287583627544 -r 189c87adf876 extras/mini-os/traps.c --- a/extras/mini-os/traps.c Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/traps.c Wed Jul 6 10:46:29 2005 @@ -1,5 +1,6 @@ #include <os.h> +#include <traps.h> #include <hypervisor.h> #include <mm.h> #include <lib.h> @@ -37,21 +38,22 @@ #ifdef __x86_64__ esp = regs->rsp; - ss = regs->ss; + ss = regs->xss; #else esp = (unsigned long) (®s->esp); ss = __KERNEL_DS; - if (regs->cs & 2) { + if (regs->xcs & 2) { +printk("CS is true, esp is %x\n", regs->esp); esp = regs->esp; - ss = regs->ss & 0xffff; + ss = regs->xss & 0xffff; } #endif - printf("EIP: %04x:[<%p>] %08x\n", - 0xffff & regs->cs , regs->eip, regs->error_code); + printf("EIP: %04x:[<%p>]\n", + 0xffff & regs->xcs , regs->eip); printf("EFLAGS: %p\n",regs->eflags); - printf("eax: %p ebx: %p ecx: %p edx: %p\n", + printf("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); - printf("esi: %p edi: %p ebp: %p esp: %p\n", + printf("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", regs->esi, regs->edi, regs->ebp, esp); #ifdef __x86_64__ printf("r8 : %p r9 : %p r10: %p r11: %p\n", @@ -60,40 +62,28 @@ regs->r12, regs->r13, regs->r14, regs->r15); #endif printf("ds: %04x es: %04x ss: %04x\n", - regs->ds & 0xffff, regs->es & 0xffff, ss); + regs->xds & 0xffff, regs->xes & 0xffff, ss); } -static __inline__ void dump_code(unsigned long eip) -{ - unsigned char *ptr = (unsigned char *)eip; - int x; - - printk("Bytes at eip: "); - for ( x = -4; x < 5; x++ ) - printf("%02x ", ptr[x]); - printk("\n"); -} - -static void __inline__ do_trap(int trapnr, char *str, - struct pt_regs * regs) -{ - printk("FATAL: Unhandled Trap %d (%s)\n", trapnr, str); - dump_regs(regs); - dump_code(regs->eip); +static void do_trap(int trapnr, char *str, struct pt_regs * regs, unsigned long error_code) +{ + printk("FATAL: Unhandled Trap %d (%s), error code=0x%lx\n", trapnr, str, error_code); + printk("Regs address %p\n", regs); + dump_regs(regs); do_exit(); } #define DO_ERROR(trapnr, str, name) \ -void do_##name(struct pt_regs * regs) \ +void do_##name(struct pt_regs * regs, unsigned long error_code) \ { \ - do_trap(trapnr, str, regs); \ + do_trap(trapnr, str, regs, error_code); \ } #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \ -void do_##name(struct pt_regs * regs) \ +void do_##name(struct pt_regs * regs, unsigned long error_code) \ { \ - do_trap(trapnr, str, regs); \ + do_trap(trapnr, str, regs, error_code); \ } DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip) @@ -109,13 +99,11 @@ DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0) DO_ERROR(18, "machine check", machine_check) -extern unsigned long virt_cr2; -void do_page_fault(struct pt_regs *regs) -{ - unsigned long addr = virt_cr2; +void do_page_fault(struct pt_regs *regs, unsigned long error_code, + unsigned long addr) +{ printk("Page fault at linear address %p\n", addr); dump_regs(regs); - dump_code(regs->eip); #ifdef __x86_64__ { unsigned long *tab = (unsigned long *)start_info.pt_base; @@ -126,35 +114,33 @@ page = tab[l4_table_offset(addr)]; tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); printk(" L4 = %p (%p)\n", page, tab); - if ( !(page & _PAGE_PRESENT) ) + if ( !(page & AGERESENT) ) goto out; page = tab[l3_table_offset(addr)]; tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); printk(" L3 = %p (%p)\n", page, tab); - if ( !(page & _PAGE_PRESENT) ) + if ( !(page & AGERESENT) ) goto out; page = tab[l2_table_offset(addr)]; tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); printk(" L2 = %p (%p) %s\n", page, tab, - (page & _PAGE_PSE) ? "(2MB)" : ""); - if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) ) + (page & AGESE) ? "(2MB)" : ""); + if ( !(page & AGERESENT) || (page & AGESE) ) goto out; page = tab[l1_table_offset(addr)]; printk(" L1 = %p\n", page); } #endif - out: - do_exit(); -} - -void do_general_protection(struct pt_regs *regs) -{ - printk("GPF\n"); - dump_regs(regs); - dump_code(regs->eip); + do_exit(); +} + +void do_general_protection(struct pt_regs *regs, long error_code) +{ + printk("GPF %p, error_code=%lx\n", regs, error_code); + dump_regs(regs); do_exit(); } @@ -172,7 +158,6 @@ { printk("Copro error\n"); dump_regs(regs); - dump_code(regs->eip); do_exit(); } @@ -196,28 +181,25 @@ * 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, _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 }, - { 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, __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 }, + { 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, 0, 0 } }; @@ -227,3 +209,4 @@ { HYPERVISOR_set_trap_table(trap_table); } + diff -r 287583627544 -r 189c87adf876 extras/mini-os/time.c --- a/extras/mini-os/time.c Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/time.c Wed Jul 6 10:46:29 2005 @@ -2,10 +2,12 @@ **************************************************************************** * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge * (C) 2002-2003 - Keir Fraser - University of Cambridge + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge **************************************************************************** * * File: time.c * Author: Rolf Neugebauer and Keir Fraser + * Changes: Grzegorz Milos * * Description: Simple time and timer functions * @@ -30,6 +32,7 @@ #include <os.h> +#include <traps.h> #include <types.h> #include <hypervisor.h> #include <events.h> @@ -40,9 +43,13 @@ * Time functions *************************************************************************/ -static unsigned int rdtsc_bitshift; -static u32 st_scale_f; /* convert ticks -> usecs */ -static u32 st_scale_i; /* convert ticks -> usecs */ +/* Cached *multiplier* to convert TSC counts to microseconds. + * (see the equation below). + * Equal to 2^32 * (1 / (clocks per usec) ). + * Initialized in time_init. + */ +static unsigned long fast_gettimeoffset_quotient; + /* These are peridically updated in shared_info, and then copied here. */ static u32 shadow_tsc_stamp; @@ -70,7 +77,7 @@ rmb(); shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec; shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec; - shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp.tsc_bits; + shadow_tsc_stamp = (u32)HYPERVISOR_shared_info->tsc_timestamp; shadow_system_time = HYPERVISOR_shared_info->system_time; rmb(); } @@ -81,22 +88,33 @@ #define TIME_VALUES_UP_TO_DATE \ (shadow_time_version == HYPERVISOR_shared_info->time_version2) - -static __inline__ unsigned long get_time_delta_usecs(void) -{ - s32 delta_tsc; - u32 low; - u64 delta, tsc; - - rdtscll(tsc); - low = (u32)(tsc >> rdtsc_bitshift); - delta_tsc = (s32)(low - shadow_tsc_stamp); - if ( unlikely(delta_tsc < 0) ) delta_tsc = 0; - delta = ((u64)delta_tsc * st_scale_f); - delta >>= 32; - delta += ((u64)delta_tsc * st_scale_i); - - return (unsigned long)delta; +static u32 get_time_delta_usecs(void) +{ + register unsigned long eax, edx; + + /* Read the Time Stamp Counter */ + + rdtsc(eax,edx); + + /* .. relative to previous jiffy (32 bits is enough) */ + eax -= shadow_tsc_stamp; + + /* + * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient + * = (tsc_low delta) * (usecs_per_clock) + * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) + * + * Using a mull instead of a divl saves up to 31 clock cycles + * in the critical path. + */ + + __asm__("mull %2" + :"=a" (eax), "=d" (edx) + :"rm" (fast_gettimeoffset_quotient), + "0" (eax)); + + /* our adjusted time offset in microseconds */ + return edx; } s64 get_s_time (void) @@ -139,6 +157,25 @@ *tv = _tv; } +static void print_current_time(void) +{ + struct timeval tv; + + get_time_values_from_xen(); + + gettimeofday(&tv); + printk("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); +} + +void block(u32 millisecs) +{ + struct timeval tv; + gettimeofday(&tv); + //printk("tv.tv_sec=%ld, tv.tv_usec=%ld, shadow_system_time=%lld\n", tv.tv_sec, tv.tv_usec, shadow_system_time ); + HYPERVISOR_set_timer_op(get_s_time() + 1000000LL * (s64) millisecs); + HYPERVISOR_block(); +} + /* * Just a dummy @@ -146,41 +183,38 @@ static void timer_handler(int ev, struct pt_regs *regs) { static int i; - struct timeval tv; get_time_values_from_xen(); i++; if (i >= 1000) { - gettimeofday(&tv); - printf("T(s=%ld us=%ld)\n", tv.tv_sec, tv.tv_usec); + print_current_time(); i = 0; } } + void init_time(void) { - u64 __cpu_khz, cpu_freq, scale; + u64 __cpu_khz; unsigned long cpu_khz; __cpu_khz = HYPERVISOR_shared_info->cpu_freq; + cpu_khz = (u32) (__cpu_khz/1000); - - rdtsc_bitshift = HYPERVISOR_shared_info->tsc_timestamp.tsc_bitshift; - cpu_freq = HYPERVISOR_shared_info->cpu_freq; - - scale = 1000000LL << (32 + rdtsc_bitshift); - scale /= cpu_freq; - - st_scale_f = scale & 0xffffffff; - st_scale_i = scale >> 32; printk("Xen reported: %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); - - add_ev_action(EV_TIMER, &timer_handler); - enable_ev_action(EV_TIMER); - enable_hypervisor_event(EV_TIMER); - -} + /* (10^6 * 2^32) / cpu_hz = (10^3 * 2^32) / cpu_khz = + (2^32 * 1 / (clocks/us)) */ + { + unsigned long eax=0, edx=1000; + __asm__("divl %2" + :"=a" (fast_gettimeoffset_quotient), "=d" (edx) + :"r" (cpu_khz), + "0" (eax), "1" (edx)); + } + + bind_virq(VIRQ_TIMER, &timer_handler); +} diff -r 287583627544 -r 189c87adf876 extras/mini-os/x86_32.S --- a/extras/mini-os/x86_32.S Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/x86_32.S Wed Jul 6 10:46:29 2005 @@ -1,4 +1,6 @@ #include <os.h> +#include <xen/arch-x86_32.h> + .section __xen_guest .asciz "XEN_VER=3.0,LOADER=generic,PT_MODE_WRITABLE" @@ -21,6 +23,7 @@ shared_info: .org 0x2000 + ES = 0x20 ORIG_EAX = 0x24 EIP = 0x28 @@ -61,6 +64,31 @@ pushl $do_divide_error do_exception: pushl %ds + pushl %eax + xorl %eax, %eax + pushl %ebp + pushl %edi + pushl %esi + pushl %edx + decl %eax # eax = -1 + pushl %ecx + pushl %ebx + cld + movl %es, %ecx + movl ES(%esp), %edi # get the function address + movl ORIG_EAX(%esp), %edx # get the error code + movl %eax, ORIG_EAX(%esp) + movl %ecx, ES(%esp) + movl $(__KERNEL_DS), %ecx + movl %ecx, %ds + movl %ecx, %es + movl %esp,%eax # pt_regs pointer + pushl %edx + pushl %eax + call *%edi + addl $8,%esp + +/* pushl %ds pushl %eax xorl %eax,%eax pushl %ebp @@ -83,7 +111,7 @@ movl %edx,%ds movl %edx,%es call *%edi - addl $8,%esp + addl $8,%esp */ ret_from_exception: @@ -112,19 +140,19 @@ 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 movb CS(%esp),%cl test $2,%cl # slow return to ring 2 or 3 jne safesti -safesti:btsl $31,4(%esi) # reenable event callbacks +safesti:movb $0,1(%esi) # reenable event callbacks scrit: /**** START OF CRITICAL REGION ****/ - cmpl %eax,(%esi) - jne 14f # process more events if necessary... + testb $0xFF,(%esi) + jnz 14f # process more events if necessary... RESTORE_ALL -14: btrl %eax,4(%esi) +14: movb $1,1(%esi) jmp 11b ecrit: /**** END OF CRITICAL REGION ****/ # [How we do the fixup]. We want to merge the current stack frame with the @@ -153,7 +181,7 @@ jmp 11b critical_fixup_table: - .byte 0x00,0x00 # cmpl %eax,(%esi) + .byte 0x00,0x00,0x00 # testb $0xff,(%esi) .byte 0x00,0x00 # jne 14f .byte 0x00 # pop %ebx .byte 0x04 # pop %ecx @@ -166,7 +194,7 @@ .byte 0x20 # pop %es .byte 0x24,0x24,0x24 # add $4,%esp .byte 0x28 # iret - .byte 0x00,0x00,0x00,0x00,0x00 # btrl $31,4(%esi) + .byte 0x00,0x00,0x00,0x00 # movb $1,1(%esi) .byte 0x00,0x00 # jmp 11b # Hypervisor uses this for application faults while it executes. @@ -220,10 +248,6 @@ pushl $do_coprocessor_segment_overrun jmp do_exception -ENTRY(double_fault) - pushl $do_double_fault - jmp do_exception - ENTRY(invalid_TSS) pushl $do_invalid_TSS jmp do_exception @@ -246,32 +270,30 @@ # This handler is special, because it gets an extra value on its stack, # which is the linear faulting address. +# fastcall register usage: %eax = pt_regs, %edx = error code, +# %ecx = fault address ENTRY(page_fault) pushl %ds pushl %eax - xorl %eax,%eax + xorl %eax, %eax pushl %ebp pushl %edi pushl %esi pushl %edx - decl %eax # eax = -1 + decl %eax /* eax = -1 */ pushl %ecx pushl %ebx cld - movl %es,%ecx - movl ORIG_EAX(%esp), %esi # get the error code - movl ES(%esp), %edi # get the faulting address + movl %es,%edi + movl ES(%esp), %ecx /* get the faulting address */ + movl ORIG_EAX(%esp), %edx /* get the error code */ movl %eax, ORIG_EAX(%esp) - movl %ecx, ES(%esp) - movl %esp,%edx - pushl %edi # push the faulting address - pushl %esi # push the error code - pushl %edx # push the pt_regs pointer - movl $(__KERNEL_DS),%edx - movl %edx,%ds - movl %edx,%es + movl %edi, ES(%esp) + movl $(__KERNEL_DS),%eax + movl %eax, %ds + movl %eax, %es + movl %esp,%eax /* pt_regs pointer */ call do_page_fault - addl $12,%esp jmp ret_from_exception ENTRY(machine_check) diff -r 287583627544 -r 189c87adf876 extras/mini-os/hypervisor.c --- a/extras/mini-os/hypervisor.c Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/hypervisor.c Wed Jul 6 10:46:29 2005 @@ -4,6 +4,7 @@ * Communication to/from hypervisor. * * Copyright (c) 2002-2003, K A Fraser + * Copyright (c) 2005, Grzegorz Milos, gm281@xxxxxxxxx,Intel Research Cambridge * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -26,65 +27,69 @@ #include <os.h> #include <hypervisor.h> +#include <events.h> -static unsigned long event_mask = 0; -static unsigned long ev_err_count; +#define active_evtchns(cpu,sh,idx) \ + ((sh)->evtchn_pending[idx] & \ + ~(sh)->evtchn_mask[idx]) void do_hypervisor_callback(struct pt_regs *regs) { - unsigned long events, flags; - shared_info_t *shared = HYPERVISOR_shared_info; + u32 l1, l2; + unsigned int l1i, l2i, port; + int cpu = 0; + shared_info_t *s = HYPERVISOR_shared_info; + vcpu_info_t *vcpu_info = &s->vcpu_data[cpu]; - do { - /* Specialised local_irq_save(). */ - flags = test_and_clear_bit(EVENTS_MASTER_ENABLE_BIT, - &shared->events_mask); - barrier(); + vcpu_info->evtchn_upcall_pending = 0; + + /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ + l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); + while ( l1 != 0 ) + { + l1i = __ffs(l1); + l1 &= ~(1 << l1i); + + while ( (l2 = active_evtchns(cpu, s, l1i)) != 0 ) + { + l2i = __ffs(l2); + l2 &= ~(1 << l2i); - events = xchg(&shared->events, 0); - events &= event_mask; - - /* 'events' now contains some pending events to handle. */ - __asm__ __volatile__ ( - " push %1 ;" - " sub $4,%%esp ;" - " jmp 2f ;" - "1: btrl %%eax,%0 ;" /* clear bit */ - " mov %%eax,(%%esp) ;" - " call do_event ;" /* do_event(event) */ - "2: bsfl %0,%%eax ;" /* %eax == bit # */ - " jnz 1b ;" - " add $8,%%esp ;" - /* we use %ebx because it is callee-saved */ - : : "b" (events), "r" (regs) - /* clobbered by callback function calls */ - : "eax", "ecx", "edx", "memory" ); - - /* Specialised local_irq_restore(). */ - if ( flags ) set_bit(EVENTS_MASTER_ENABLE_BIT, &shared->events_mask); - barrier(); + port = (l1i << 5) + l2i; + do_event(port, regs); + } } - while ( shared->events ); } -void enable_hypervisor_event(unsigned int ev) + +inline void mask_evtchn(u32 port) { - set_bit(ev, &event_mask); - set_bit(ev, &HYPERVISOR_shared_info->events_mask); - if ( test_bit(EVENTS_MASTER_ENABLE_BIT, - &HYPERVISOR_shared_info->events_mask) ) - do_hypervisor_callback(NULL); + shared_info_t *s = HYPERVISOR_shared_info; + synch_set_bit(port, &s->evtchn_mask[0]); } -void disable_hypervisor_event(unsigned int ev) +inline void unmask_evtchn(u32 port) { - clear_bit(ev, &event_mask); - clear_bit(ev, &HYPERVISOR_shared_info->events_mask); + shared_info_t *s = HYPERVISOR_shared_info; + vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()]; + + synch_clear_bit(port, &s->evtchn_mask[0]); + + /* + * The following is basically the equivalent of 'hw_resend_irq'. Just like + * a real IO-APIC we 'lose the interrupt edge' if the channel is masked. + */ + if ( synch_test_bit (port, &s->evtchn_pending[0]) && + !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel) ) + { + vcpu_info->evtchn_upcall_pending = 1; + if ( !vcpu_info->evtchn_upcall_mask ) + force_evtchn_callback(); + } } -void ack_hypervisor_event(unsigned int ev) +inline void clear_evtchn(u32 port) { - if ( !(event_mask & (1<<ev)) ) - atomic_inc((atomic_t *)&ev_err_count); - set_bit(ev, &HYPERVISOR_shared_info->events_mask); + shared_info_t *s = HYPERVISOR_shared_info; + synch_clear_bit(port, &s->evtchn_pending[0]); } diff -r 287583627544 -r 189c87adf876 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/kernel.c Wed Jul 6 10:46:29 2005 @@ -5,6 +5,7 @@ * from head.S. * * Copyright (c) 2002-2003, K A Fraser & R Neugebauer + * Copyright (c) 2005, Grzegorz Milos, Intel Research Cambridge * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -56,10 +57,6 @@ void hypervisor_callback(void); void failsafe_callback(void); -/* default event handlers */ -static void exit_handler(int ev, struct pt_regs *regs); -static void debug_handler(int ev, struct pt_regs *regs); - extern char shared_info[PAGE_SIZE]; static shared_info_t *map_shared_info(unsigned long pa) @@ -80,6 +77,7 @@ void start_kernel(start_info_t *si) { static char hello[] = "Bootstrapping...\n"; + int i; (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello); /* Copy the start_info struct to a globally-accessible area. */ @@ -126,28 +124,32 @@ init_mm(); /* set up events */ -// init_events(); - - /* - * These need to be replaced with event-channel/control-interface - * equivalents. - */ -#if 0 - /* Install some handlers. */ - add_ev_action(EV_DIE, &exit_handler); - enable_ev_action(EV_DIE); - enable_hypervisor_event(EV_DIE); - - add_ev_action(EV_DEBUG, &debug_handler); - enable_ev_action(EV_DEBUG); - enable_hypervisor_event(EV_DEBUG); -#endif - + init_events(); /* init time and timers */ -// init_time(); + init_time(); /* do nothing */ - for ( ; ; ) HYPERVISOR_yield(); + i = 0; + for ( ; ; ) + { + if(i >= 1000) + { + { + unsigned long saved; + __asm__ ("movl %%esp, %0" + :"=r"(saved) /* y is output operand */ + /* x is input operand */); +// :"a"); /* %eax is clobbered register */ + printk("ESP=0x%lx\n", saved); + } + + printk("1000 bloks\n"); + i=0; + } +// HYPERVISOR_yield(); + block(1); + i++; + } } @@ -163,13 +165,3 @@ printk("do_exit called!\n"); for ( ;; ) HYPERVISOR_shutdown(); } -static void exit_handler(int ev, struct pt_regs *regs) { - do_exit(); -} - -/* - * a debug handler to print out some state from the guest - */ -static void debug_handler(int ev, struct pt_regs *regs) { - dump_regs(regs); -} diff -r 287583627544 -r 189c87adf876 extras/mini-os/events.c --- a/extras/mini-os/events.c Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/events.c Wed Jul 6 10:46:29 2005 @@ -1,19 +1,18 @@ /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- **************************************************************************** * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge **************************************************************************** * * File: events.c * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) - * Changes: + * Changes: Grzegorz Milos (gm281@xxxxxxxxx) * - * Date: Jul 2003 + * Date: Jul 2003, changes Jun 2005 * * Environment: Xen Minimal OS - * Description: Deal with events + * Description: Deals with events recieved on event channels * - **************************************************************************** - * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $ **************************************************************************** */ @@ -22,25 +21,25 @@ #include <events.h> #include <lib.h> +#include <xen/event_channel.h> static ev_action_t ev_actions[NR_EVS]; -void default_handler(int ev, struct pt_regs *regs); +void default_handler(u32 port, struct pt_regs *regs); /* - * demux events to different handlers + * Demux events to different handlers. */ -unsigned int do_event(int ev, struct pt_regs *regs) +int do_event(u32 port, struct pt_regs *regs) { ev_action_t *action; - if (ev >= NR_EVS) { - printk("Large event number %d\n", ev); + if (port >= NR_EVS) { + printk("Port number too large: %d\n", port); return 0; } - action = &ev_actions[ev]; + action = &ev_actions[port]; action->count++; - ack_hypervisor_event(ev); if (!action->handler) goto out; @@ -49,45 +48,49 @@ goto out; /* call the handler */ - action->handler(ev, regs); + action->handler(port, regs); + + clear_evtchn(port); out: return 1; } -/* - * add a handler - */ -unsigned int add_ev_action( int ev, void (*handler)(int, struct pt_regs *) ) +int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) ) { - if (ev_actions[ev].handler) { - printk ("event[%d] already handled by %p", ev, ev_actions[ev].handler); - return 0; + evtchn_op_t op; + int ret = 0; + u32 port; + + /* Try to bind the virq to a port */ + op.cmd = EVTCHNOP_bind_virq; + op.u.bind_virq.virq = virq; + + if ( HYPERVISOR_event_channel_op(&op) != 0 ) + { + ret = 1; + printk("Failed to bind virtual IRQ %d\n", virq); + goto out; } - ev_actions[ev].handler = handler; - return 1; -} + port = op.u.bind_virq.port; + + if(ev_actions[port].handler) + printk("WARN: Handler for port %d already registered, replacing\n", + port); -unsigned int enable_ev_action( int ev ) -{ - if (!ev_actions[ev].handler) { - printk ("enable event[%d], no handler installed", ev); - return 0; - } - ev_actions[ev].status &= ~EVS_DISABLED; - return 1; -} - -unsigned int disable_ev_action( int ev ) -{ - ev_actions[ev].status |= EVS_DISABLED; - return 1; + ev_actions[port].handler = handler; + ev_actions[port].status &= ~EVS_DISABLED; + + /* Finally unmask the port */ + unmask_evtchn(port); +out: + return ret; } /* - * initially all events are without a handler and disabled + * Initially all events are without a handler and disabled */ void init_events(void) { @@ -101,6 +104,6 @@ } } -void default_handler(int ev, struct pt_regs *regs) { - printk("X[%d] ", ev); +void default_handler(u32 port, struct pt_regs *regs) { + printk("[Port %d] - event received\n", port); } diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/os.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/os.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,334 @@ +/****************************************************************************** + * os.h + * + * random collection of macros and definition + */ + +#ifndef _OS_H_ +#define _OS_H_ + +#define NULL 0 + +#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 +#define __builtin_expect(x, expected_value) (x) +#endif +#define unlikely(x) __builtin_expect((x),0) + +#define smp_processor_id() 0 +#define preempt_disable() ((void)0) +#define preempt_enable() ((void)0) + +#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0)) + +#ifndef __ASSEMBLY__ +#include <types.h> +#endif +#include <xen/xen.h> + +#define __KERNEL_CS FLAT_KERNEL_CS +#define __KERNEL_DS FLAT_KERNEL_DS +#define __KERNEL_SS FLAT_KERNEL_SS + +#define TRAP_divide_error 0 +#define TRAP_debug 1 +#define TRAP_nmi 2 +#define TRAP_int3 3 +#define TRAP_overflow 4 +#define TRAP_bounds 5 +#define TRAP_invalid_op 6 +#define TRAP_no_device 7 +#define TRAP_double_fault 8 +#define TRAP_copro_seg 9 +#define TRAP_invalid_tss 10 +#define TRAP_no_segment 11 +#define TRAP_stack_error 12 +#define TRAP_gp_fault 13 +#define TRAP_page_fault 14 +#define TRAP_spurious_int 15 +#define TRAP_copro_error 16 +#define TRAP_alignment_check 17 +#define TRAP_machine_check 18 +#define TRAP_simd_error 19 +#define TRAP_deferred_nmi 31 + +/* Everything below this point is not included by assembler (.S) files. */ +#ifndef __ASSEMBLY__ + +#define pt_regs xen_regs + +void trap_init(void); + +/* + * 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 __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 __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 __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 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 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") + +#define LOCK_PREFIX "" +#define LOCK "" +#define ADDR (*(volatile long *) addr) +/* + * Make sure gcc doesn't try to be clever and move things around + * on us. We need to use _exactly_ the address the user gave us, + * not some alias that contains the same information. + */ +typedef struct { volatile int counter; } atomic_t; + + +#define xchg(ptr,v) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) +struct __xchg_dummy { unsigned long a[100]; }; +#define __xg(x) ((volatile struct __xchg_dummy *)(x)) +static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, + int size) +{ + switch (size) { + case 1: + __asm__ __volatile__("xchgb %b0,%1" + :"=q" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 2: + __asm__ __volatile__("xchgw %w0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + case 4: + __asm__ __volatile__("xchgl %0,%1" + :"=r" (x) + :"m" (*__xg(ptr)), "0" (x) + :"memory"); + break; + } + return x; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * atomic_inc - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void atomic_inc(atomic_t *v) +{ + __asm__ __volatile__( + LOCK "incl %0" + :"=m" (v->counter) + :"m" (v->counter)); +} + + +#define rdtscll(val) \ + __asm__ __volatile__("rdtsc" : "=A" (val)) + +static __inline__ unsigned long __ffs(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"rm" (word)); + return word; +} + +#define ADDR (*(volatile long *) addr) + +static __inline__ void synch_set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__ ( + "lock btsl %1,%0" + : "=m" (ADDR) : "Ir" (nr) : "memory" ); +} + +static __inline__ void synch_clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__ ( + "lock btrl %1,%0" + : "=m" (ADDR) : "Ir" (nr) : "memory" ); +} + +static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + __asm__ __volatile__ ( + "lock btsl %2,%1\n\tsbbl %0,%0" + : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory"); + return oldbit; +} + + +static __inline__ int synch_const_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & + (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int synch_var_test_bit(int nr, volatile void * addr) +{ + int oldbit; + __asm__ __volatile__ ( + "btl %2,%1\n\tsbbl %0,%0" + : "=r" (oldbit) : "m" (ADDR), "Ir" (nr) ); + return oldbit; +} + +#define synch_test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + synch_const_test_bit((nr),(addr)) : \ + synch_var_test_bit((nr),(addr))) +#endif /* !__ASSEMBLY__ */ + +#define rdtsc(low,high) \ + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) + +#endif /* _OS_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/mm.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/mm.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,111 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + * + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * Copyright (c) 2005, Keir A Fraser + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (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 _MM_H_ +#define _MM_H_ + +#ifdef __x86_64__ + +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 21 +#define L3_PAGETABLE_SHIFT 30 +#define L4_PAGETABLE_SHIFT 39 + +#define L1_PAGETABLE_ENTRIES 512 +#define L2_PAGETABLE_ENTRIES 512 +#define L3_PAGETABLE_ENTRIES 512 +#define L4_PAGETABLE_ENTRIES 512 + +/* These are page-table limitations. Current CPUs support only 40-bit phys. */ +#define PADDR_BITS 52 +#define VADDR_BITS 48 +#define PADDR_MASK ((1UL << PADDR_BITS)-1) +#define VADDR_MASK ((1UL << VADDR_BITS)-1) + +#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT) + +/* Given a virtual address, get an entry offset into a page table. */ +#define l1_table_offset(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) +#define l2_table_offset(_a) \ + (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) +#define l3_table_offset(_a) \ + (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) +#define l4_table_offset(_a) \ + (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) +#endif + +#define _PAGE_PRESENT 0x001UL +#define _PAGE_RW 0x002UL +#define _PAGE_USER 0x004UL +#define _PAGE_PWT 0x008UL +#define _PAGE_PCD 0x010UL +#define _PAGE_ACCESSED 0x020UL +#define _PAGE_DIRTY 0x040UL +#define _PAGE_PAT 0x080UL +#define _PAGE_PSE 0x080UL +#define _PAGE_GLOBAL 0x100UL + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +extern unsigned long *phys_to_machine_mapping; +#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)]) +#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)]) +static __inline__ unsigned long phys_to_machine(unsigned long phys) +{ + unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT); + machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK); + return machine; +} +static __inline__ unsigned long machine_to_phys(unsigned long machine) +{ + unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT); + phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); + 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)) +#define __va to_virt +#define __pa to_phys + +void init_mm(void); +unsigned long alloc_pages(int order); + +#endif /* _MM_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/traps.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/traps.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,41 @@ +/* + **************************************************************************** + * (C) 2005 - Grzegorz Milos - Intel Reseach Cambridge + **************************************************************************** + * + * File: traps.h + * Author: Grzegorz Milos (gm281@xxxxxxxxx) + * + * Date: Jun 2005 + * + * Environment: Xen Minimal OS + * Description: Deals with traps + * + **************************************************************************** + */ + +#ifndef _TRAPS_H_ +#define _TRAPS_H_ + +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; +}; + + +void dump_regs(struct pt_regs *regs); + +#endif /* _TRAPS_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/hypervisor.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/hypervisor.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,357 @@ +/****************************************************************************** + * hypervisor.h + * + * Hypervisor handling. + * + * TODO - x86_64 broken! + * + * Copyright (c) 2002, K A Fraser + * Copyright (c) 2005, Grzegorz Milos + */ + +#ifndef _HYPERVISOR_H_ +#define _HYPERVISOR_H_ + +#include <types.h> + +#include <xen/xen.h> +#include <xen/io/domain_controller.h> + + + +/* + * a placeholder for the start of day information passed up from the hypervisor + */ +union start_info_union +{ + start_info_t start_info; + char padding[512]; +}; +extern union start_info_union start_info_union; +#define start_info (start_info_union.start_info) + + +/* hypervisor.c */ +//void do_hypervisor_callback(struct pt_regs *regs); +void mask_evtchn(u32 port); +void unmask_evtchn(u32 port); +void clear_evtchn(u32 port); + +/* + * 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_event_channel_op( + void *op) +{ + int ret; + unsigned long ignore; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ignore) + : "0" (__HYPERVISOR_event_channel_op), "1" (op) + : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_set_trap_table(trap_info_t *table) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table), + _a1 (table) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, + int count, + int *success_count) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), + _a1 (req), _a2 (count), _a3 (success_count) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), + _a1 (frame_list), _a2 (entries) : "memory" ); + + + return ret; +} + +static __inline__ int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_stack_switch), + _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) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), + _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( + int set) +{ + int ret; + unsigned long ign; + + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ign) + : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) + : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_yield(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + _a1 (SCHEDOP_yield) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_block(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + _a1 (SCHEDOP_block) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_shutdown(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + _a1 (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_reboot(void) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + _a1 (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_suspend(unsigned long srec) +{ + int ret; + /* NB. On suspend, control software expects a suspend record in %esi. */ + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + _a1 (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), + "S" (srec) : "memory" ); + + return ret; +} + +#ifdef __i386__ +static __inline__ long HYPERVISOR_set_timer_op( u64 timeout ) +{ + int ret; + unsigned long timeout_hi = (unsigned long)(timeout>>32); + unsigned long timeout_lo = (unsigned long)timeout; + unsigned long ign1, ign2; + + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ign1), "=c" (ign2) + : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi) + : "memory"); + + return ret; +} +#else +static __inline__ long HYPERVISOR_set_timer_op( u64 timeout ) +{ + int ret; + + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) + : "0" ((unsigned long)__HYPERVISOR_set_timer_op), + "D" (timeout) + : __syscall_clobber ); + + return ret; +} +#endif + + +static __inline__ int HYPERVISOR_dom0_op(void *dom0_op) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_dom0_op), + _a1 (dom0_op) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg), + _a1 (reg), _a2 (value) : "memory" ); + + return ret; +} + +static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg) +{ + unsigned long ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg), + _a1 (reg) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_update_descriptor( + unsigned long pa, unsigned long word1, unsigned long word2) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor), + _a1 (pa), _a2 (word1), _a3 (word2) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op), + _a1 (dom_mem_op) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_multicall), + _a1 (call_list), _a2 (nr_calls) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_update_va_mapping( + unsigned long page_nr, unsigned long new_val, unsigned long flags) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), + _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_xen_version(int cmd) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_xen_version), + _a1 (cmd) : "memory" ); + + return ret; +} + +static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str) +{ + int ret; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret) : "0" (__HYPERVISOR_console_io), + _a1 (cmd), _a2 (count), _a3 (str) : "memory" ); + + return ret; +} + +#endif /* __HYPERVISOR_H__ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/lib.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/lib.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,114 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + **************************************************************************** + * + * File: lib.h + * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) + * Changes: + * + * Date: Aug 2003 + * + * Environment: Xen Minimal OS + * Description: Random useful library functions, contains some freebsd stuff + * + **************************************************************************** + * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ + **************************************************************************** + * + *- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)stdarg.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/i386/include/stdarg.h,v 1.10 1999/08/28 00:44:26 peter Exp $ + */ + +#ifndef _LIB_H_ +#define _LIB_H_ + +#include <stdarg.h> + +/* printing */ +#define printk printf +#define kprintf printf +int printf(const char *fmt, ...); +int vprintf(const char *fmt, va_list ap); +int sprintf(char *buf, const char *cfmt, ...); +int vsprintf(char *buf, const char *cfmt, va_list ap); + +/* string and memory manipulation */ +int memcmp(const void *cs, const void *ct, size_t count); +void *memcpy(void *dest, const void *src, size_t count); +int strncmp(const char *cs, const char *ct, size_t count); +int strcmp(const char *cs, const char *ct); +char *strcpy(char *dest, const char *src); +char *strncpy(char *dest, const char *src, size_t count); +void *memset(void *s,int c, size_t count); +size_t strnlen(const char *s, size_t count); +size_t strlen(const char *s); +char *strchr(const char *s, int c); +char *strstr(const char *s1, const char *s2); + + +/* dlmalloc functions */ +struct mallinfo { + int arena; /* non-mmapped space allocated from system */ + int ordblks; /* number of free chunks */ + int smblks; /* number of fastbin blocks */ + int hblks; /* number of mmapped regions */ + int hblkhd; /* space in mmapped regions */ + int usmblks; /* maximum total allocated space */ + int fsmblks; /* space available in freed fastbin blocks */ + int uordblks; /* total allocated space */ + int fordblks; /* total free space */ + int keepcost; /* top-most, releasable (via malloc_trim) space */ +}; + +void *malloc(size_t n); +void *calloc(size_t n_elements, size_t element_size); +void free(void* p); +void *realloc(void* p, size_t n); +void *memalign(size_t alignment, size_t n); +void *valloc(size_t n); +struct mallinfo mallinfo(void); +int mallopt(int parameter_number, int parameter_value); + +void **independent_calloc(size_t n_elements, size_t size, void* chunks[]); +void **independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); +void *pvalloc(size_t n); +void cfree(void* p); +int malloc_trim(size_t pad); +size_t malloc_usable_size(void* p); +void malloc_stats(void); + + +#endif /* _LIB_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/types.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/types.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,52 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + **************************************************************************** + * + * File: types.h + * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) + * Changes: + * + * Date: May 2003 + * + * Environment: Xen Minimal OS + * Description: a random collection of type definitions + * + **************************************************************************** + * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ + **************************************************************************** + */ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +typedef signed char s8; +typedef unsigned char u8; +typedef signed short s16; +typedef unsigned short u16; +typedef signed int s32; +typedef unsigned int u32; +#ifdef __i386__ +typedef signed long long s64; +typedef unsigned long long u64; +#elif defined(__x86_64__) +typedef signed long s64; +typedef unsigned long u64; +#endif + +typedef unsigned int size_t; + +/* FreeBSD compat types */ +typedef unsigned char u_char; +typedef unsigned int u_int; +typedef unsigned long u_long; +#ifdef __i386__ +typedef long long quad_t; +typedef unsigned long long u_quad_t; +typedef unsigned int uintptr_t; +#elif defined(__x86_64__) +typedef long quad_t; +typedef unsigned long u_quad_t; +typedef unsigned long uintptr_t; +#endif +#endif /* _TYPES_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/events.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/events.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,44 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * (C) 2005 - Grzegorz Milos - Intel Reseach Cambridge + **************************************************************************** + * + * File: events.h + * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) + * Changes: Grzegorz Milos (gm281@xxxxxxxxx) + * + * Date: Jul 2003, changes Jun 2005 + * + * Environment: Xen Minimal OS + * Description: Deals with events on the event channels + * + **************************************************************************** + */ + +#ifndef _EVENTS_H_ +#define _EVENTS_H_ + +#include<traps.h> + +#define NR_EVS 1024 + +/* ev handler status */ +#define EVS_INPROGRESS 1 /* Event handler active - do not enter! */ +#define EVS_DISABLED 2 /* Event disabled - do not enter! */ +#define EVS_PENDING 4 /* Event pending - replay on enable */ +#define EVS_REPLAY 8 /* Event has been replayed but not acked yet */ + +/* this represents a event handler. Chaining or sharing is not allowed */ +typedef struct _ev_action_t { + void (*handler)(int, struct pt_regs *); + unsigned int status; /* IRQ status */ + u32 count; +} ev_action_t; + +/* prototypes */ +int do_event(u32 port, struct pt_regs *regs); +int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) ); +void init_events(void); + +#endif /* _EVENTS_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/include/time.h --- /dev/null Wed Jul 6 08:50:11 2005 +++ b/extras/mini-os/include/time.h Wed Jul 6 10:46:29 2005 @@ -0,0 +1,57 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + **************************************************************************** + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge + **************************************************************************** + * + * File: time.h + * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) + * Changes: Grzegorz Milos (gm281@xxxxxxxxx) + * + * Date: Jul 2003, changesJun 2005 + * + * Environment: Xen Minimal OS + * Description: Time and timer functions + * + **************************************************************************** + */ + +#ifndef _TIME_H_ +#define _TIME_H_ + +/* + * System Time + * 64 bit value containing the nanoseconds elapsed since boot time. + * This value is adjusted by frequency drift. + * NOW() returns the current time. + * The other macros are for convenience to approximate short intervals + * of real time into system time + */ +typedef s64 s_time_t; +#define NOW() ((s_time_t)get_s_time()) +#define SECONDS(_s) (((s_time_t)(_s)) * 1000000000UL ) +#define TENTHS(_ts) (((s_time_t)(_ts)) * 100000000UL ) +#define HUNDREDTHS(_hs) (((s_time_t)(_hs)) * 10000000UL ) +#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000UL ) +#define MICROSECS(_us) (((s_time_t)(_us)) * 1000UL ) +#define Time_Max ((s_time_t) 0x7fffffffffffffffLL) +#define FOREVER Time_Max + + +/* wall clock time */ +typedef long time_t; +typedef long suseconds_t; +struct timeval { + time_t tv_sec; /* seconds */ + suseconds_t tv_usec; /* microseconds */ +}; + + +/* prototypes */ +void init_time(void); +s_time_t get_s_time(void); +s_time_t get_v_time(void); +void gettimeofday(struct timeval *tv); +void block(u32 millisecs); + +#endif /* _TIME_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/events.h --- a/extras/mini-os/h/events.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,53 +0,0 @@ -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- - **************************************************************************** - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - **************************************************************************** - * - * File: events.h - * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) - * Changes: - * - * Date: Jul 2003 - * - * Environment: Xen Minimal OS - * Description: deal with events - * - **************************************************************************** - * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ - **************************************************************************** - */ - -#ifndef _EVENTS_H_ -#define _EVENTS_H_ - -/* _EVENT_* are defined in xen-public/xen.h */ -#define EV_BLKDEV _EVENT_BLKDEV -#define EV_TIMER _EVENT_TIMER -#define EV_DIE _EVENT_DIE -#define EV_DEBUG _EVENT_DEBUG -#define EV_NET _EVENT_NET -#define EV_PS2 _EVENT_PS2 - -#define NR_EVS (sizeof(HYPERVISOR_shared_info->events) * 8) - -/* ev handler status */ -#define EVS_INPROGRESS 1 /* Event handler active - do not enter! */ -#define EVS_DISABLED 2 /* Event disabled - do not enter! */ -#define EVS_PENDING 4 /* Event pending - replay on enable */ -#define EVS_REPLAY 8 /* Event has been replayed but not acked yet */ - -/* this represents a event handler. Chaining or sharing is not allowed */ -typedef struct _ev_action_t { - void (*handler)(int, struct pt_regs *); - unsigned int status; /* IRQ status */ - u32 count; -} ev_action_t; - -/* prototypes */ -unsigned int do_event(int ev, struct pt_regs *regs); -unsigned int add_ev_action( int ev, void (*handler)(int, struct pt_regs *) ); -unsigned int enable_ev_action( int ev ); -unsigned int disable_ev_action( int ev ); -void init_events(void); - -#endif /* _EVENTS_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/hypervisor.h --- a/extras/mini-os/h/hypervisor.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,316 +0,0 @@ -/****************************************************************************** - * hypervisor.h - * - * Linux-specific hypervisor handling. - * - * Copyright (c) 2002, K A Fraser - */ - -#ifndef _HYPERVISOR_H_ -#define _HYPERVISOR_H_ - -#include <types.h> - -#include <xen-public/xen.h> -#include <xen-public/io/domain_controller.h> - -/* - * a placeholder for the start of day information passed up from the hypervisor - */ -union start_info_union -{ - start_info_t start_info; - char padding[512]; -}; -extern union start_info_union start_info_union; -#define start_info (start_info_union.start_info) - - -/* hypervisor.c */ -void do_hypervisor_callback(struct pt_regs *regs); -void enable_hypervisor_event(unsigned int ev); -void disable_hypervisor_event(unsigned int ev); -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), - _a1 (table) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, - int count, - int *success_count) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), - _a1 (req), _a2 (count), _a3 (success_count) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), - _a1 (frame_list), _a2 (entries) : "memory" ); - - - return ret; -} - -static __inline__ int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_stack_switch), - _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) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), - _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( - int set) -{ - int ret; - unsigned long ign; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign) - : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) - : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_yield(void) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - _a1 (SCHEDOP_yield) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_block(void) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - _a1 (SCHEDOP_block) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_shutdown(void) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - _a1 (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) - : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_reboot(void) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - _a1 (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) - : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_suspend(unsigned long srec) -{ - int ret; - /* NB. On suspend, control software expects a suspend record in %esi. */ - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), - _a1 (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), - "S" (srec) : "memory" ); - - return ret; -} - -static __inline__ long HYPERVISOR_set_timer_op(void *timer_arg) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_set_timer_op), - _a1 (timer_arg) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_dom0_op(void *dom0_op) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_dom0_op), - _a1 (dom0_op) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg), - _a1 (reg), _a2 (value) : "memory" ); - - return ret; -} - -static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg) -{ - unsigned long ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg), - _a1 (reg) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_update_descriptor( - unsigned long pa, unsigned long word1, unsigned long word2) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor), - _a1 (pa), _a2 (word1), _a3 (word2) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op), - _a1 (dom_mem_op) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_multicall), - _a1 (call_list), _a2 (nr_calls) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_update_va_mapping( - unsigned long page_nr, unsigned long new_val, unsigned long flags) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), - _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_xen_version(int cmd) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_xen_version), - _a1 (cmd) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_console_io), - _a1 (cmd), _a2 (count), _a3 (str) : "memory" ); - - return ret; -} - -#endif /* __HYPERVISOR_H__ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/lib.h --- a/extras/mini-os/h/lib.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,114 +0,0 @@ -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- - **************************************************************************** - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - **************************************************************************** - * - * File: lib.h - * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) - * Changes: - * - * Date: Aug 2003 - * - * Environment: Xen Minimal OS - * Description: Random useful library functions, contains some freebsd stuff - * - **************************************************************************** - * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ - **************************************************************************** - * - *- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)stdarg.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/i386/include/stdarg.h,v 1.10 1999/08/28 00:44:26 peter Exp $ - */ - -#ifndef _LIB_H_ -#define _LIB_H_ - -#include <stdarg.h> - -/* printing */ -#define printk printf -#define kprintf printf -int printf(const char *fmt, ...); -int vprintf(const char *fmt, va_list ap); -int sprintf(char *buf, const char *cfmt, ...); -int vsprintf(char *buf, const char *cfmt, va_list ap); - -/* string and memory manipulation */ -int memcmp(const void *cs, const void *ct, size_t count); -void *memcpy(void *dest, const void *src, size_t count); -int strncmp(const char *cs, const char *ct, size_t count); -int strcmp(const char *cs, const char *ct); -char *strcpy(char *dest, const char *src); -char *strncpy(char *dest, const char *src, size_t count); -void *memset(void *s,int c, size_t count); -size_t strnlen(const char *s, size_t count); -size_t strlen(const char *s); -char *strchr(const char *s, int c); -char *strstr(const char *s1, const char *s2); - - -/* dlmalloc functions */ -struct mallinfo { - int arena; /* non-mmapped space allocated from system */ - int ordblks; /* number of free chunks */ - int smblks; /* number of fastbin blocks */ - int hblks; /* number of mmapped regions */ - int hblkhd; /* space in mmapped regions */ - int usmblks; /* maximum total allocated space */ - int fsmblks; /* space available in freed fastbin blocks */ - int uordblks; /* total allocated space */ - int fordblks; /* total free space */ - int keepcost; /* top-most, releasable (via malloc_trim) space */ -}; - -void *malloc(size_t n); -void *calloc(size_t n_elements, size_t element_size); -void free(void* p); -void *realloc(void* p, size_t n); -void *memalign(size_t alignment, size_t n); -void *valloc(size_t n); -struct mallinfo mallinfo(void); -int mallopt(int parameter_number, int parameter_value); - -void **independent_calloc(size_t n_elements, size_t size, void* chunks[]); -void **independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); -void *pvalloc(size_t n); -void cfree(void* p); -int malloc_trim(size_t pad); -size_t malloc_usable_size(void* p); -void malloc_stats(void); - - -#endif /* _LIB_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/mm.h --- a/extras/mini-os/h/mm.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,111 +0,0 @@ -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- - * - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - * Copyright (c) 2005, Keir A Fraser - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (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 _MM_H_ -#define _MM_H_ - -#ifdef __x86_64__ - -#define L1_PAGETABLE_SHIFT 12 -#define L2_PAGETABLE_SHIFT 21 -#define L3_PAGETABLE_SHIFT 30 -#define L4_PAGETABLE_SHIFT 39 - -#define L1_PAGETABLE_ENTRIES 512 -#define L2_PAGETABLE_ENTRIES 512 -#define L3_PAGETABLE_ENTRIES 512 -#define L4_PAGETABLE_ENTRIES 512 - -/* These are page-table limitations. Current CPUs support only 40-bit phys. */ -#define PADDR_BITS 52 -#define VADDR_BITS 48 -#define PADDR_MASK ((1UL << PADDR_BITS)-1) -#define VADDR_MASK ((1UL << VADDR_BITS)-1) - -#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT) - -/* Given a virtual address, get an entry offset into a page table. */ -#define l1_table_offset(_a) \ - (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) -#define l2_table_offset(_a) \ - (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) -#define l3_table_offset(_a) \ - (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) -#define l4_table_offset(_a) \ - (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) -#endif - -#define _PAGE_PRESENT 0x001UL -#define _PAGE_RW 0x002UL -#define _PAGE_USER 0x004UL -#define _PAGE_PWT 0x008UL -#define _PAGE_PCD 0x010UL -#define _PAGE_ACCESSED 0x020UL -#define _PAGE_DIRTY 0x040UL -#define _PAGE_PAT 0x080UL -#define _PAGE_PSE 0x080UL -#define _PAGE_GLOBAL 0x100UL - -#define PAGE_SHIFT 12 -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) - -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - -extern unsigned long *phys_to_machine_mapping; -#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)]) -#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)]) -static __inline__ unsigned long phys_to_machine(unsigned long phys) -{ - unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT); - machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK); - return machine; -} -static __inline__ unsigned long machine_to_phys(unsigned long machine) -{ - unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT); - phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); - 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)) -#define __va to_virt -#define __pa to_phys - -void init_mm(void); -unsigned long alloc_pages(int order); - -#endif /* _MM_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/os.h --- a/extras/mini-os/h/os.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,280 +0,0 @@ -/****************************************************************************** - * os.h - * - * random collection of macros and definition - */ - -#ifndef _OS_H_ -#define _OS_H_ - -#define NULL 0 - -#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 -#define __builtin_expect(x, expected_value) (x) -#endif -#define unlikely(x) __builtin_expect((x),0) - -#define smp_processor_id() 0 -#define preempt_disable() ((void)0) -#define preempt_enable() ((void)0) - -#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0)) - -#ifndef __ASSEMBLY__ -#include <types.h> -#endif -#include <xen-public/xen.h> - -#define __KERNEL_CS FLAT_KERNEL_CS -#define __KERNEL_DS FLAT_KERNEL_DS -#define __KERNEL_SS FLAT_KERNEL_SS - -#define TRAP_divide_error 0 -#define TRAP_debug 1 -#define TRAP_nmi 2 -#define TRAP_int3 3 -#define TRAP_overflow 4 -#define TRAP_bounds 5 -#define TRAP_invalid_op 6 -#define TRAP_no_device 7 -#define TRAP_double_fault 8 -#define TRAP_copro_seg 9 -#define TRAP_invalid_tss 10 -#define TRAP_no_segment 11 -#define TRAP_stack_error 12 -#define TRAP_gp_fault 13 -#define TRAP_page_fault 14 -#define TRAP_spurious_int 15 -#define TRAP_copro_error 16 -#define TRAP_alignment_check 17 -#define TRAP_machine_check 18 -#define TRAP_simd_error 19 -#define TRAP_deferred_nmi 31 - -/* Everything below this point is not included by assembler (.S) files. */ -#ifndef __ASSEMBLY__ - -#define pt_regs xen_regs - -void trap_init(void); -void dump_regs(struct pt_regs *regs); - -/* - * 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 __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 __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 __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 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 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") - -#define LOCK_PREFIX "" -#define LOCK "" -#define ADDR (*(volatile long *) addr) -/* - * Make sure gcc doesn't try to be clever and move things around - * on us. We need to use _exactly_ the address the user gave us, - * not some alias that contains the same information. - */ -typedef struct { volatile int counter; } atomic_t; - - -#define xchg(ptr,v) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) -struct __xchg_dummy { unsigned long a[100]; }; -#define __xg(x) ((volatile struct __xchg_dummy *)(x)) -static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, - int size) -{ - switch (size) { - case 1: - __asm__ __volatile__("xchgb %b0,%1" - :"=q" (x) - :"m" (*__xg(ptr)), "0" (x) - :"memory"); - break; - case 2: - __asm__ __volatile__("xchgw %w0,%1" - :"=r" (x) - :"m" (*__xg(ptr)), "0" (x) - :"memory"); - break; - case 4: - __asm__ __volatile__("xchgl %0,%1" - :"=r" (x) - :"m" (*__xg(ptr)), "0" (x) - :"memory"); - break; - } - return x; -} - -/** - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static __inline__ int test_and_clear_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( LOCK_PREFIX - "btrl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"=m" (ADDR) - :"Ir" (nr) : "memory"); - return oldbit; -} - -static __inline__ int constant_test_bit(int nr, const volatile void * addr) -{ - return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; -} - -static __inline__ int variable_test_bit(int nr, volatile void * addr) -{ - int oldbit; - - __asm__ __volatile__( - "btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (ADDR),"Ir" (nr)); - return oldbit; -} - -#define test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - constant_test_bit((nr),(addr)) : \ - variable_test_bit((nr),(addr))) - - -/** - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static __inline__ void set_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btsl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} - -/** - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() - * in order to ensure changes are visible on other processors. - */ -static __inline__ void clear_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btrl %1,%0" - :"=m" (ADDR) - :"Ir" (nr)); -} - -/** - * atomic_inc - increment atomic variable - * @v: pointer of type atomic_t - * - * Atomically increments @v by 1. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. - */ -static __inline__ void atomic_inc(atomic_t *v) -{ - __asm__ __volatile__( - LOCK "incl %0" - :"=m" (v->counter) - :"m" (v->counter)); -} - - -#define rdtscll(val) \ - __asm__ __volatile__("rdtsc" : "=A" (val)) - - -#endif /* !__ASSEMBLY__ */ - -#endif /* _OS_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/time.h --- a/extras/mini-os/h/time.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,57 +0,0 @@ -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- - **************************************************************************** - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - **************************************************************************** - * - * File: time.h - * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) - * Changes: - * - * Date: Jul 2003 - * - * Environment: Xen Minimal OS - * Description: Time and timer functions - * - **************************************************************************** - * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ - **************************************************************************** - */ - -#ifndef _TIME_H_ -#define _TIME_H_ - -/* - * System Time - * 64 bit value containing the nanoseconds elapsed since boot time. - * This value is adjusted by frequency drift. - * NOW() returns the current time. - * The other macros are for convenience to approximate short intervals - * of real time into system time - */ -typedef s64 s_time_t; -#define NOW() ((s_time_t)get_s_time()) -#define SECONDS(_s) (((s_time_t)(_s)) * 1000000000UL ) -#define TENTHS(_ts) (((s_time_t)(_ts)) * 100000000UL ) -#define HUNDREDTHS(_hs) (((s_time_t)(_hs)) * 10000000UL ) -#define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000UL ) -#define MICROSECS(_us) (((s_time_t)(_us)) * 1000UL ) -#define Time_Max ((s_time_t) 0x7fffffffffffffffLL) -#define FOREVER Time_Max - - -/* wall clock time */ -typedef long time_t; -typedef long suseconds_t; -struct timeval { - time_t tv_sec; /* seconds */ - suseconds_t tv_usec; /* microseconds */ -}; - - -/* prototypes */ -void init_time(void); -s_time_t get_s_time(void); -s_time_t get_v_time(void); -void gettimeofday(struct timeval *tv); - -#endif /* _TIME_H_ */ diff -r 287583627544 -r 189c87adf876 extras/mini-os/h/types.h --- a/extras/mini-os/h/types.h Wed Jul 6 08:50:11 2005 +++ /dev/null Wed Jul 6 10:46:29 2005 @@ -1,52 +0,0 @@ -/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- - **************************************************************************** - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - **************************************************************************** - * - * File: types.h - * Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx) - * Changes: - * - * Date: May 2003 - * - * Environment: Xen Minimal OS - * Description: a random collection of type definitions - * - **************************************************************************** - * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ - **************************************************************************** - */ - -#ifndef _TYPES_H_ -#define _TYPES_H_ - -typedef signed char s8; -typedef unsigned char u8; -typedef signed short s16; -typedef unsigned short u16; -typedef signed int s32; -typedef unsigned int u32; -#ifdef __i386__ -typedef signed long long s64; -typedef unsigned long long u64; -#elif defined(__x86_64__) -typedef signed long s64; -typedef unsigned long u64; -#endif - -typedef unsigned int size_t; - -/* FreeBSD compat types */ -typedef unsigned char u_char; -typedef unsigned int u_int; -typedef unsigned long u_long; -#ifdef __i386__ -typedef long long quad_t; -typedef unsigned long long u_quad_t; -typedef unsigned int uintptr_t; -#elif defined(__x86_64__) -typedef long quad_t; -typedef unsigned long u_quad_t; -typedef unsigned long uintptr_t; -#endif -#endif /* _TYPES_H_ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |