WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] mini-os implementation of xenbus, some 64bit fixes

To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>, Keir Fraser <Keir.Fraser@xxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] mini-os implementation of xenbus, some 64bit fixes
From: Grzegorz Milos <gm281@xxxxxxxxx>
Date: Wed, 07 Sep 2005 21:03:24 +0100
Delivery-date: Wed, 07 Sep 2005 20:01:44 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla Thunderbird 1.0.6 (Macintosh/20050716)
This patch ports the Linux implementation of xenbus, in order to do that very simple threading support is introduced. Apart of that numerous fixes for 64 bit are included. Mini-os now compiles (for 64bit) but requires memory management and threading fixes before it works as well as 32bit version.

Gregor
# HG changeset patch
# User gmilos@xxxxxxxxxxxxxxxxxxxxx
# Node ID 8d393e2d3b6633cf0d97d7bf83f73cd441e4dbdb
# Parent  de8a90fc266798037134fa8b96a39b2150b3a0f6
Xenbus implementation ported from Linux to Mini-os, simple thread support 
introduced 
to simplify the porting. 64 bit version of Mini-os now compiles, but does not 
work
because of the pagetables and some bits of scheduler not being written.

Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx>

diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/Makefile
--- a/extras/mini-os/Makefile   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/Makefile   Wed Sep  7 18:10:45 2005
@@ -31,16 +31,18 @@
 OBJS := $(TARGET_ARCH).o
 OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
 OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
-
+OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
+                                                                               
   
 HDRS := $(wildcard include/*.h)
 HDRS += $(wildcard include/xen/*.h)
 
 default: $(TARGET)
 
-xen-public:
+links:
        [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
-
-$(TARGET): xen-public $(OBJS)
+       [ -e xenbus/xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h 
xenbus/xenstored.h
+       
+$(TARGET): links $(OBJS)
        $(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
        gzip -f -9 -c $@.elf >$@.gz
 
@@ -55,3 +57,4 @@
 %.o: %.S $(HDRS) Makefile
        $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
 
+
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/events.c
--- a/extras/mini-os/events.c   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/events.c   Wed Sep  7 18:10:45 2005
@@ -17,13 +17,13 @@
  */
 
 #include <os.h>
+#include <mm.h>
 #include <hypervisor.h>
 #include <events.h>
 #include <lib.h>
 
-#include <xen/event_channel.h>
 static ev_action_t ev_actions[NR_EVS];
-void default_handler(u32 port, struct pt_regs *regs);
+void default_handler(int port, struct pt_regs *regs);
 
 
 /*
@@ -32,7 +32,6 @@
 int do_event(u32 port, struct pt_regs *regs)
 {
     ev_action_t  *action;
-
     if (port >= NR_EVS) {
         printk("Port number too large: %d\n", port);
         return 0;
@@ -57,11 +56,23 @@
 
 }
 
+void bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
+{
+       if(ev_actions[port].handler)
+        printk("WARN: Handler for port %d already registered, replacing\n",
+                               port);
+
+       ev_actions[port].handler = handler;
+       ev_actions[port].status &= ~EVS_DISABLED;         
+ 
+       /* Finally unmask the port */
+       unmask_evtchn(port);
+}
+
 int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
 {
        evtchn_op_t op;
        int ret = 0;
-       u32 port;
 
        /* Try to bind the virq to a port */
        op.cmd = EVTCHNOP_bind_virq;
@@ -73,21 +84,12 @@
                printk("Failed to bind virtual IRQ %d\n", virq);
                goto out;
     }
-
-    port = op.u.bind_virq.port;
-       
-       if(ev_actions[port].handler)
-        printk("WARN: Handler for port %d already registered, replacing\n",
-                               port);
-
-       ev_actions[port].handler = handler;
-       ev_actions[port].status &= ~EVS_DISABLED;
-       
-       /* Finally unmask the port */
-       unmask_evtchn(port);
+    bind_evtchn(op.u.bind_virq.port, handler); 
 out:
        return ret;
 }
+
+
 
 /*
  * Initially all events are without a handler and disabled
@@ -100,10 +102,10 @@
     for ( i = 0; i < NR_EVS; i++ )
     {
         ev_actions[i].status  = EVS_DISABLED;
-        ev_actions[i].handler = NULL;
+        ev_actions[i].handler = default_handler;
     }
 }
 
-void default_handler(u32 port, struct pt_regs *regs) {
+void default_handler(int port, struct pt_regs *regs) {
     printk("[Port %d] - event received\n", port);
 }
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/events.h   Wed Sep  7 18:10:45 2005
@@ -20,6 +20,7 @@
 #define _EVENTS_H_
 
 #include<traps.h>
+#include <xen/event_channel.h>
 
 #define NR_EVS 1024
 
@@ -39,6 +40,16 @@
 /* prototypes */
 int do_event(u32 port, struct pt_regs *regs);
 int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) );
+void bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *) );
 void init_events(void);
 
+static inline int notify_via_evtchn(int port)
+{
+    evtchn_op_t op;
+    op.cmd = EVTCHNOP_send;
+    op.u.send.local_port = port;
+    return HYPERVISOR_event_channel_op(&op);
+}
+
+
 #endif /* _EVENTS_H_ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/hypervisor.h
--- a/extras/mini-os/include/hypervisor.h       Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/hypervisor.h       Wed Sep  7 18:10:45 2005
@@ -13,7 +13,6 @@
 #define _HYPERVISOR_H_
 
 #include <types.h>
-
 #include <xen/xen.h>
 #include <xen/io/domain_controller.h>
 
@@ -40,48 +39,26 @@
 /*
  * 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)
+#if defined(__i386__)
+static inline int
+HYPERVISOR_set_trap_table(
+    trap_info_t *table)
 {
     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, 
-                                            domid_t domid)
+       : "0" (__HYPERVISOR_set_trap_table), "1" (table)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_mmu_update(
+    mmu_update_t *req, int count, int *success_count, domid_t domid)
 {
     int ret;
     unsigned long ign1, ign2, ign3, ign4;
@@ -89,18 +66,16 @@
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
-        : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
-          "3" (success_count), "4" (domid)
-        : "memory" );
-
-    return ret;
-}
-
-
-static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, 
-                                           int count, 
-                                           int *success_count, 
-                                           domid_t domid)
+       : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
+        "3" (success_count), "4" (domid)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_mmuext_op(
+    struct mmuext_op *op, int count, int *success_count, domid_t domid)
 {
     int ret;
     unsigned long ign1, ign2, ign3, ign4;
@@ -108,70 +83,65 @@
     __asm__ __volatile__ (
         TRAP_INSTR
         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
-        : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
-          "3" (success_count), "4" (domid)
-        : "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(
+       : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
+        "3" (success_count), "4" (domid)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_set_gdt(
+    unsigned long *frame_list, int entries)
+{
+    int ret;
+    unsigned long ign1, ign2;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
+       : "memory" );
+
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_stack_switch(
+    unsigned long ss, unsigned long esp)
+{
+    int ret;
+    unsigned long ign1, ign2;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
+       : "memory" );
+
+    return ret;
+}
+
+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
+    unsigned long ign1, ign2, ign3, ign4;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+       : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
+         "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
 HYPERVISOR_fpu_taskswitch(
     int set)
 {
@@ -187,67 +157,106 @@
     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;
+static inline int
+HYPERVISOR_yield(
+    void)
+{
+    int ret;
+    unsigned long ign;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign)
+       : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
+       : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_block(
+    void)
+{
+    int ret;
+    unsigned long ign1;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
+       : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_shutdown(
+    void)
+{
+    int ret;
+    unsigned long ign1;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
+        : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_reboot(
+    void)
+{
+    int ret;
+    unsigned long ign1;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
+        : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_suspend(
+    unsigned long srec)
+{
+    int ret;
+    unsigned long ign1, ign2;
+
     /* 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 )
+        : "=a" (ret), "=b" (ign1), "=S" (ign2)
+       : "0" (__HYPERVISOR_sched_op),
+        "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 
+        "S" (srec) : "memory", "ecx");
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_crash(
+    void)
+{
+    int ret;
+    unsigned long ign1;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
+        : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline long
+HYPERVISOR_set_timer_op(
+    u64 timeout)
 {
     int ret;
     unsigned long timeout_hi = (unsigned long)(timeout>>32);
@@ -262,8 +271,516 @@
 
     return ret;
 }
+
+#if 0
+static inline int
+HYPERVISOR_dom0_op(
+    dom0_op_t *dom0_op)
+{
+    int ret;
+    unsigned long ign1;
+
+    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
+       : "memory");
+
+    return ret;
+}
+#endif
+
+static inline int
+HYPERVISOR_set_debugreg(
+    int reg, unsigned long value)
+{
+    int ret;
+    unsigned long ign1, ign2;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
+       : "memory" );
+
+    return ret;
+}
+
+static inline unsigned long
+HYPERVISOR_get_debugreg(
+    int reg)
+{
+    unsigned long ret;
+    unsigned long ign;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign)
+       : "0" (__HYPERVISOR_get_debugreg), "1" (reg)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_update_descriptor(
+    u64 ma, u64 desc)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+       : "0" (__HYPERVISOR_update_descriptor),
+         "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)),
+         "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32))
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_dom_mem_op(
+    unsigned int op, unsigned long *extent_list,
+    unsigned long nr_extents, unsigned int extent_order)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4, ign5;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
+         "=D" (ign5)
+       : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
+         "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
+        : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_multicall(
+    void *call_list, int nr_calls)
+{
+    int ret;
+    unsigned long ign1, ign2;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_update_va_mapping(
+    unsigned long va, pte_t new_val, unsigned long flags)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
+       : "0" (__HYPERVISOR_update_va_mapping), 
+          "1" (va), "2" ((new_val).pte_low),
+#ifdef CONFIG_X86_PAE
+         "3" ((new_val).pte_high),
 #else
-static __inline__ long HYPERVISOR_set_timer_op( u64 timeout )
+         "3" (0),
+#endif
+         "4" (flags)
+       : "memory" );
+
+    return ret;
+}
+
+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_xen_version(
+    int cmd)
+{
+    int ret;
+    unsigned long ignore;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ignore)
+       : "0" (__HYPERVISOR_xen_version), "1" (cmd)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_console_io(
+    int cmd, int count, char *str)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
+       : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_physdev_op(
+    void *physdev_op)
+{
+    int ret;
+    unsigned long ign;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign)
+       : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_grant_table_op(
+    unsigned int cmd, void *uop, unsigned int count)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
+       : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_update_va_mapping_otherdomain(
+    unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
+{
+    int ret;
+    unsigned long ign1, ign2, ign3, ign4, ign5;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3),
+         "=S" (ign4), "=D" (ign5)
+       : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
+          "1" (va), "2" ((new_val).pte_low),
+#ifdef CONFIG_X86_PAE
+         "3" ((new_val).pte_high),
+#else
+         "3" (0),
+#endif
+         "4" (flags), "5" (domid) :
+        "memory" );
+    
+    return ret;
+}
+
+static inline int
+HYPERVISOR_vm_assist(
+    unsigned int cmd, unsigned int type)
+{
+    int ret;
+    unsigned long ign1, ign2;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
+       : "memory" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_boot_vcpu(
+    unsigned long vcpu, vcpu_guest_context_t *ctxt)
+{
+    int ret;
+    unsigned long ign1, ign2;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
+       : "memory");
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_vcpu_down(
+    int vcpu)
+{
+    int ret;
+    unsigned long ign1;
+    /* Yes, I really do want to clobber edx here: when we resume a
+       vcpu after unpickling a multi-processor domain, it returns
+       here, but clobbers all of the call clobbered registers. */
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
+        : "memory", "ecx", "edx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_vcpu_up(
+    int vcpu)
+{
+    int ret;
+    unsigned long ign1;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift))
+        : "memory", "ecx" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_vcpu_pickle(
+    int vcpu, vcpu_guest_context_t *ctxt)
+{
+    int ret;
+    unsigned long ign1, ign2;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret), "=b" (ign1), "=c" (ign2)
+       : "0" (__HYPERVISOR_sched_op),
+         "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
+         "2" (ctxt)
+        : "memory" );
+
+    return ret;
+}
+#elif defined(__x86_64__)
+
+#define __syscall_clobber "r11","rcx","memory"
+
+/*
+ * Assembler stubs for hyper-calls.
+ */
+static inline int
+HYPERVISOR_set_trap_table(
+    trap_info_t *table)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_set_trap_table), "D" (table)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_mmu_update(
+    mmu_update_t *req, int count, int *success_count, domid_t domid)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        "movq %5, %%r10;" TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_mmu_update), "D" (req), "S" 
((long)count),
+         "d" (success_count), "g" ((unsigned long)domid)
+       : __syscall_clobber, "r10" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_mmuext_op(
+    struct mmuext_op *op, int count, int *success_count, domid_t domid)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        "movq %5, %%r10;" TRAP_INSTR
+        : "=a" (ret)
+        : "0" (__HYPERVISOR_mmuext_op), "D" (op), "S" ((long)count), 
+          "d" (success_count), "g" ((unsigned long)domid)
+        : __syscall_clobber, "r10" );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_set_gdt(
+    unsigned long *frame_list, int entries)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_set_gdt), "D" (frame_list), "S" 
((long)entries)
+       : __syscall_clobber );
+
+
+    return ret;
+}
+static inline int
+HYPERVISOR_stack_switch(
+    unsigned long ss, unsigned long esp)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_stack_switch), "D" (ss), "S" (esp)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+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" ((unsigned long)__HYPERVISOR_set_callbacks), "D" (event_address),
+         "S" (failsafe_address), "d" (syscall_address)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_fpu_taskswitch(
+    int set)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_fpu_taskswitch),
+          "D" ((unsigned long) set) : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_yield(
+    void)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned 
long)SCHEDOP_yield)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_block(
+    void)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned 
long)SCHEDOP_block)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_shutdown(
+    void)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_sched_op),
+         "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_poweroff << 
SCHEDOP_reasonshift)))
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_reboot(
+    void)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_sched_op),
+         "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_reboot << 
SCHEDOP_reasonshift)))
+       : __syscall_clobber );
+
+    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" ((unsigned long)__HYPERVISOR_sched_op),
+        "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_suspend << 
SCHEDOP_reasonshift))), 
+        "S" (srec)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+/*
+ * We can have the timeout value in a single argument for the hypercall, but
+ * that will break the common code. 
+ */
+static inline long
+HYPERVISOR_set_timer_op(
+    u64 timeout)
 {
     int ret;
 
@@ -276,108 +793,286 @@
 
     return ret;
 }
+
+#if 0
+static inline int
+HYPERVISOR_dom0_op(
+    dom0_op_t *dom0_op)
+{
+    int ret;
+
+    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_dom0_op), "D" (dom0_op)
+       : __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)
+static inline int
+HYPERVISOR_set_debugreg(
+    int reg, unsigned long value)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_set_debugreg), "D" ((unsigned 
long)reg), "S" (value)
+       : __syscall_clobber );
+
+    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;
-}
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_get_debugreg), "D" ((unsigned 
long)reg)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_update_descriptor(
+    unsigned long ma, unsigned long word)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_update_descriptor), "D" (ma),
+         "S" (word)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_dom_mem_op(
+    unsigned int op, unsigned long *extent_list,
+    unsigned long nr_extents, unsigned int extent_order)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        "movq %5,%%r10; movq %6,%%r8;" TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_dom_mem_op), "D" ((unsigned 
long)op), "S" (extent_list),
+         "d" (nr_extents), "g" ((unsigned long) extent_order), "g" ((unsigned 
long) DOMID_SELF)
+       : __syscall_clobber,"r8","r10");
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_multicall(
+    void *call_list, int nr_calls)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_multicall), "D" (call_list), "S" 
((unsigned long)nr_calls)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_update_va_mapping(
+    unsigned long page_nr, pte_t new_val, unsigned long flags)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_update_va_mapping), 
+          "D" (page_nr), "S" (new_val.pte), "d" (flags)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_event_channel_op(
+    void *op)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_event_channel_op), "D" (op)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_xen_version(
+    int cmd)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_xen_version), "D" ((unsigned 
long)cmd)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_console_io(
+    int cmd, int count, char *str)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_console_io), "D" ((unsigned 
long)cmd), "S" ((unsigned long)count), "d" (str)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_physdev_op(
+    void *physdev_op)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_physdev_op), "D" (physdev_op)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_grant_table_op(
+    unsigned int cmd, void *uop, unsigned int count)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_grant_table_op), "D" ((unsigned 
long)cmd), "S" ((unsigned long)uop), "d" (count)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+#if 0
+static inline int
+HYPERVISOR_update_va_mapping_otherdomain(
+    unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        "movq %5, %%r10;" TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_update_va_mapping_otherdomain),
+          "D" (page_nr), "S" (new_val.pte), "d" (flags), "g" ((unsigned 
long)domid)
+       : __syscall_clobber,"r10");
+    
+    return ret;
+}
+#endif
+
+static inline int
+HYPERVISOR_vm_assist(
+    unsigned int cmd, unsigned int type)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_vm_assist), "D" ((unsigned 
long)cmd), "S" ((unsigned long)type)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_switch_to_user(void)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_switch_to_user) : 
__syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_boot_vcpu(
+    unsigned long vcpu, vcpu_guest_context_t *ctxt)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" (__HYPERVISOR_boot_vcpu), "D" (vcpu), "S" (ctxt)
+       : __syscall_clobber);
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_set_segment_base(
+    int reg, unsigned long value)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_set_segment_base), "D" ((unsigned 
long)reg), "S" (value)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+static inline int
+HYPERVISOR_vcpu_pickle(
+    int vcpu, vcpu_guest_context_t *ctxt)
+{
+    int ret;
+
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret)
+       : "0" ((unsigned long)__HYPERVISOR_sched_op),
+       "D" ((unsigned long)SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
+       "S" ((unsigned long)ctxt)
+       : __syscall_clobber );
+
+    return ret;
+}
+
+
+#else
+#error "Unsupported architecture"
+#endif
 
 #endif /* __HYPERVISOR_H__ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h      Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/lib.h      Wed Sep  7 18:10:45 2005
@@ -60,10 +60,22 @@
 /* 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);
+#define _p(_x) ((void *)(unsigned long)(_x))
+void printf(const char *fmt, ...);
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int snprintf(char * buf, size_t size, const char *fmt, ...);
+int scnprintf(char * buf, size_t size, const char *fmt, ...);
+int vsprintf(char *buf, const char *fmt, va_list args);
+int sprintf(char * buf, const char *fmt, ...);
+int vsscanf(const char * buf, const char * fmt, va_list args);
+int sscanf(const char * buf, const char * fmt, ...);
+
+long simple_strtol(const char *cp,char **endp,unsigned int base);
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
+long long simple_strtoll(const char *cp,char **endp,unsigned int base);
+unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int 
base);
+
 
 /* string and memory manipulation */
 int    memcmp(const void *cs, const void *ct, size_t count);
@@ -77,6 +89,16 @@
 size_t strlen(const char *s);
 char  *strchr(const char *s, int c);
 char  *strstr(const char *s1, const char *s2);
+char * strcat(char * dest, const char * src);
+
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+struct kvec {
+    void *iov_base;
+    size_t iov_len;
+};
+
 
 
 #endif /* _LIB_H_ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/mm.h       Wed Sep  7 18:10:45 2005
@@ -24,6 +24,15 @@
 
 #ifndef _MM_H_
 #define _MM_H_
+
+#ifdef __i386__
+#include <xen/arch-x86_32.h>
+#endif
+
+#ifdef __x86_64__
+#include <xen/arch-x86_64.h>
+#endif
+
 
 #ifdef __x86_64__
 
@@ -56,6 +65,8 @@
 
 #define L1_PAGETABLE_ENTRIES    1024
 #define L2_PAGETABLE_ENTRIES    1024
+
+#elif defined(__x86_64__)
 #endif
 
 /* Given a virtual address, get an entry offset into a page table. */
@@ -97,13 +108,15 @@
 
 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 >> L1_PAGETABLE_SHIFT);
     machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK);
     return machine;
 }
+
+
+#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
 static __inline__ unsigned long machine_to_phys(unsigned long machine)
 {
     unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT);
@@ -119,16 +132,15 @@
 
 #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
 
 #define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
+#define mach_to_virt(_mach)        (to_virt(machine_to_phys(_mach)))
+#define mfn_to_virt(_mfn)          (mach_to_virt(_mfn << PAGE_SHIFT))
 
 void init_mm(void);
 unsigned long alloc_pages(int order);
 #define alloc_page()    alloc_pages(0);
 void free_pages(void *pointer, int order);
-//int is_mfn_mapped(unsigned long mfn);
 
 static __inline__ int get_order(unsigned long size)
 {
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/os.h
--- a/extras/mini-os/include/os.h       Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/os.h       Wed Sep  7 18:10:45 2005
@@ -15,15 +15,16 @@
 #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>
+#include <hypervisor.h>
 #endif
 #include <xen/xen.h>
+
+
+#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0))
 
 #define __KERNEL_CS  FLAT_KERNEL_CS
 #define __KERNEL_DS  FLAT_KERNEL_DS
@@ -54,8 +55,6 @@
 /* Everything below this point is not included by assembler (.S) files. */
 #ifndef __ASSEMBLY__
 
-#define pt_regs xen_regs
-
 void trap_init(void);
 
 /* 
@@ -69,10 +68,8 @@
 #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)
 
@@ -80,13 +77,11 @@
 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)                                                        
\
@@ -100,15 +95,12 @@
 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)
@@ -116,11 +108,9 @@
 #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)
 
@@ -135,6 +125,15 @@
 
 /* This is a barrier for the compiler only, NOT the processor! */
 #define barrier() __asm__ __volatile__("": : :"memory")
+
+#if defined(__i386__)
+#define mb()    __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#define rmb()   __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
+#elif defined(__x86_64__)
+#define mb()    __asm__ __volatile__ ("mfence":::"memory")
+#define rmb()   __asm__ __volatile__ ("lfence":::"memory")
+#endif
+
 
 #define LOCK_PREFIX ""
 #define LOCK ""
@@ -147,69 +146,71 @@
 typedef struct { volatile int counter; } atomic_t;
 
 
-#define xchg(ptr,v) \
-        ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+/************************** i386 *******************************/
+#if defined (__i386__)
+
+#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;
+#define __xg(x) ((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
+ * @nr: Bit to clear
  * @addr: Address to count from
  *
- * This operation is atomic and cannot be reordered.  
+ * This operation is atomic and cannot be reordered.
+ * It can be reorderdered on other architectures other than x86.
  * 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;
+static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__( LOCK
+               "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 unsigned long *addr)
+{
+       return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
+}
+
+static inline int variable_test_bit(int nr, const volatile unsigned long * 
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) \
@@ -217,6 +218,152 @@
  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: there are no guarantees that this function will not be reordered
+ * on non x86 architectures, so if you are writting portable code,
+ * make sure not to rely on its reordering 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 unsigned long * addr)
+{
+       __asm__ __volatile__( LOCK
+               "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 unsigned long * addr)
+{
+       __asm__ __volatile__( LOCK
+               "btrl %1,%0"
+               :"=m" (ADDR)
+               :"Ir" (nr));
+}
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+       __asm__("bsfl %1,%0"
+               :"=r" (word)
+               :"rm" (word));
+       return word;
+}
+
+
+/*
+ * These have to be done with inline assembly: that way the bit-setting
+ * is guaranteed to be atomic. All bit operations return 0 if the bit
+ * was cleared before the operation and != 0 if it was not.
+ *
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+#define ADDR (*(volatile long *) addr)
+
+#define rdtscll(val) \
+     __asm__ __volatile__("rdtsc" : "=A" (val))
+
+
+
+#elif defined(__x86_64__)/* ifdef __i386__ */
+/************************** x86_84 *******************************/
+
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned 
long)(v),(ptr),sizeof(*(ptr))))
+#define __xg(x) ((volatile long *)(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 %k0,%1"
+                               :"=r" (x)
+                               :"m" (*__xg(ptr)), "0" (x)
+                               :"memory");
+                       break;
+               case 8:
+                       __asm__ __volatile__("xchgq %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 clear
+ * @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)
+               :"dIr" (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 const void * addr)
+{
+       int oldbit;
+
+       __asm__ __volatile__(
+               "btl %2,%1\n\tsbbl %0,%0"
+               :"=r" (oldbit)
+               :"m" (ADDR),"dIr" (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
@@ -230,10 +377,10 @@
  */
 static __inline__ void set_bit(int nr, volatile void * addr)
 {
-        __asm__ __volatile__( LOCK_PREFIX
-                "btsl %1,%0"
-                :"=m" (ADDR)
-                :"Ir" (nr));
+       __asm__ __volatile__( LOCK_PREFIX
+               "btsl %1,%0"
+               :"=m" (ADDR)
+               :"dIr" (nr) : "memory");
 }
 
 /**
@@ -248,40 +395,43 @@
  */
 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))
-
+       __asm__ __volatile__( LOCK_PREFIX
+               "btrl %1,%0"
+               :"=m" (ADDR)
+               :"dIr" (nr));
+}
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
 static __inline__ unsigned long __ffs(unsigned long word)
 {
-        __asm__("bsfl %1,%0"
-                :"=r" (word)
-                :"rm" (word));
-        return word;
+       __asm__("bsfq %1,%0"
+               :"=r" (word)
+               :"rm" (word));
+       return word;
 }
 
 #define ADDR (*(volatile long *) addr)
+
+#define rdtscll(val) do { \
+     unsigned int __a,__d; \
+     asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
+     (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
+} while(0)
+
+
+#else /* ifdef __x86_64__ */
+#error "Unsupported architecture"
+#endif
+
+
+/********************* common i386 and x86_64  ****************************/
+
+
 
 static __inline__ void synch_set_bit(int nr, volatile void * addr)
 {
@@ -306,6 +456,14 @@
     return oldbit;
 }
 
+static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
+{
+    int oldbit;
+    __asm__ __volatile__ (
+        "lock btrl %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)
 {
@@ -326,9 +484,8 @@
 (__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 /* not assembly */
 #endif /* _OS_H_ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/time.h
--- a/extras/mini-os/include/time.h     Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/time.h     Wed Sep  7 18:10:45 2005
@@ -58,6 +58,6 @@
 s_time_t get_s_time(void);
 s_time_t get_v_time(void);
 void     gettimeofday(struct timeval *tv);
-void     block(u32 millisecs);
+void     block_domain(u32 millisecs);
 
 #endif /* _TIME_H_ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/traps.h
--- a/extras/mini-os/include/traps.h    Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/traps.h    Wed Sep  7 18:10:45 2005
@@ -17,6 +17,7 @@
 #ifndef _TRAPS_H_
 #define _TRAPS_H_
 
+#ifdef __i386__
 struct pt_regs {
        long ebx;
        long ecx;
@@ -34,7 +35,38 @@
        long esp;
        int  xss;
 };
+#elif __x86_64__
 
+struct pt_regs {
+       unsigned long r15;
+       unsigned long r14;
+       unsigned long r13;
+       unsigned long r12;
+       unsigned long rbp;
+       unsigned long rbx;
+/* arguments: non interrupts/non tracing syscalls only save upto here*/
+       unsigned long r11;
+       unsigned long r10;      
+       unsigned long r9;
+       unsigned long r8;
+       unsigned long rax;
+       unsigned long rcx;
+       unsigned long rdx;
+       unsigned long rsi;
+       unsigned long rdi;
+       unsigned long orig_rax;
+/* end of arguments */         
+/* cpu exception frame or undefined */
+       unsigned long rip;
+       unsigned long cs;
+       unsigned long eflags; 
+       unsigned long rsp; 
+       unsigned long ss;
+/* top of stack page */ 
+};
+
+
+#endif
 
 void dump_regs(struct pt_regs *regs);
 
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/types.h
--- a/extras/mini-os/include/types.h    Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/types.h    Wed Sep  7 18:10:45 2005
@@ -44,11 +44,19 @@
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
 typedef unsigned int        uintptr_t;
+
+typedef struct { unsigned long pte_low; } pte_t;
 #elif defined(__x86_64__)
 typedef long                quad_t;
 typedef unsigned long       u_quad_t;
 typedef unsigned long       uintptr_t;
+
+typedef struct { unsigned long pte; } pte_t;
 #endif
 
+
+
+
+#define INT_MAX         ((int)(~0U>>1))
 #define UINT_MAX            (~0U)
 #endif /* _TYPES_H_ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/kernel.c   Wed Sep  7 18:10:45 2005
@@ -33,6 +33,8 @@
 #include <time.h>
 #include <types.h>
 #include <lib.h>
+#include <sched.h>
+#include <xenbus.h>
 
 /*
  * Shared page for communicating with the hypervisor.
@@ -59,10 +61,12 @@
 
 extern char shared_info[PAGE_SIZE];
 
+#define __pte(x) ((pte_t) { (0) } )
+
 static shared_info_t *map_shared_info(unsigned long pa)
 {
     if ( HYPERVISOR_update_va_mapping(
-        (unsigned long)shared_info, pa | 7, UVMF_INVLPG) )
+        (unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG) )
     {
         printk("Failed to map shared_info!!\n");
         *(int*)0=0;
@@ -77,7 +81,6 @@
 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. */
@@ -96,7 +99,6 @@
         (unsigned long)hypervisor_callback,
         (unsigned long)failsafe_callback, 0);
 #endif
-
     trap_init();
 
     /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
@@ -119,7 +121,6 @@
      * If used for porting another OS, start here to figure out your
      * guest os entry point. Otherwise continue below...
      */
-
     /* init memory management */
     init_mm();
 
@@ -127,15 +128,15 @@
     init_events();
     /* init time and timers */
     init_time();
+    
+    /* init scheduler */
+    init_sched();
 
-    /* do nothing */
-    i = 0;
-    for ( ; ; ) 
-    {      
-//        HYPERVISOR_yield();
-        block(100);
-        i++;
-    }
+    /* init xenbus */
+    xs_init();
+    
+    /* Everything initialised, start idle thread */
+    run_idle_thread();
 }
 
 
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/lib/printf.c
--- a/extras/mini-os/lib/printf.c       Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/lib/printf.c       Wed Sep  7 18:10:45 2005
@@ -1,20 +1,18 @@
-/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
+/* 
  ****************************************************************************
  * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
  ****************************************************************************
  *
  *        File: printf.c
  *      Author: Rolf Neugebauer (neugebar@xxxxxxxxxxxxx)
- *     Changes: 
+ *     Changes: Grzegorz Milos (gm281@xxxxxxxxx) 
  *              
- *        Date: Aug 2003
+ *        Date: Aug 2003, Aug 2005
  * 
  * Environment: Xen Minimal OS
  * Description: Library functions for printing
  *              (freebsd port, mainly sys/subr_prf.c)
  *
- ****************************************************************************
- * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
  ****************************************************************************
  *
  *-
@@ -60,409 +58,748 @@
 #include <types.h>
 #include <hypervisor.h>
 #include <lib.h>
-
-/****************************************************************************
- * RN: printf family of routines
- * taken mainly from sys/subr_prf.c
- ****************************************************************************/
-char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-#define hex2ascii(hex)  (hex2ascii_data[hex])
-#define NBBY    8               /* number of bits in a byte */
-#define MAXNBUF    (sizeof(quad_t) * NBBY + 1)
-
-static int kvprintf(char const *fmt, void *arg, int radix, va_list ap);
-
-
-int
-printf(const char *fmt, ...)
-{
-       va_list ap;
-       int retval;
-    static char printk_buf[1024];
-
-       va_start(ap, fmt);
-       retval = kvprintf(fmt, printk_buf, 10, ap);
-    printk_buf[retval] = '\0';
-       va_end(ap);
-    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(printk_buf), 
-                                printk_buf);
-       return retval;
-}
-
-int
-vprintf(const char *fmt, va_list ap)
-{
-       int retval;
-    static char printk_buf[1024];
-       retval = kvprintf(fmt, printk_buf, 10, ap);
-    printk_buf[retval] = '\0';
-    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(printk_buf),
-                                printk_buf);
-       return retval;
-}
-
-int
-sprintf(char *buf, const char *cfmt, ...)
-{
-       int retval;
-       va_list ap;
-
-       va_start(ap, cfmt);
-       retval = kvprintf(cfmt, (void *)buf, 10, ap);
-       buf[retval] = '\0';
-       va_end(ap);
-       return retval;
-}
-
-int
-vsprintf(char *buf, const char *cfmt, va_list ap)
-{
-       int retval;
-
-       retval = kvprintf(cfmt, (void *)buf, 10, ap);
-       buf[retval] = '\0';
-       return retval;
-}
-
-
-/*
- * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
- * order; return an optional length and a pointer to the last character
- * written in the buffer (i.e., the first character of the string).
- * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
- */
-static char *
-ksprintn(char *nbuf, u_long ul, int base, int *lenp)
-{
-       char *p;
-
-       p = nbuf;
-       *p = '\0';
-       do {
-               *++p = hex2ascii(ul % base);
-       } while (ul /= base);
-       if (lenp)
-               *lenp = p - nbuf;
-       return (p);
-}
-/* ksprintn, but for a quad_t. */
-static char *
-ksprintqn(char *nbuf, u_quad_t uq, int base, int *lenp)
-{
-       char *p;
-
-       p = nbuf;
-       *p = '\0';
-       do {
-               *++p = hex2ascii(uq % base);
-       } while (uq /= base);
-       if (lenp)
-               *lenp = p - nbuf;
-       return (p);
-}
-
-/*
- * Scaled down version of printf(3).
+#include <mm.h>
+#include <ctype.h>
+
+/**
+ * simple_strtoul - convert a string to an unsigned long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+    unsigned long result = 0,value;
+
+    if (!base) {
+        base = 10;
+        if (*cp == '0') {
+            base = 8;
+            cp++;
+            if ((*cp == 'x') && isxdigit(cp[1])) {
+                cp++;
+                base = 16;
+            }
+        }
+    }
+    while (isxdigit(*cp) &&
+           (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+        result = result*base + value;
+        cp++;
+    }
+    if (endp)
+        *endp = (char *)cp;
+    return result;
+}
+
+/**
+ * simple_strtol - convert a string to a signed long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+    if(*cp=='-')
+        return -simple_strtoul(cp+1,endp,base);
+    return simple_strtoul(cp,endp,base);
+}
+
+/**
+ * simple_strtoull - convert a string to an unsigned long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int 
base)
+{
+    unsigned long long result = 0,value;
+
+    if (!base) {
+        base = 10;
+        if (*cp == '0') {
+            base = 8;
+            cp++;
+            if ((*cp == 'x') && isxdigit(cp[1])) {
+                cp++;
+                base = 16;
+            }
+        }
+    }
+    while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+                                                               ? toupper(*cp) 
: *cp)-'A'+10) < base) {
+        result = result*base + value;
+        cp++;
+    }
+    if (endp)
+        *endp = (char *)cp;
+    return result;
+}
+
+/**
+ * simple_strtoll - convert a string to a signed long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+{
+    if(*cp=='-')
+        return -simple_strtoull(cp+1,endp,base);
+    return simple_strtoull(cp,endp,base);
+}
+
+static int skip_atoi(const char **s)
+{
+    int i=0;
+
+    while (isdigit(**s))
+        i = i*10 + *((*s)++) - '0';
+    return i;
+}
+
+#define ZEROPAD 1               /* pad with zero */
+#define SIGN    2               /* unsigned/signed long */
+#define PLUS    4               /* show plus */
+#define SPACE   8               /* space if plus */
+#define LEFT    16              /* left justified */
+#define SPECIAL 32              /* 0x */
+#define LARGE   64              /* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * buf, char * end, long long num, int base, int 
size, int precision, int type)
+{
+    char c,sign,tmp[66];
+    const char *digits;
+    const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+    const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    int i;
+
+    digits = (type & LARGE) ? large_digits : small_digits;
+    if (type & LEFT)
+        type &= ~ZEROPAD;
+    if (base < 2 || base > 36)
+        return buf;
+    c = (type & ZEROPAD) ? '0' : ' ';
+    sign = 0;
+    if (type & SIGN) {
+        if (num < 0) {
+            sign = '-';
+            num = -num;
+            size--;
+        } else if (type & PLUS) {
+            sign = '+';
+            size--;
+        } else if (type & SPACE) {
+            sign = ' ';
+            size--;
+        }
+    }
+    if (type & SPECIAL) {
+        if (base == 16)
+            size -= 2;
+        else if (base == 8)
+            size--;
+    }
+    i = 0;
+    if (num == 0)
+        tmp[i++]='0';
+    else 
+    {
+        /* XXX KAF: force unsigned mod and div. */
+        unsigned long long num2=(unsigned long long)num;
+        unsigned int base2=(unsigned int)base;
+        while (num2 != 0) { tmp[i++] = digits[num2%base2]; num2 /= base2; }
+    }
+    if (i > precision)
+        precision = i;
+    size -= precision;
+    if (!(type&(ZEROPAD+LEFT))) {
+        while(size-->0) {
+            if (buf <= end)
+                *buf = ' ';
+            ++buf;
+        }
+    }
+    if (sign) {
+        if (buf <= end)
+            *buf = sign;
+        ++buf;
+    }
+    if (type & SPECIAL) {
+        if (base==8) {
+            if (buf <= end)
+                *buf = '0';
+            ++buf;
+        } else if (base==16) {
+            if (buf <= end)
+                *buf = '0';
+            ++buf;
+            if (buf <= end)
+                *buf = digits[33];
+            ++buf;
+        }
+    }
+    if (!(type & LEFT)) {
+        while (size-- > 0) {
+            if (buf <= end)
+                *buf = c;
+            ++buf;
+        }
+    }
+    while (i < precision--) {
+        if (buf <= end)
+            *buf = '0';
+        ++buf;
+    }
+    while (i-- > 0) {
+        if (buf <= end)
+            *buf = tmp[i];
+        ++buf;
+    }
+    while (size-- > 0) {
+        if (buf <= end)
+            *buf = ' ';
+        ++buf;
+    }
+    return buf;
+}
+
+/**
+* vsnprintf - Format a string and place it in a buffer
+* @buf: The buffer to place the result into
+* @size: The size of the buffer, including the trailing null space
+* @fmt: The format string to use
+* @args: Arguments for the format string
+*
+* Call this function if you are already dealing with a va_list.
+* You probably want snprintf instead.
+ */
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+    int len;
+    unsigned long long num;
+    int i, base;
+    char *str, *end, c;
+    const char *s;
+
+    int flags;          /* flags to number() */
+
+    int field_width;    /* width of output field */
+    int precision;              /* min. # of digits for integers; max
+                                   number of chars for from string */
+    int qualifier;              /* 'h', 'l', or 'L' for integer fields */
+                                /* 'z' support added 23/7/1999 S.H.    */
+                                /* 'z' changed to 'Z' --davidm 1/25/99 */
+
+    str = buf;
+    end = buf + size - 1;
+
+    if (end < buf - 1) {
+        end = ((void *) -1);
+        size = end - buf + 1;
+    }
+
+    for (; *fmt ; ++fmt) {
+        if (*fmt != '%') {
+            if (str <= end)
+                *str = *fmt;
+            ++str;
+            continue;
+        }
+
+        /* process flags */
+        flags = 0;
+    repeat:
+        ++fmt;          /* this also skips first '%' */
+        switch (*fmt) {
+        case '-': flags |= LEFT; goto repeat;
+        case '+': flags |= PLUS; goto repeat;
+        case ' ': flags |= SPACE; goto repeat;
+        case '#': flags |= SPECIAL; goto repeat;
+        case '0': flags |= ZEROPAD; goto repeat;
+        }
+
+        /* get field width */
+        field_width = -1;
+        if (isdigit(*fmt))
+            field_width = skip_atoi(&fmt);
+        else if (*fmt == '*') {
+            ++fmt;
+            /* it's the next argument */
+            field_width = va_arg(args, int);
+            if (field_width < 0) {
+                field_width = -field_width;
+                flags |= LEFT;
+            }
+        }
+
+        /* get the precision */
+        precision = -1;
+        if (*fmt == '.') {
+            ++fmt;
+            if (isdigit(*fmt))
+                precision = skip_atoi(&fmt);
+            else if (*fmt == '*') {
+                ++fmt;
+                          /* it's the next argument */
+                precision = va_arg(args, int);
+            }
+            if (precision < 0)
+                precision = 0;
+        }
+
+        /* get the conversion qualifier */
+        qualifier = -1;
+        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+            qualifier = *fmt;
+            ++fmt;
+            if (qualifier == 'l' && *fmt == 'l') {
+                qualifier = 'L';
+                ++fmt;
+            }
+        }
+        if (*fmt == 'q') {
+            qualifier = 'L';
+            ++fmt;
+        }
+
+        /* default base */
+        base = 10;
+
+        switch (*fmt) {
+        case 'c':
+            if (!(flags & LEFT)) {
+                while (--field_width > 0) {
+                    if (str <= end)
+                        *str = ' ';
+                    ++str;
+                }
+            }
+            c = (unsigned char) va_arg(args, int);
+            if (str <= end)
+                *str = c;
+            ++str;
+            while (--field_width > 0) {
+                if (str <= end)
+                    *str = ' ';
+                ++str;
+            }
+            continue;
+
+        case 's':
+            s = va_arg(args, char *);
+            if (!s)
+                s = "<NULL>";
+
+            len = strnlen(s, precision);
+
+            if (!(flags & LEFT)) {
+                while (len < field_width--) {
+                    if (str <= end)
+                        *str = ' ';
+                    ++str;
+                }
+            }
+            for (i = 0; i < len; ++i) {
+                if (str <= end)
+                    *str = *s;
+                ++str; ++s;
+            }
+            while (len < field_width--) {
+                if (str <= end)
+                    *str = ' ';
+                ++str;
+            }
+            continue;
+
+        case 'p':
+            if (field_width == -1) {
+                field_width = 2*sizeof(void *);
+                flags |= ZEROPAD;
+            }
+            str = number(str, end,
+                         (unsigned long) va_arg(args, void *),
+                         16, field_width, precision, flags);
+            continue;
+
+
+        case 'n':
+            /* FIXME:
+             * What does C99 say about the overflow case here? */
+            if (qualifier == 'l') {
+                long * ip = va_arg(args, long *);
+                *ip = (str - buf);
+            } else if (qualifier == 'Z') {
+                size_t * ip = va_arg(args, size_t *);
+                *ip = (str - buf);
+            } else {
+                int * ip = va_arg(args, int *);
+                *ip = (str - buf);
+            }
+            continue;
+
+        case '%':
+            if (str <= end)
+                *str = '%';
+            ++str;
+            continue;
+
+                        /* integer number formats - set up the flags and 
"break" */
+        case 'o':
+            base = 8;
+            break;
+
+        case 'X':
+            flags |= LARGE;
+        case 'x':
+            base = 16;
+            break;
+
+        case 'd':
+        case 'i':
+            flags |= SIGN;
+        case 'u':
+            break;
+
+        default:
+            if (str <= end)
+                *str = '%';
+            ++str;
+            if (*fmt) {
+                if (str <= end)
+                    *str = *fmt;
+                ++str;
+            } else {
+                --fmt;
+            }
+            continue;
+        }
+        if (qualifier == 'L')
+            num = va_arg(args, long long);
+        else if (qualifier == 'l') {
+            num = va_arg(args, unsigned long);
+            if (flags & SIGN)
+                num = (signed long) num;
+        } else if (qualifier == 'Z') {
+            num = va_arg(args, size_t);
+        } else if (qualifier == 'h') {
+            num = (unsigned short) va_arg(args, int);
+            if (flags & SIGN)
+                num = (signed short) num;
+        } else {
+            num = va_arg(args, unsigned int);
+            if (flags & SIGN)
+                num = (signed int) num;
+        }
+
+        str = number(str, end, num, base,
+                     field_width, precision, flags);
+    }
+    if (str <= end)
+        *str = '\0';
+    else if (size > 0)
+        /* don't write out a null byte if the buf size is zero */
+        *end = '\0';
+    /* the trailing null byte doesn't count towards the total
+     * ++str;
+     */
+    return str-buf;
+}
+
+/**
+ * snprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ */
+int snprintf(char * buf, size_t size, const char *fmt, ...)
+{
+    va_list args;
+    int i;
+
+    va_start(args, fmt);
+    i=vsnprintf(buf,size,fmt,args);
+    va_end(args);
+    return i;
+}
+
+/**
+ * vsprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
  *
- * Two additional formats:
- *
- * The format %b is supported to decode error registers.
- * Its usage is:
- *
- *     printf("reg=%b\n", regval, "<base><arg>*");
- *
- * where <base> is the output base expressed as a control character, e.g.
- * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
- * the first of which gives the bit number to be inspected (origin 1), and
- * the next characters (up to a control character, i.e. a character <= 32),
- * give the name of the register.  Thus:
- *
- *     kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
- *
- * would produce output:
- *
- *     reg=3<BITTWO,BITONE>
- *
- * XXX:  %D  -- Hexdump, takes pointer and separator string:
- *             ("%6D", ptr, ":")   -> XX:XX:XX:XX:XX:XX
- *             ("%*D", len, ptr, " " -> XX XX XX XX ...
- */
-
-/* RN: This normally takes a function for output. 
- * we always print to a string and the use HYPERCALL for write to console */
-static int
-kvprintf(char const *fmt, void *arg, int radix, va_list ap)
-{
-
-#define PCHAR(c) {int cc=(c); *d++ = cc; retval++; }
-
-       char nbuf[MAXNBUF];
-       char *p, *q, *d;
-       u_char *up;
-       int ch, n;
-       u_long ul;
-       u_quad_t uq;
-       int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
-       int dwidth;
-       char padc;
-       int retval = 0;
-
-       ul = 0;
-       uq = 0;
-    d = (char *) arg;
-
-       if (fmt == NULL)
-               fmt = "(fmt null)\n";
-
-       if (radix < 2 || radix > 36)
-               radix = 10;
-
-       for (;;) {
-               padc = ' ';
-               width = 0;
-               while ((ch = (u_char)*fmt++) != '%') {
-                       if (ch == '\0') 
-                               return retval;
-                       PCHAR(ch);
-               }
-               qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
-               sign = 0; dot = 0; dwidth = 0;
-reswitch:      switch (ch = (u_char)*fmt++) {
-               case '.':
-                       dot = 1;
-                       goto reswitch;
-               case '#':
-                       sharpflag = 1;
-                       goto reswitch;
-               case '+':
-                       sign = 1;
-                       goto reswitch;
-               case '-':
-                       ladjust = 1;
-                       goto reswitch;
-               case '%':
-                       PCHAR(ch);
-                       break;
-               case '*':
-                       if (!dot) {
-                               width = va_arg(ap, int);
-                               if (width < 0) {
-                                       ladjust = !ladjust;
-                                       width = -width;
+ * Call this function if you are already dealing with a va_list.
+ * You probably want sprintf instead.
+ */
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+    return vsnprintf(buf, 0xFFFFFFFFUL, fmt, args);
+}
+
+
+/**
+ * sprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ */
+int sprintf(char * buf, const char *fmt, ...)
+{
+    va_list args;
+    int i;
+
+    va_start(args, fmt);
+    i=vsprintf(buf,fmt,args);
+    va_end(args);
+    return i;
+}
+
+
+void printf(const char *fmt, ...)
+{
+    static char   buf[1024];
+    va_list       args;
+    
+    va_start(args, fmt);
+    (void)vsnprintf(buf, sizeof(buf), fmt, args);
+    va_end(args);        
+   
+    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
+}
+
+/**
+ * vsscanf - Unformat a buffer into a list of arguments
+ * @buf:       input buffer
+ * @fmt:       format of buffer
+ * @args:      arguments
+ */
+int vsscanf(const char * buf, const char * fmt, va_list args)
+{
+       const char *str = buf;
+       char *next;
+       char digit;
+       int num = 0;
+       int qualifier;
+       int base;
+       int field_width;
+       int is_sign = 0;
+
+       while(*fmt && *str) {
+               /* skip any white space in format */
+               /* white space in format matchs any amount of
+                * white space, including none, in the input.
+                */
+               if (isspace(*fmt)) {
+                       while (isspace(*fmt))
+                               ++fmt;
+                       while (isspace(*str))
+                               ++str;
+               }
+
+               /* anything that is not a conversion must match exactly */
+               if (*fmt != '%' && *fmt) {
+                       if (*fmt++ != *str++)
+                               break;
+                       continue;
+               }
+
+               if (!*fmt)
+                       break;
+               ++fmt;
+               
+               /* skip this conversion.
+                * advance both strings to next white space
+                */
+               if (*fmt == '*') {
+                       while (!isspace(*fmt) && *fmt)
+                               fmt++;
+                       while (!isspace(*str) && *str)
+                               str++;
+                       continue;
+               }
+
+               /* get field width */
+               field_width = -1;
+               if (isdigit(*fmt))
+                       field_width = skip_atoi(&fmt);
+
+               /* get conversion qualifier */
+               qualifier = -1;
+               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+                   *fmt == 'Z' || *fmt == 'z') {
+                       qualifier = *fmt++;
+                       if (unlikely(qualifier == *fmt)) {
+                               if (qualifier == 'h') {
+                                       qualifier = 'H';
+                                       fmt++;
+                               } else if (qualifier == 'l') {
+                                       qualifier = 'L';
+                                       fmt++;
                                }
-                       } else {
-                               dwidth = va_arg(ap, int);
                        }
-                       goto reswitch;
-               case '0':
-                       if (!dot) {
-                               padc = '0';
-                               goto reswitch;
+               }
+               base = 10;
+               is_sign = 0;
+
+               if (!*fmt || !*str)
+                       break;
+
+               switch(*fmt++) {
+               case 'c':
+               {
+                       char *s = (char *) va_arg(args,char*);
+                       if (field_width == -1)
+                               field_width = 1;
+                       do {
+                               *s++ = *str++;
+                       } while (--field_width > 0 && *str);
+                       num++;
+               }
+               continue;
+               case 's':
+               {
+                       char *s = (char *) va_arg(args, char *);
+                       if(field_width == -1)
+                               field_width = INT_MAX;
+                       /* first, skip leading white space in buffer */
+                       while (isspace(*str))
+                               str++;
+
+                       /* now copy until next white space */
+                       while (*str && !isspace(*str) && field_width--) {
+                               *s++ = *str++;
                        }
-               case '1': case '2': case '3': case '4':
-               case '5': case '6': case '7': case '8': case '9':
-                               for (n = 0;; ++fmt) {
-                                       n = n * 10 + ch - '0';
-                                       ch = *fmt;
-                                       if (ch < '0' || ch > '9')
-                                               break;
-                               }
-                       if (dot)
-                               dwidth = n;
-                       else
-                               width = n;
-                       goto reswitch;
-               case 'b':
-                       ul = va_arg(ap, int);
-                       p = va_arg(ap, char *);
-                       for (q = ksprintn(nbuf, ul, *p++, NULL); *q;)
-                               PCHAR(*q--);
-
-                       if (!ul)
-                               break;
-
-                       for (tmp = 0; *p;) {
-                               n = *p++;
-                               if (ul & (1 << (n - 1))) {
-                                       PCHAR(tmp ? ',' : '<');
-                                       for (; (n = *p) > ' '; ++p)
-                                               PCHAR(n);
-                                       tmp = 1;
-                               } else
-                                       for (; *p > ' '; ++p)
-                                               continue;
-                       }
-                       if (tmp)
-                               PCHAR('>');
-                       break;
-               case 'c':
-                       PCHAR(va_arg(ap, int));
-                       break;
-               case 'D':
-                       up = va_arg(ap, u_char *);
-                       p = va_arg(ap, char *);
-                       if (!width)
-                               width = 16;
-                       while(width--) {
-                               PCHAR(hex2ascii(*up >> 4));
-                               PCHAR(hex2ascii(*up & 0x0f));
-                               up++;
-                               if (width)
-                                       for (q=p;*q;q++)
-                                               PCHAR(*q);
-                       }
-                       break;
-               case 'd':
-                       if (qflag)
-                               uq = va_arg(ap, quad_t);
-                       else if (lflag)
-                               ul = va_arg(ap, long);
-                       else
-                               ul = va_arg(ap, int);
-                       sign = 1;
-                       base = 10;
-                       goto number;
-               case 'l':
-                       if (lflag) {
-                               lflag = 0;
-                               qflag = 1;
-                       } else
-                               lflag = 1;
-                       goto reswitch;
+                       *s = '\0';
+                       num++;
+               }
+               continue;
+               case 'n':
+                       /* return number of characters read so far */
+               {
+                       int *i = (int *)va_arg(args,int*);
+                       *i = str - buf;
+               }
+               continue;
                case 'o':
-                       if (qflag)
-                               uq = va_arg(ap, u_quad_t);
-                       else if (lflag)
-                               ul = va_arg(ap, u_long);
-                       else
-                               ul = va_arg(ap, u_int);
                        base = 8;
-                       goto nosign;
-               case 'p':
-                       ul = (uintptr_t)va_arg(ap, void *);
-                       base = 16;
-                       sharpflag = 0;
-            padc  = '0';
-            width = sizeof(uintptr_t)*2;
-                       goto nosign;
-               case 'q':
-                       qflag = 1;
-                       goto reswitch;
-               case 'n':
-               case 'r':
-                       if (qflag)
-                               uq = va_arg(ap, u_quad_t);
-                       else if (lflag)
-                               ul = va_arg(ap, u_long);
-                       else
-                               ul = sign ?
-                                   (u_long)va_arg(ap, int) : va_arg(ap, u_int);
-                       base = radix;
-                       goto number;
-               case 's':
-                       p = va_arg(ap, char *);
-                       if (p == NULL)
-                               p = "(null)";
-                       if (!dot)
-                               n = strlen (p);
-                       else
-                               for (n = 0; n < dwidth && p[n]; n++)
-                                       continue;
-
-                       width -= n;
-
-                       if (!ladjust && width > 0)
-                               while (width--)
-                                       PCHAR(padc);
-                       while (n--)
-                               PCHAR(*p++);
-                       if (ladjust && width > 0)
-                               while (width--)
-                                       PCHAR(padc);
-                       break;
-               case 'u':
-                       if (qflag)
-                               uq = va_arg(ap, u_quad_t);
-                       else if (lflag)
-                               ul = va_arg(ap, u_long);
-                       else
-                               ul = va_arg(ap, u_int);
-                       base = 10;
-                       goto nosign;
+                       break;
                case 'x':
                case 'X':
-                       if (qflag)
-                               uq = va_arg(ap, u_quad_t);
-                       else if (lflag)
-                               ul = va_arg(ap, u_long);
-                       else
-                               ul = va_arg(ap, u_int);
                        base = 16;
-                       goto nosign;
+                       break;
+               case 'i':
+                        base = 0;
+               case 'd':
+                       is_sign = 1;
+               case 'u':
+                       break;
+               case '%':
+                       /* looking for '%' in str */
+                       if (*str++ != '%') 
+                               return num;
+                       continue;
+               default:
+                       /* invalid format; stop here */
+                       return num;
+               }
+
+               /* have some sort of integer conversion.
+                * first, skip white space in buffer.
+                */
+               while (isspace(*str))
+                       str++;
+
+               digit = *str;
+               if (is_sign && digit == '-')
+                       digit = *(str + 1);
+
+               if (!digit
+                    || (base == 16 && !isxdigit(digit))
+                    || (base == 10 && !isdigit(digit))
+                    || (base == 8 && (!isdigit(digit) || digit > '7'))
+                    || (base == 0 && !isdigit(digit)))
+                               break;
+
+               switch(qualifier) {
+               case 'H':       /* that's 'hh' in format */
+                       if (is_sign) {
+                               signed char *s = (signed char *) 
va_arg(args,signed char *);
+                               *s = (signed char) 
simple_strtol(str,&next,base);
+                       } else {
+                               unsigned char *s = (unsigned char *) 
va_arg(args, unsigned char *);
+                               *s = (unsigned char) simple_strtoul(str, &next, 
base);
+                       }
+                       break;
+               case 'h':
+                       if (is_sign) {
+                               short *s = (short *) va_arg(args,short *);
+                               *s = (short) simple_strtol(str,&next,base);
+                       } else {
+                               unsigned short *s = (unsigned short *) 
va_arg(args, unsigned short *);
+                               *s = (unsigned short) simple_strtoul(str, 
&next, base);
+                       }
+                       break;
+               case 'l':
+                       if (is_sign) {
+                               long *l = (long *) va_arg(args,long *);
+                               *l = simple_strtol(str,&next,base);
+                       } else {
+                               unsigned long *l = (unsigned long*) 
va_arg(args,unsigned long*);
+                               *l = simple_strtoul(str,&next,base);
+                       }
+                       break;
+               case 'L':
+                       if (is_sign) {
+                               long long *l = (long long*) va_arg(args,long 
long *);
+                               *l = simple_strtoll(str,&next,base);
+                       } else {
+                               unsigned long long *l = (unsigned long long*) 
va_arg(args,unsigned long long*);
+                               *l = simple_strtoull(str,&next,base);
+                       }
+                       break;
+               case 'Z':
                case 'z':
-                       if (qflag)
-                               uq = va_arg(ap, u_quad_t);
-                       else if (lflag)
-                               ul = va_arg(ap, u_long);
-                       else
-                               ul = sign ?
-                                   (u_long)va_arg(ap, int) : va_arg(ap, u_int);
-                       base = 16;
-                       goto number;
-nosign:                        sign = 0;
-number:                        
-                       if (qflag) {
-                               if (sign && (quad_t)uq < 0) {
-                                       neg = 1;
-                                       uq = -(quad_t)uq;
-                               }
-                               p = ksprintqn(nbuf, uq, base, &tmp);
+               {
+                       size_t *s = (size_t*) va_arg(args,size_t*);
+                       *s = (size_t) simple_strtoul(str,&next,base);
+               }
+               break;
+               default:
+                       if (is_sign) {
+                               int *i = (int *) va_arg(args, int*);
+                               *i = (int) simple_strtol(str,&next,base);
                        } else {
-                               if (sign && (long)ul < 0) {
-                                       neg = 1;
-                                       ul = -(long)ul;
-                               }
-                               p = ksprintn(nbuf, ul, base, &tmp);
+                               unsigned int *i = (unsigned int*) va_arg(args, 
unsigned int*);
+                               *i = (unsigned int) 
simple_strtoul(str,&next,base);
                        }
-                       if (sharpflag && (qflag ? uq != 0 : ul != 0)) {
-                               if (base == 8)
-                                       tmp++;
-                               else if (base == 16)
-                                       tmp += 2;
-                       }
-                       if (neg)
-                               tmp++;
-
-                       if (!ladjust && width && (width -= tmp) > 0)
-                               while (width--)
-                                       PCHAR(padc);
-                       if (neg)
-                               PCHAR('-');
-                       if (sharpflag && (qflag ? uq != 0 : ul != 0)) {
-                               if (base == 8) {
-                                       PCHAR('0');
-                               } else if (base == 16) {
-                                       PCHAR('0');
-                                       PCHAR('x');
-                               }
-                       }
-
-                       while (*p)
-                               PCHAR(*p--);
-
-                       if (ladjust && width && (width -= tmp) > 0)
-                               while (width--)
-                                       PCHAR(padc);
-
-                       break;
-               default:
-                       PCHAR('%');
-                       if (lflag)
-                               PCHAR('l');
-                       PCHAR(ch);
-                       break;
-               }
+                       break;
+               }
+               num++;
+
+               if (!next)
+                       break;
+               str = next;
        }
-#undef PCHAR
-}
-
+       return num;
+}
+
+/**
+ * sscanf - Unformat a buffer into a list of arguments
+ * @buf:       input buffer
+ * @fmt:       formatting of buffer
+ * @...:       resulting arguments
+ */
+int sscanf(const char * buf, const char * fmt, ...)
+{
+       va_list args;
+       int i;
+
+       va_start(args,fmt);
+       i = vsscanf(buf,fmt,args);
+       va_end(args);
+       return i;
+}
+
+
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/lib/string.c
--- a/extras/mini-os/lib/string.c       Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/lib/string.c       Wed Sep  7 18:10:45 2005
@@ -107,6 +107,19 @@
         return sc - s;
 }
 
+
+char * strcat(char * dest, const char * src)
+{
+    char *tmp = dest;
+    
+    while (*dest)
+        dest++;
+    
+    while ((*dest++ = *src++) != '\0');
+    
+    return tmp;
+}
+
 size_t strlen(const char * s)
 {
        const char *sc;
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/mm.c
--- a/extras/mini-os/mm.c       Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/mm.c       Wed Sep  7 18:10:45 2005
@@ -198,7 +198,6 @@
 #endif
 
 
-
 /*
  * Initialise allocator, placing addresses [@min,@max] in free pool.
  * @min and @max are PHYSICAL addresses.
@@ -486,16 +485,17 @@
     phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
    
     /* First page follows page table pages and 3 more pages (store page etc) */
-    start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames + 3;
+    start_pfn = PFN_UP(to_phys(start_info.pt_base)) + start_info.nr_pt_frames 
+ 3;
     max_pfn = start_info.nr_pages;
 
     printk("  start_pfn:    %lx\n", start_pfn);
     printk("  max_pfn:      %lx\n", max_pfn);
 
 
+#ifdef __i386__
     build_pagetable(&start_pfn, &max_pfn);
-    
-#ifdef __i386__
+#endif
+
     /*
      * now we can initialise the page allocator
      */
@@ -503,7 +503,5 @@
            (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
            (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
     init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));   
-#endif
-    
     printk("MM: done\n");
 }
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/time.c
--- a/extras/mini-os/time.c     Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/time.c     Wed Sep  7 18:10:45 2005
@@ -203,7 +203,7 @@
 }
 
 
-void block(u32 millisecs)
+void block_domain(u32 millisecs)
 {
     struct timeval tv;
     gettimeofday(&tv);
@@ -232,5 +232,6 @@
 
 void init_time(void)
 {
+    printk("Initialising timer interface\n");
     bind_virq(VIRQ_TIMER, &timer_handler);
 }
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/traps.c
--- a/extras/mini-os/traps.c    Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/traps.c    Wed Sep  7 18:10:45 2005
@@ -33,36 +33,7 @@
 
 void dump_regs(struct pt_regs *regs)
 {
-    unsigned long esp;
-    unsigned short ss;
-
-#ifdef __x86_64__
-    esp = regs->rsp;
-    ss  = regs->xss;
-#else
-    esp = (unsigned long) (&regs->esp);
-    ss = __KERNEL_DS;
-    if (regs->xcs & 2) {
-printk("CS is true, esp is %x\n", regs->esp);
-        esp = regs->esp;
-        ss = regs->xss & 0xffff;
-    }
-#endif
-    printf("EIP:    %04x:[<%p>]\n",
-           0xffff & regs->xcs , regs->eip);
-    printf("EFLAGS: %p\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);
-#ifdef __x86_64__
-    printf("r8 : %p   r9 : %p   r10: %p   r11: %p\n",
-           regs->r8,  regs->r9,  regs->r10, regs->r11);
-    printf("r12: %p   r13: %p   r14: %p   r15: %p\n",
-           regs->r12, regs->r13, regs->r14, regs->r15);
-#endif
-    printf("ds: %04x   es: %04x   ss: %04x\n",
-           regs->xds & 0xffff, regs->xes & 0xffff, ss);
+    printk("FIXME: proper register dump (with the stack dump)\n");
 }      
 
 
@@ -105,6 +76,7 @@
     printk("Page fault at linear address %p\n", addr);
     dump_regs(regs);
 #ifdef __x86_64__
+    /* FIXME: _PAGE_PSE */
     {
         unsigned long *tab = (unsigned long *)start_info.pt_base;
         unsigned long page;
@@ -112,23 +84,16 @@
         printk("Pagetable walk from %p:\n", tab);
         
         page = tab[l4_table_offset(addr)];
-        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
+        tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
         printk(" L4 = %p (%p)\n", page, tab);
-        if ( !(page & AGERESENT) )
-            goto out;
 
         page = tab[l3_table_offset(addr)];
-        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
+        tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
         printk("  L3 = %p (%p)\n", page, tab);
-        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 & AGESE) ? "(2MB)" : "");
-        if ( !(page & AGERESENT) || (page & AGESE) )
-            goto out;
+        tab =  to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
+        printk("   L2 = %p (%p)\n", page, tab);
         
         page = tab[l1_table_offset(addr)];
         printk("    L1 = %p\n", page);
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/ctype.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/ctype.h    Wed Sep  7 18:10:45 2005
@@ -0,0 +1,79 @@
+#ifndef _CTYPE_H
+#define _CTYPE_H
+
+/*
+ * NOTE! This ctype does not handle EOF like the standard C
+ * library is required to.
+ */
+
+#define _U     0x01    /* upper */
+#define _L     0x02    /* lower */
+#define _D     0x04    /* digit */
+#define _C     0x08    /* cntrl */
+#define _P     0x10    /* punct */
+#define _S     0x20    /* white space (space/lf/tab) */
+#define _X     0x40    /* hex digit */
+#define _SP    0x80    /* hard space (0x20) */
+
+
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c)     ((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c)     ((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c)     ((__ismask(c)&(_C)) != 0)
+#define isdigit(c)     ((__ismask(c)&(_D)) != 0)
+#define isgraph(c)     ((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c)     ((__ismask(c)&(_L)) != 0)
+#define isprint(c)     ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c)     ((__ismask(c)&(_P)) != 0)
+#define isspace(c)     ((__ismask(c)&(_S)) != 0)
+#define isupper(c)     ((__ismask(c)&(_U)) != 0)
+#define isxdigit(c)    ((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+static inline unsigned char __tolower(unsigned char c)
+{
+       if (isupper(c))
+               c -= 'A'-'a';
+       return c;
+}
+
+static inline unsigned char __toupper(unsigned char c)
+{
+       if (islower(c))
+               c -= 'a'-'A';
+       return c;
+}
+
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+
+#endif
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/err.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/err.h      Wed Sep  7 18:10:45 2005
@@ -0,0 +1,31 @@
+#ifndef _ERR_H
+#define _ERR_H
+
+#include <errno.h>
+
+/*
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a dentry
+ * pointer with the same return value.
+ *
+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ */
+#define IS_ERR_VALUE(x) ((x) > (unsigned long)-1000L)
+
+static inline void *ERR_PTR(long error)
+{
+       return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+       return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+       return IS_ERR_VALUE((unsigned long)ptr);
+}
+
+#endif /* _LINUX_ERR_H */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/errno-base.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/errno-base.h       Wed Sep  7 18:10:45 2005
@@ -0,0 +1,39 @@
+#ifndef _ERRNO_BASE_H
+#define _ERRNO_BASE_H
+
+#define        EPERM            1      /* Operation not permitted */
+#define        ENOENT           2      /* No such file or directory */
+#define        ESRCH            3      /* No such process */
+#define        EINTR            4      /* Interrupted system call */
+#define        EIO              5      /* I/O error */
+#define        ENXIO            6      /* No such device or address */
+#define        E2BIG            7      /* Argument list too long */
+#define        ENOEXEC          8      /* Exec format error */
+#define        EBADF            9      /* Bad file number */
+#define        ECHILD          10      /* No child processes */
+#define        EAGAIN          11      /* Try again */
+#define        ENOMEM          12      /* Out of memory */
+#define        EACCES          13      /* Permission denied */
+#define        EFAULT          14      /* Bad address */
+#define        ENOTBLK         15      /* Block device required */
+#define        EBUSY           16      /* Device or resource busy */
+#define        EEXIST          17      /* File exists */
+#define        EXDEV           18      /* Cross-device link */
+#define        ENODEV          19      /* No such device */
+#define        ENOTDIR         20      /* Not a directory */
+#define        EISDIR          21      /* Is a directory */
+#define        EINVAL          22      /* Invalid argument */
+#define        ENFILE          23      /* File table overflow */
+#define        EMFILE          24      /* Too many open files */
+#define        ENOTTY          25      /* Not a typewriter */
+#define        ETXTBSY         26      /* Text file busy */
+#define        EFBIG           27      /* File too large */
+#define        ENOSPC          28      /* No space left on device */
+#define        ESPIPE          29      /* Illegal seek */
+#define        EROFS           30      /* Read-only file system */
+#define        EMLINK          31      /* Too many links */
+#define        EPIPE           32      /* Broken pipe */
+#define        EDOM            33      /* Math argument out of domain of func 
*/
+#define        ERANGE          34      /* Math result not representable */
+
+#endif
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/errno.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/errno.h    Wed Sep  7 18:10:45 2005
@@ -0,0 +1,109 @@
+#ifndef _ERRNO_H
+#define _ERRNO_H
+
+#include <errno-base.h>
+
+#define        EDEADLK         35      /* Resource deadlock would occur */
+#define        ENAMETOOLONG    36      /* File name too long */
+#define        ENOLCK          37      /* No record locks available */
+#define        ENOSYS          38      /* Function not implemented */
+#define        ENOTEMPTY       39      /* Directory not empty */
+#define        ELOOP           40      /* Too many symbolic links encountered 
*/
+#define        EWOULDBLOCK     EAGAIN  /* Operation would block */
+#define        ENOMSG          42      /* No message of desired type */
+#define        EIDRM           43      /* Identifier removed */
+#define        ECHRNG          44      /* Channel number out of range */
+#define        EL2NSYNC        45      /* Level 2 not synchronized */
+#define        EL3HLT          46      /* Level 3 halted */
+#define        EL3RST          47      /* Level 3 reset */
+#define        ELNRNG          48      /* Link number out of range */
+#define        EUNATCH         49      /* Protocol driver not attached */
+#define        ENOCSI          50      /* No CSI structure available */
+#define        EL2HLT          51      /* Level 2 halted */
+#define        EBADE           52      /* Invalid exchange */
+#define        EBADR           53      /* Invalid request descriptor */
+#define        EXFULL          54      /* Exchange full */
+#define        ENOANO          55      /* No anode */
+#define        EBADRQC         56      /* Invalid request code */
+#define        EBADSLT         57      /* Invalid slot */
+
+#define        EDEADLOCK       EDEADLK
+
+#define        EBFONT          59      /* Bad font file format */
+#define        ENOSTR          60      /* Device not a stream */
+#define        ENODATA         61      /* No data available */
+#define        ETIME           62      /* Timer expired */
+#define        ENOSR           63      /* Out of streams resources */
+#define        ENONET          64      /* Machine is not on the network */
+#define        ENOPKG          65      /* Package not installed */
+#define        EREMOTE         66      /* Object is remote */
+#define        ENOLINK         67      /* Link has been severed */
+#define        EADV            68      /* Advertise error */
+#define        ESRMNT          69      /* Srmount error */
+#define        ECOMM           70      /* Communication error on send */
+#define        EPROTO          71      /* Protocol error */
+#define        EMULTIHOP       72      /* Multihop attempted */
+#define        EDOTDOT         73      /* RFS specific error */
+#define        EBADMSG         74      /* Not a data message */
+#define        EOVERFLOW       75      /* Value too large for defined data 
type */
+#define        ENOTUNIQ        76      /* Name not unique on network */
+#define        EBADFD          77      /* File descriptor in bad state */
+#define        EREMCHG         78      /* Remote address changed */
+#define        ELIBACC         79      /* Can not access a needed shared 
library */
+#define        ELIBBAD         80      /* Accessing a corrupted shared library 
*/
+#define        ELIBSCN         81      /* .lib section in a.out corrupted */
+#define        ELIBMAX         82      /* Attempting to link in too many 
shared libraries */
+#define        ELIBEXEC        83      /* Cannot exec a shared library 
directly */
+#define        EILSEQ          84      /* Illegal byte sequence */
+#define        ERESTART        85      /* Interrupted system call should be 
restarted */
+#define        ESTRPIPE        86      /* Streams pipe error */
+#define        EUSERS          87      /* Too many users */
+#define        ENOTSOCK        88      /* Socket operation on non-socket */
+#define        EDESTADDRREQ    89      /* Destination address required */
+#define        EMSGSIZE        90      /* Message too long */
+#define        EPROTOTYPE      91      /* Protocol wrong type for socket */
+#define        ENOPROTOOPT     92      /* Protocol not available */
+#define        EPROTONOSUPPORT 93      /* Protocol not supported */
+#define        ESOCKTNOSUPPORT 94      /* Socket type not supported */
+#define        EOPNOTSUPP      95      /* Operation not supported on transport 
endpoint */
+#define        EPFNOSUPPORT    96      /* Protocol family not supported */
+#define        EAFNOSUPPORT    97      /* Address family not supported by 
protocol */
+#define        EADDRINUSE      98      /* Address already in use */
+#define        EADDRNOTAVAIL   99      /* Cannot assign requested address */
+#define        ENETDOWN        100     /* Network is down */
+#define        ENETUNREACH     101     /* Network is unreachable */
+#define        ENETRESET       102     /* Network dropped connection because 
of reset */
+#define        ECONNABORTED    103     /* Software caused connection abort */
+#define        ECONNRESET      104     /* Connection reset by peer */
+#define        ENOBUFS         105     /* No buffer space available */
+#define        EISCONN         106     /* Transport endpoint is already 
connected */
+#define        ENOTCONN        107     /* Transport endpoint is not connected 
*/
+#define        ESHUTDOWN       108     /* Cannot send after transport endpoint 
shutdown */
+#define        ETOOMANYREFS    109     /* Too many references: cannot splice */
+#define        ETIMEDOUT       110     /* Connection timed out */
+#define        ECONNREFUSED    111     /* Connection refused */
+#define        EHOSTDOWN       112     /* Host is down */
+#define        EHOSTUNREACH    113     /* No route to host */
+#define        EALREADY        114     /* Operation already in progress */
+#define        EINPROGRESS     115     /* Operation now in progress */
+#define        ESTALE          116     /* Stale NFS file handle */
+#define        EUCLEAN         117     /* Structure needs cleaning */
+#define        ENOTNAM         118     /* Not a XENIX named type file */
+#define        ENAVAIL         119     /* No XENIX semaphores available */
+#define        EISNAM          120     /* Is a named type file */
+#define        EREMOTEIO       121     /* Remote I/O error */
+#define        EDQUOT          122     /* Quota exceeded */
+
+#define        ENOMEDIUM       123     /* No medium found */
+#define        EMEDIUMTYPE     124     /* Wrong medium type */
+#define        ECANCELED       125     /* Operation Canceled */
+#define        ENOKEY          126     /* Required key not available */
+#define        EKEYEXPIRED     127     /* Key has expired */
+#define        EKEYREVOKED     128     /* Key has been revoked */
+#define        EKEYREJECTED    129     /* Key was rejected by service */
+
+/* for robust mutexes */
+#define        EOWNERDEAD      130     /* Owner died */
+#define        ENOTRECOVERABLE 131     /* State not recoverable */
+
+#endif
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/fcntl.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/fcntl.h    Wed Sep  7 18:10:45 2005
@@ -0,0 +1,89 @@
+#ifndef _I386_FCNTL_H
+#define _I386_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE         0003
+#define O_RDONLY            00
+#define O_WRONLY            01
+#define O_RDWR              02
+#define O_CREAT                   0100 /* not fcntl */
+#define O_EXCL            0200 /* not fcntl */
+#define O_NOCTTY          0400 /* not fcntl */
+#define O_TRUNC                  01000 /* not fcntl */
+#define O_APPEND         02000
+#define O_NONBLOCK       04000
+#define O_NDELAY       O_NONBLOCK
+#define O_SYNC          010000
+#define FASYNC          020000 /* fcntl, for BSD compatibility */
+#define O_DIRECT        040000 /* direct disk access hint */
+#define O_LARGEFILE    0100000
+#define O_DIRECTORY    0200000 /* must be a directory */
+#define O_NOFOLLOW     0400000 /* don't follow links */
+#define O_NOATIME      01000000
+
+#define F_DUPFD                0       /* dup */
+#define F_GETFD                1       /* get close_on_exec */
+#define F_SETFD                2       /* set/clear close_on_exec */
+#define F_GETFL                3       /* get file->f_flags */
+#define F_SETFL                4       /* set file->f_flags */
+#define F_GETLK                5
+#define F_SETLK                6
+#define F_SETLKW       7
+
+#define F_SETOWN       8       /*  for sockets. */
+#define F_GETOWN       9       /*  for sockets. */
+#define F_SETSIG       10      /*  for sockets. */
+#define F_GETSIG       11      /*  for sockets. */
+
+#define F_GETLK64      12      /*  using 'struct flock64' */
+#define F_SETLK64      13
+#define F_SETLKW64     14
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC     1       /* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK                0
+#define F_WRLCK                1
+#define F_UNLCK                2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK                4       /* or 3 */
+#define F_SHLCK                8       /* or 4 */
+
+/* for leases */
+#define F_INPROGRESS   16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH                1       /* shared lock */
+#define LOCK_EX                2       /* exclusive lock */
+#define LOCK_NB                4       /* or'd with one of the above to prevent
+                                  blocking */
+#define LOCK_UN                8       /* remove lock */
+
+#define LOCK_MAND      32      /* This is a mandatory flock */
+#define LOCK_READ      64      /* ... Which allows concurrent read operations 
*/
+#define LOCK_WRITE     128     /* ... Which allows concurrent write operations 
*/
+#define LOCK_RW                192     /* ... Which allows concurrent read & 
write ops */
+
+/*
+struct flock {
+       short l_type;
+       short l_whence;
+       off_t l_start;
+       off_t l_len;
+       pid_t l_pid;
+};
+
+struct flock64 {
+       short  l_type;
+       short  l_whence;
+       loff_t l_start;
+       loff_t l_len;
+       pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE  1024
+*/
+#endif
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/list.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/list.h     Wed Sep  7 18:10:45 2005
@@ -0,0 +1,187 @@
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+       struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+       (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries. 
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static __inline__ void __list_add(struct list_head * new,
+       struct list_head * prev,
+       struct list_head * next)
+{
+       next->prev = new;
+       new->next = next;
+       new->prev = prev;
+       prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static __inline__ void list_add(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static __inline__ void list_add_tail(struct list_head *new, struct list_head 
*head)
+{
+       __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static __inline__ void __list_del(struct list_head * prev,
+                                 struct list_head * next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is in 
an undefined state.
+ */
+static __inline__ void list_del(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static __inline__ void list_del_init(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+       INIT_LIST_HEAD(entry); 
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static __inline__ int list_empty(struct list_head *head)
+{
+       return head->next == head;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static __inline__ void list_splice(struct list_head *list, struct list_head 
*head)
+{
+       struct list_head *first = list->next;
+
+       if (first != list) {
+               struct list_head *last = list->prev;
+               struct list_head *at = head->next;
+
+               first->prev = head;
+               head->next = first;
+
+               last->next = at;
+               at->prev = last;
+       }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:       the &struct list_head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+       ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+/**
+ * list_for_each       -       iterate over a list
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @head:      the head for your list.
+ */
+#define list_for_each(pos, head) \
+       for (pos = (head)->next; pos != (head); pos = pos->next)
+               
+/**
+ * list_for_each_safe  -       iterate over a list safe against removal of 
list entry
+ * @pos:       the &struct list_head to use as a loop counter.
+ * @n:         another &struct list_head to use as temporary storage
+ * @head:      the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+       for (pos = (head)->next, n = pos->next; pos != (head); \
+               pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry -       iterate over list of given type
+ * @pos:       the type * to use as a loop counter.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)                         \
+       for (pos = list_entry((head)->next, typeof(*pos), member)       \
+                    /*, prefetch(pos->member.next) */;                 \
+            &pos->member != (head);                                    \
+            pos = list_entry(pos->member.next, typeof(*pos), member)   \
+                    /*,prefetch(pos->member.next)*/)
+
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against 
removal of list entry
+ * @pos:       the type * to use as a loop counter.
+ * @n:         another type * to use as temporary storage
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)                 \
+       for (pos = list_entry((head)->next, typeof(*pos), member),      \
+               n = list_entry(pos->member.next, typeof(*pos), member); \
+            &pos->member != (head);                                    \
+            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif /* _LINUX_LIST_H */
+
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/sched.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/sched.h    Wed Sep  7 18:10:45 2005
@@ -0,0 +1,38 @@
+#ifndef __SCHED_H__
+#define __SCHED_H__
+
+#include <list.h>
+
+struct thread
+{
+    char *name;
+    char *stack;
+    unsigned long eps;
+    unsigned long eip;
+    struct list_head thread_list;
+    u32 flags;
+};
+
+
+
+void init_sched(void);
+void run_idle_thread(void);
+struct thread* create_thread(char *name, void (*function)(void *), void *data);
+void schedule(void);
+
+static inline struct thread* get_current(void)
+{
+    struct thread **current;
+#ifdef __i386__    
+    __asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
+#endif    
+    return *current;
+}
+          
+#define current get_current()
+
+
+void wake(struct thread *thread);
+void block(struct thread *thread);
+
+#endif /* __SCHED_H__ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/semaphore.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/semaphore.h        Wed Sep  7 18:10:45 2005
@@ -0,0 +1,46 @@
+#ifndef _SEMAPHORE_H_
+#define _SEMAPHORE_H_
+
+#include <wait.h>
+
+/*
+ * Implementation of semaphore in Mini-os is simple, because 
+ * there are no preemptive threads, the atomicity is guaranteed.
+ */
+
+struct semaphore
+{
+       int count;
+       struct wait_queue_head wait;
+};
+
+
+#define __SEMAPHORE_INITIALIZER(name, n)                            \
+{                                                                   \
+    .count    = n,                                                  \
+    .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
+}
+
+#define __MUTEX_INITIALIZER(name) \
+    __SEMAPHORE_INITIALIZER(name,1)
+                           
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+    struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+    
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+static void inline down(struct semaphore *sem)
+{
+    wait_event(sem->wait, sem->count > 0);
+    sem->count--;
+}
+
+static void inline up(struct semaphore *sem)
+{
+    sem->count++;
+    wake_up(&sem->wait);
+}
+
+#endif /* _SEMAPHORE_H */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/wait.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/wait.h     Wed Sep  7 18:10:45 2005
@@ -0,0 +1,91 @@
+#ifndef __WAIT_H__
+#define __WAIT_H__
+
+#include <sched.h>
+#include <list.h>
+#include <lib.h>
+#include <os.h>
+
+struct wait_queue
+{
+    struct thread *thread;
+    struct list_head thread_list;
+};
+
+struct wait_queue_head
+{
+    /* TODO - lock required? */
+    struct list_head thread_list;
+};
+
+#define DECLARE_WAIT_QUEUE_HEAD(name) \
+   struct wait_queue_head name =     \
+        { .thread_list = { &(name).thread_list, &(name).thread_list} }
+
+#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                           \
+    .thread_list      = { &(name).thread_list, &(name).thread_list } }
+
+
+#define DEFINE_WAIT(name)                               \
+struct wait_queue name = {                              \
+    .thread       = current,                            \
+    .thread_list  = LIST_HEAD_INIT((name).thread_list), \
+}
+
+
+
+static inline void init_waitqueue_entry(struct wait_queue *q, struct thread 
*thread)
+{
+    q->thread = thread;
+}
+
+
+static inline void add_wait_queue(struct wait_queue_head *h, struct wait_queue 
*q)
+{
+    if (list_empty(&q->thread_list))
+        list_add(&q->thread_list, &h->thread_list);   
+}
+
+static inline void remove_wait_queue(struct wait_queue *q)
+{
+    list_del(&q->thread_list);
+}
+
+static inline void wake_up(struct wait_queue_head *head)
+{
+    struct list_head *tmp, *next;
+    list_for_each_safe(tmp, next, &head->thread_list)
+    {
+         struct wait_queue *curr;
+         curr = list_entry(tmp, struct wait_queue, thread_list);
+         wake(curr->thread);
+    }
+}
+
+#define wait_event(wq, condition) do{             \
+    unsigned long flags;                          \
+    if(condition)                                 \
+        break;                                    \
+    DEFINE_WAIT(__wait);                          \
+    for(;;)                                       \
+    {                                             \
+        /* protect the list */                    \
+        local_irq_save(flags);                    \
+        add_wait_queue(&wq, &__wait);             \
+        block(current);                           \
+        local_irq_restore(flags);                 \
+        if(condition)                             \
+            break;                                \
+        schedule();                               \
+    }                                             \
+    local_irq_save(flags);                        \
+    /* need to wake up */                         \
+    wake(current);                                \
+    remove_wait_queue(&__wait);                   \
+    local_irq_restore(flags);                     \
+} while(0) 
+
+
+
+
+#endif /* __WAIT_H__ */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/include/xenbus.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/include/xenbus.h   Wed Sep  7 18:10:45 2005
@@ -0,0 +1,89 @@
+/******************************************************************************
+ * xenbus.h
+ *
+ * Talks to Xen Store to figure out what devices we have.
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _ASM_XEN_XENBUS_H
+#define _ASM_XEN_XENBUS_H
+
+
+/* Caller must hold this lock to call these functions: it's also held
+ * across watch callbacks. */
+// TODO
+//extern struct semaphore xenbus_lock;
+
+char **xenbus_directory(const char *dir, const char *node, unsigned int *num);
+void *xenbus_read(const char *dir, const char *node, unsigned int *len);
+int xenbus_write(const char *dir, const char *node,
+                const char *string, int createflags);
+int xenbus_mkdir(const char *dir, const char *node);
+int xenbus_exists(const char *dir, const char *node);
+int xenbus_rm(const char *dir, const char *node);
+int xenbus_transaction_start(const char *subtree);
+int xenbus_transaction_end(int abort);
+
+/* Single read and scanf: returns -errno or num scanned if > 0. */
+int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
+       __attribute__((format(scanf, 3, 4)));
+
+/* Single printf and write: returns -errno or 0. */
+int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
+       __attribute__((format(printf, 3, 4)));
+
+/* Generic read function: NULL-terminated triples of name,
+ * sprintf-style type string, and pointer. Returns 0 or errno.*/
+int xenbus_gather(const char *dir, ...);
+
+/* Register callback to watch this node. */
+struct xenbus_watch
+{
+       struct list_head list;
+       char *node;
+       void (*callback)(struct xenbus_watch *, const char *node);
+};
+
+int register_xenbus_watch(struct xenbus_watch *watch);
+void unregister_xenbus_watch(struct xenbus_watch *watch);
+void reregister_xenbus_watches(void);
+
+/* Called from xen core code. */
+void xenbus_suspend(void);
+void xenbus_resume(void);
+
+#define XENBUS_IS_ERR_READ(str) ({                     \
+       if (!IS_ERR(str) && strlen(str) == 0) {         \
+               kfree(str);                             \
+               str = ERR_PTR(-ERANGE);                 \
+       }                                               \
+       IS_ERR(str);                                    \
+})
+
+#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
+
+int xs_init(void);
+
+#endif /* _ASM_XEN_XENBUS_H */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/sched.c
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/sched.c    Wed Sep  7 18:10:45 2005
@@ -0,0 +1,300 @@
+/* 
+ ****************************************************************************
+ * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
+ ****************************************************************************
+ *
+ *        File: sched.c
+ *      Author: Grzegorz Milos
+ *     Changes: 
+ *              
+ *        Date: Aug 2005
+ * 
+ * Environment: Xen Minimal OS
+ * Description: simple scheduler for Mini-Os
+ *
+ * The scheduler is non-preemptive (cooperative), and schedules according 
+ * to Round Robin algorithm.
+ *
+ ****************************************************************************
+ * 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.
+ */
+
+#include <os.h>
+#include <hypervisor.h>
+#include <time.h>
+#include <mm.h>
+#include <types.h>
+#include <lib.h>
+#include <xmalloc.h>
+#include <list.h>
+#include <sched.h>
+#include <semaphore.h>
+
+#ifdef SCHED_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
+
+#define RUNNABLE_FLAG   0x00000001
+
+#define is_runnable(_thread)    (_thread->flags & RUNNABLE_FLAG)
+#define set_runnable(_thread)   (_thread->flags |= RUNNABLE_FLAG)
+#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
+
+
+struct thread *idle_thread;
+LIST_HEAD(exited_threads);
+
+void dump_stack(struct thread *thread)
+{
+    unsigned long *bottom = (unsigned long *)thread->stack + 2048; 
+    unsigned long *pointer = (unsigned long *)thread->eps;
+    int count;
+    printk("The stack for \"%s\"\n", thread->name);
+    for(count = 0; count < 15 && pointer < bottom; count ++)
+    {
+        printk("[0x%lx] 0x%lx\n", pointer, *pointer);
+        pointer++;
+    }
+    
+    if(pointer < bottom) printk("Not the whole stack printed\n");
+}
+
+#ifdef __i386__
+#define switch_threads(prev, next) do {                                 \
+    unsigned long esi,edi;                                              \
+    __asm__ __volatile__("pushfl\n\t"                                   \
+                         "pushl %%ebp\n\t"                              \
+                         "movl %%esp,%0\n\t"         /* save ESP */     \
+                         "movl %4,%%esp\n\t"        /* restore ESP */   \
+                         "movl $1f,%1\n\t"          /* save EIP */      \
+                         "pushl %5\n\t"             /* restore EIP */   \
+                         "ret\n\t"                                      \
+                         "1:\t"                                         \
+                         "popl %%ebp\n\t"                               \
+                         "popfl"                                        \
+                         :"=m" (prev->eps),"=m" (prev->eip),            \
+                          "=S" (esi),"=D" (edi)             \
+                         :"m" (next->eps),"m" (next->eip),              \
+                          "2" (prev), "d" (next));                      \
+} while (0)
+#elif __x86_64__
+/* FIXME */
+#endif
+
+void inline print_runqueue(void)
+{
+    struct list_head *it;
+    struct thread *th;
+    list_for_each(it, &idle_thread->thread_list)
+    {
+        th = list_entry(it, struct thread, thread_list);
+        printk("   Thread \"%s\", runnable=%d\n", th->name, is_runnable(th));
+    }
+    printk("\n");
+}
+
+
+void schedule(void)
+{
+    struct thread *prev, *next, *thread;
+    struct list_head *iterator;
+    unsigned long flags;
+    prev = current;
+    local_irq_save(flags); 
+    list_for_each(iterator, &exited_threads)
+    {
+        thread = list_entry(iterator, struct thread, thread_list);
+        if(thread != prev)
+        {
+            list_del(&thread->thread_list);
+            free_pages(thread->stack, 1);
+            xfree(thread);
+        }
+    }
+    next = idle_thread;    
+    /* Thread list needs to be protected */
+    list_for_each(iterator, &idle_thread->thread_list)
+    {
+        thread = list_entry(iterator, struct thread, thread_list);
+        if(is_runnable(thread)) 
+        {
+            next = thread;
+            /* Put this thread on the end of the list */
+            list_del(&thread->thread_list);
+            list_add_tail(&thread->thread_list, &idle_thread->thread_list);
+            break;
+        }
+    }
+    local_irq_restore(flags);
+    /* Interrupting the switch is equivalent to having the next thread
+       inturrupted at the return instruction. And therefore at safe point. */
+/* The thread switching only works for i386 at the moment */    
+#ifdef __i386__    
+    if(prev != next) switch_threads(prev, next);
+#endif    
+}
+
+
+
+void exit_thread(struct thread *thread)
+{
+    unsigned long flags;
+    printk("Thread \"%s\" exited.\n", thread->name);
+    local_irq_save(flags);
+    /* Remove from the thread list */
+    list_del(&thread->thread_list);
+    clear_runnable(thread);
+    /* Put onto exited list */
+    list_add(&thread->thread_list, &exited_threads);
+    local_irq_restore(flags);
+    /* Schedule will free the resources */
+    schedule();
+}
+
+
+struct thread* create_thread(char *name, void (*function)(void *), void *data)
+{
+    struct thread *thread;
+    unsigned long flags;
+    
+    thread = xmalloc(struct thread);
+    /* Allocate 2 pages for stack, stack will be 2pages aligned */
+    thread->stack = (char *)alloc_pages(1);
+    thread->name = name;
+    printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread, 
+            thread->stack);
+    
+    thread->eps = (unsigned long)thread->stack + 4096 * 2 - 4;
+    /* Save pointer to the thread on the stack, used by current macro */
+    *((unsigned long *)thread->stack) = (unsigned long)thread;
+    *((unsigned long *)thread->eps) = (unsigned long)thread;
+    thread->eps -= 4; 
+    *((unsigned long *)thread->eps) = (unsigned long)data;
+    
+    /* No return address */
+    thread->eps -= 4;
+    *((unsigned long *)thread->eps) = (unsigned long)exit_thread;
+    
+    thread->eip = (unsigned long)function;
+     
+    /* Not runable, not exited */ 
+    thread->flags = 0;
+    set_runnable(thread);
+    
+    local_irq_save(flags);
+    if(idle_thread != NULL)
+        list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
+    local_irq_restore(flags);
+
+    return thread;
+}
+
+
+void block(struct thread *thread)
+{
+    clear_runnable(thread);
+}
+
+void wake(struct thread *thread)
+{
+    set_runnable(thread);
+}
+
+void idle_thread_fn(void *unused)
+{
+    for(;;)
+    {
+        schedule();
+        printk("Blocking the domain\n"); 
+        block_domain(10000);
+    }
+}
+
+void run_idle_thread(void)
+{
+    /* Switch stacks and run the thread */ 
+    __asm__ __volatile__("mov %0,%%esp\n\t"
+                         "push %1\n\t" 
+                         "ret"                                            
+                         :"=m" (idle_thread->eps)
+                         :"m" (idle_thread->eip));                          
+}
+
+
+
+DECLARE_MUTEX(mutex);
+
+void th_f1(void *data)
+{
+    struct timeval tv1, tv2;
+
+    for(;;)
+    {
+        down(&mutex);
+        printk("Thread \"%s\" got semaphore, runnable %d\n", current->name, 
is_runnable(current));
+        schedule();
+        printk("Thread \"%s\" releases the semaphore\n", current->name);
+        up(&mutex);
+        
+        
+        gettimeofday(&tv1);
+        for(;;)
+        {
+            gettimeofday(&tv2);
+            if(tv2.tv_sec - tv1.tv_sec > 2) break;
+        }
+                
+        
+        schedule(); 
+    }
+}
+
+void th_f2(void *data)
+{
+    for(;;)
+    {
+        printk("Thread OTHER executing, data 0x%lx\n", data);
+        schedule();
+    }
+}
+
+
+
+void init_sched(void)
+{
+    printk("Initialising scheduler\n");
+       
+    idle_thread = create_thread("Idle", idle_thread_fn, NULL);
+    INIT_LIST_HEAD(&idle_thread->thread_list);
+
+    
+/*    create_thread("1", th_f1, (void *)0x1234);    
+    create_thread("2", th_f1, (void *)0x1234);    
+    create_thread("3", th_f1, (void *)0x1234);    
+    create_thread("4", th_f1, (void *)0x1234);    
+    create_thread("5", th_f1, (void *)0x1234);    
+    create_thread("6", th_f1, (void *)0x1234);    
+    create_thread("second", th_f2, NULL);
+*/   
+}
+
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/xenbus/Makefile
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/xenbus/Makefile    Wed Sep  7 18:10:45 2005
@@ -0,0 +1,9 @@
+all: xenstore.h xenbus_comms.o xenbus_xs.o xenbus_probe.o
+
+xenstore.h:
+       [ -e xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h 
xenstored.h
+
+clean:
+       #Taken care of by main Makefile
+       #rm xenstored.h
+       #rm *.o
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/xenbus/xenbus_comms.c
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/xenbus/xenbus_comms.c      Wed Sep  7 18:10:45 2005
@@ -0,0 +1,231 @@
+/******************************************************************************
+ * xenbus_comms.c
+ *
+ * Low level code to talks to Xen Store: ringbuffer and event channel.
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include <types.h>
+#include <wait.h>
+#include <mm.h>
+#include <hypervisor.h>
+#include <events.h>
+#include <os.h>
+#include <lib.h>
+
+
+#ifdef XENBUS_COMMS_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(file=xenbus_comms.c, line=%d) " _f "\n", __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
+
+#define RINGBUF_DATASIZE ((PAGE_SIZE / 2) - sizeof(struct ringbuf_head))
+struct ringbuf_head
+{
+       u32 write; /* Next place to write to */
+       u32 read; /* Next place to read from */
+       u8 flags;
+       char buf[0];
+} __attribute__((packed));
+
+DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
+
+static inline struct ringbuf_head *outbuf(void)
+{
+       return mfn_to_virt(start_info.store_mfn);
+}
+
+static inline struct ringbuf_head *inbuf(void)
+{
+       return (struct ringbuf_head *)((char 
*)mfn_to_virt(start_info.store_mfn) + PAGE_SIZE/2);
+}
+
+static void wake_waiting(int port, struct pt_regs *regs)
+{
+       wake_up(&xb_waitq);
+}
+
+static int check_buffer(const struct ringbuf_head *h)
+{
+       return (h->write < RINGBUF_DATASIZE && h->read < RINGBUF_DATASIZE);
+}
+
+/* We can't fill last byte: would look like empty buffer. */
+static void *get_output_chunk(const struct ringbuf_head *h,
+                             void *buf, u32 *len)
+{
+       u32 read_mark;
+
+       if (h->read == 0)
+               read_mark = RINGBUF_DATASIZE - 1;
+       else
+               read_mark = h->read - 1;
+
+       /* Here to the end of buffer, unless they haven't read some out. */
+       *len = RINGBUF_DATASIZE - h->write;
+       if (read_mark >= h->write)
+               *len = read_mark - h->write;
+       return (void *)((char *)buf + h->write);
+}
+
+static const void *get_input_chunk(const struct ringbuf_head *h,
+                                  const void *buf, u32 *len)
+{
+       /* Here to the end of buffer, unless they haven't written some. */
+       *len = RINGBUF_DATASIZE - h->read;
+       if (h->write >= h->read)
+               *len = h->write - h->read;
+       return (void *)((char *)buf + h->read);
+}
+
+static void update_output_chunk(struct ringbuf_head *h, u32 len)
+{
+       h->write += len;
+       if (h->write == RINGBUF_DATASIZE)
+               h->write = 0;
+}
+
+static void update_input_chunk(struct ringbuf_head *h, u32 len)
+{
+       h->read += len;
+       if (h->read == RINGBUF_DATASIZE)
+               h->read = 0;
+}
+
+static int output_avail(struct ringbuf_head *out)
+{
+       unsigned int avail;
+
+       get_output_chunk(out, out->buf, &avail);
+       return avail != 0;
+}
+
+int xb_write(const void *data, unsigned len)
+{
+       struct ringbuf_head h;
+       struct ringbuf_head *out = outbuf();
+
+       do {
+               void *dst;
+               unsigned int avail;
+
+               wait_event(xb_waitq, output_avail(out));
+
+               /* Read, then check: not that we don't trust store.
+                * Hell, some of my best friends are daemons.  But,
+                * in this post-911 world... */
+               h = *out;
+               mb();
+               if (!check_buffer(&h)) {
+                       return -1; /* ETERRORIST! */
+               }
+
+               dst = get_output_chunk(&h, out->buf, &avail);
+               if (avail > len)
+                       avail = len;
+               memcpy(dst, data, avail);
+               data = (void *)((char *)data + avail);
+               len -= avail;
+               update_output_chunk(out, avail);
+               notify_via_evtchn(start_info.store_evtchn);
+       } while (len != 0);
+
+       return 0;
+}
+
+int xs_input_avail(void)
+{
+       unsigned int avail;
+       struct ringbuf_head *in = inbuf();
+
+       get_input_chunk(in, in->buf, &avail);
+       return avail != 0;
+}
+
+int xb_read(void *data, unsigned len)
+{
+       struct ringbuf_head h;
+       struct ringbuf_head *in = inbuf();
+       int was_full;
+
+       while (len != 0) {
+               unsigned int avail;
+               const char *src;
+
+               wait_event(xb_waitq, xs_input_avail());
+               h = *in;
+               mb();
+               if (!check_buffer(&h)) {
+                       return -1;
+               }
+
+               src = get_input_chunk(&h, in->buf, &avail);
+               if (avail > len)
+                       avail = len;
+               was_full = !output_avail(&h);
+
+               memcpy(data, src, avail);
+               data = (void *)((char *)data + avail);
+               len -= avail;
+               update_input_chunk(in, avail);
+               DEBUG("Finished read of %i bytes (%i to go)\n", avail, len);
+               /* If it was full, tell them we've taken some. */
+               if (was_full)
+                       notify_via_evtchn(start_info.store_evtchn);
+       }
+
+       /* If we left something, wake watch thread to deal with it. */
+       if (xs_input_avail())
+               wake_up(&xb_waitq);
+
+       return 0;
+}
+
+/* Set up interrupt handler off store event channel. */
+int xb_init_comms(void)
+{
+    printk("Init xenbus comms, store event channel %d\n", 
start_info.store_evtchn);
+       if (!start_info.store_evtchn)
+               return 0;
+    printk("Binding virq\n");
+       bind_evtchn(start_info.store_evtchn, &wake_waiting);
+
+       /* FIXME zero out page -- domain builder should probably do this*/
+       memset(mfn_to_virt(start_info.store_mfn), 0, PAGE_SIZE);
+    notify_via_evtchn(start_info.store_evtchn);
+       return 0;
+}
+
+void xb_suspend_comms(void)
+{
+
+       if (!start_info.store_evtchn)
+               return;
+
+    // TODO
+       //unbind_evtchn_from_irqhandler(xen_start_info.store_evtchn, &xb_waitq);
+}
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/xenbus/xenbus_comms.h
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/xenbus/xenbus_comms.h      Wed Sep  7 18:10:45 2005
@@ -0,0 +1,40 @@
+/*
+ * Private include for xenbus communications.
+ * 
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _XENBUS_COMMS_H
+#define _XENBUS_COMMS_H
+
+int xb_init_comms(void);
+void xb_suspend_comms(void);
+
+/* Low level routines. */
+int xb_write(const void *data, unsigned len);
+int xb_read(void *data, unsigned len);
+int xs_input_avail(void);
+extern struct wait_queue_head xb_waitq;
+
+#endif /* _XENBUS_COMMS_H */
diff -r de8a90fc2667 -r 8d393e2d3b66 extras/mini-os/xenbus/xenbus_xs.c
--- /dev/null   Fri Aug 26 10:18:44 2005
+++ b/extras/mini-os/xenbus/xenbus_xs.c Wed Sep  7 18:10:45 2005
@@ -0,0 +1,554 @@
+/******************************************************************************
+ * xenbus_xs.c
+ *
+ * This is the kernel equivalent of the "xs" library.  We don't need everything
+ * and we use xenbus_comms for communication.
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+#include <errno.h>
+#include <types.h>
+#include <list.h>
+#include <lib.h>
+#include <err.h>
+#include <os.h>
+#include <xmalloc.h>
+#include <fcntl.h>
+#include <xenbus.h>
+#include <wait.h>
+#include <sched.h>
+#include <semaphore.h>
+#include "xenstored.h"
+#include "xenbus_comms.h"
+
+#define streq(a, b) (strcmp((a), (b)) == 0)
+
+static char printf_buffer[4096];
+static LIST_HEAD(watches);
+//TODO
+DECLARE_MUTEX(xenbus_lock);
+
+static int get_error(const char *errorstring)
+{
+       unsigned int i;
+
+       for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
+               if (i == ARRAY_SIZE(xsd_errors) - 1) {
+                       printk("XENBUS xen store gave: unknown error %s",
+                              errorstring);
+                       return EINVAL;
+               }
+       }
+       return xsd_errors[i].errnum;
+}
+
+static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
+{
+       struct xsd_sockmsg msg;
+       void *ret;
+       int err;
+
+       err = xb_read(&msg, sizeof(msg));
+       if (err)
+               return ERR_PTR(err);
+
+       ret = xmalloc_array(char, msg.len + 1);
+       if (!ret)
+               return ERR_PTR(-ENOMEM);
+
+       err = xb_read(ret, msg.len);
+       if (err) {
+               xfree(ret);
+               return ERR_PTR(err);
+       }
+       ((char*)ret)[msg.len] = '\0';
+
+       *type = msg.type;
+       if (len)
+               *len = msg.len;
+       return ret;
+}
+
+/* Emergency write. */
+void xenbus_debug_write(const char *str, unsigned int count)
+{
+       struct xsd_sockmsg msg;
+
+       msg.type = XS_DEBUG;
+       msg.len = sizeof("print") + count + 1;
+
+       xb_write(&msg, sizeof(msg));
+       xb_write("print", sizeof("print"));
+       xb_write(str, count);
+       xb_write("", 1);
+}
+
+/* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
+static void *xs_talkv(enum xsd_sockmsg_type type,
+                     const struct kvec *iovec,
+                     unsigned int num_vecs,
+                     unsigned int *len)
+{
+       struct xsd_sockmsg msg;
+       void *ret = NULL;
+       unsigned int i;
+       int err;
+
+       //WARN_ON(down_trylock(&xenbus_lock) == 0);
+
+       msg.type = type;
+       msg.len = 0;
+       for (i = 0; i < num_vecs; i++)
+               msg.len += iovec[i].iov_len;
+
+       err = xb_write(&msg, sizeof(msg));
+       if (err)
+               return ERR_PTR(err);
+
+       for (i = 0; i < num_vecs; i++) {
+               err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
+               if (err)
+                       return ERR_PTR(err);
+       }
+
+       /* Watches can have fired before reply comes: daemon detects
+        * and re-transmits, so we can ignore this. */
+       do {
+               xfree(ret);
+               ret = read_reply(&msg.type, len);
+               if (IS_ERR(ret))
+                       return ret;
+       } while (msg.type == XS_WATCH_EVENT);
+
+       if (msg.type == XS_ERROR) {
+               err = get_error(ret);
+               xfree(ret);
+               return ERR_PTR(-err);
+       }
+
+       //BUG_ON(msg.type != type);
+       return ret;
+}
+
+/* Simplified version of xs_talkv: single message. */
+static void *xs_single(enum xsd_sockmsg_type type,
+                      const char *string, unsigned int *len)
+{
+       struct kvec iovec;
+
+       iovec.iov_base = (void *)string;
+       iovec.iov_len = strlen(string) + 1;
+       return xs_talkv(type, &iovec, 1, len);
+}
+
+/* Many commands only need an ack, don't care what it says. */
+static int xs_error(char *reply)
+{
+       if (IS_ERR(reply))
+               return PTR_ERR(reply);
+       xfree(reply);
+       return 0;
+}
+
+static unsigned int count_strings(const char *strings, unsigned int len)
+{
+       unsigned int num;
+       const char *p;
+
+       for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
+               num++;
+
+       return num;
+}
+
+/* Return the path to dir with /name appended. */ 
+static char *join(const char *dir, const char *name)
+{
+       static char buffer[4096];
+
+       //BUG_ON(down_trylock(&xenbus_lock) == 0);
+       /* XXX FIXME: might not be correct if name == "" */
+       //BUG_ON(strlen(dir) + strlen("/") + strlen(name) + 1 > sizeof(buffer));
+
+       strcpy(buffer, dir);
+       if (!streq(name, "")) {
+               strcat(buffer, "/");
+               strcat(buffer, name);
+       }
+       return buffer;
+}
+
+char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
+{
+       char *strings, *p, **ret;
+       unsigned int len;
+
+       strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
+       if (IS_ERR(strings))
+               return (char **)strings;
+
+       /* Count the strings. */
+       *num = count_strings(strings, len);
+
+       /* Transfer to one big alloc for easy freeing. */
+       ret = (char **)xmalloc_array(char, *num * sizeof(char *) + len);
+       if (!ret) {
+               xfree(strings);
+               return ERR_PTR(-ENOMEM);
+       }
+       memcpy(&ret[*num], strings, len);
+       xfree(strings);
+
+       strings = (char *)&ret[*num];
+       for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
+               ret[(*num)++] = p;
+       return ret;
+}
+
+/* Check if a path exists. Return 1 if it does. */
+int xenbus_exists(const char *dir, const char *node)
+{
+       char **d;
+       int dir_n;
+
+       d = xenbus_directory(dir, node, &dir_n);
+       if (IS_ERR(d))
+               return 0;
+       xfree(d);
+       return 1;
+}
+
+/* Get the value of a single file.
+ * Returns a kmalloced value: call free() on it after use.
+ * len indicates length in bytes.
+ */
+void *xenbus_read(const char *dir, const char *node, unsigned int *len)
+{
+       return xs_single(XS_READ, join(dir, node), len);
+}
+
+/* Write the value of a single file.
+ * Returns -err on failure.  createflags can be 0, O_CREAT, or O_CREAT|O_EXCL.
+ */
+int xenbus_write(const char *dir, const char *node,
+                const char *string, int createflags)
+{
+       const char *flags, *path;
+       struct kvec iovec[3];
+
+       path = join(dir, node);
+       /* Format: Flags (as string), path, data. */
+       if (createflags == 0)
+               flags = XS_WRITE_NONE;
+       else if (createflags == O_CREAT)
+               flags = XS_WRITE_CREATE;
+       else if (createflags == (O_CREAT|O_EXCL))
+               flags = XS_WRITE_CREATE_EXCL;
+       else
+               return -EINVAL;
+
+       iovec[0].iov_base = (void *)path;
+       iovec[0].iov_len = strlen(path) + 1;
+       iovec[1].iov_base = (void *)flags;
+       iovec[1].iov_len = strlen(flags) + 1;
+       iovec[2].iov_base = (void *)string;
+       iovec[2].iov_len = strlen(string);
+
+       return xs_error(xs_talkv(XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
+}
+
+/* Create a new directory. */
+int xenbus_mkdir(const char *dir, const char *node)
+{
+       return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL));
+}
+
+/* Destroy a file or directory (directories must be empty). */
+int xenbus_rm(const char *dir, const char *node)
+{
+       return xs_error(xs_single(XS_RM, join(dir, node), NULL));
+}
+
+/* Start a transaction: changes by others will not be seen during this
+ * transaction, and changes will not be visible to others until end.
+ * Transaction only applies to the given subtree.
+ * You can only have one transaction at any time.
+ */
+int xenbus_transaction_start(const char *subtree)
+{
+       return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL));
+}
+
+/* End a transaction.
+ * If abandon is true, transaction is discarded instead of committed.
+ */
+int xenbus_transaction_end(int abort)
+{
+       char abortstr[2];
+
+       if (abort)
+               strcpy(abortstr, "F");
+       else
+               strcpy(abortstr, "T");
+       return xs_error(xs_single(XS_TRANSACTION_END, abortstr, NULL));
+}
+
+/* Single read and scanf: returns -errno or num scanned. */
+int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
+{
+       va_list ap;
+       int ret;
+       char *val;
+
+       val = xenbus_read(dir, node, NULL);
+       if (IS_ERR(val))
+               return PTR_ERR(val);
+
+       va_start(ap, fmt);
+       ret = vsscanf(val, fmt, ap);
+       va_end(ap);
+       xfree(val);
+       /* Distinctive errno. */
+       if (ret == 0)
+               return -ERANGE;
+       return ret;
+}
+
+/* Single printf and write: returns -errno or 0. */
+int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
+{
+       va_list ap;
+       int ret;
+
+       //BUG_ON(down_trylock(&xenbus_lock) == 0);
+       va_start(ap, fmt);
+       ret = vsnprintf(printf_buffer, sizeof(printf_buffer), fmt, ap);
+       va_end(ap);
+
+       //BUG_ON(ret > sizeof(printf_buffer)-1);
+       return xenbus_write(dir, node, printf_buffer, O_CREAT);
+}
+
+       
+/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
+int xenbus_gather(const char *dir, ...)
+{
+       va_list ap;
+       const char *name;
+       int ret = 0;
+
+       va_start(ap, dir);
+       while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
+               const char *fmt = va_arg(ap, char *);
+               void *result = va_arg(ap, void *);
+               char *p;
+
+               p = xenbus_read(dir, name, NULL);
+               if (IS_ERR(p)) {
+                       ret = PTR_ERR(p);
+                       break;
+               }
+               if (fmt) {
+                       if (sscanf(p, fmt, result) == 0)
+                               ret = -EINVAL;
+                       xfree(p);
+               } else
+                       *(char **)result = p;
+       }
+       va_end(ap);
+       return ret;
+}
+
+static int xs_watch(const char *path, const char *token)
+{
+       struct kvec iov[2];
+
+       iov[0].iov_base = (void *)path;
+       iov[0].iov_len = strlen(path) + 1;
+       iov[1].iov_base = (void *)token;
+       iov[1].iov_len = strlen(token) + 1;
+
+       return xs_error(xs_talkv(XS_WATCH, iov, ARRAY_SIZE(iov), NULL));
+}
+
+static char *xs_read_watch(char **token)
+{
+       enum xsd_sockmsg_type type;
+       char *ret;
+
+       ret = read_reply(&type, NULL);
+       if (IS_ERR(ret))
+               return ret;
+
+       //BUG_ON(type != XS_WATCH_EVENT);
+       *token = ret + strlen(ret) + 1;
+       return ret;
+}
+
+static int xs_acknowledge_watch(const char *token)
+{
+       return xs_error(xs_single(XS_WATCH_ACK, token, NULL));
+}
+
+static int xs_unwatch(const char *path, const char *token)
+{
+       struct kvec iov[2];
+
+       iov[0].iov_base = (char *)path;
+       iov[0].iov_len = strlen(path) + 1;
+       iov[1].iov_base = (char *)token;
+       iov[1].iov_len = strlen(token) + 1;
+
+       return xs_error(xs_talkv(XS_UNWATCH, iov, ARRAY_SIZE(iov), NULL));
+}
+
+/* A little paranoia: we don't just trust token. */
+static struct xenbus_watch *find_watch(const char *token)
+{
+       struct xenbus_watch *i, *cmp;
+
+       cmp = (void *)simple_strtoul(token, NULL, 16);
+
+       list_for_each_entry(i, &watches, list)
+               if (i == cmp)
+                       return i;
+       return NULL;
+}
+
+/* Register callback to watch this node. */
+int register_xenbus_watch(struct xenbus_watch *watch)
+{
+       /* Pointer in ascii is the token. */
+       char token[sizeof(watch) * 2 + 1];
+       int err;
+
+       sprintf(token, "%lX", (long)watch);
+       //BUG_ON(find_watch(token));
+printk("Registered watch for: %s\n", token);
+       err = xs_watch(watch->node, token);
+       if (!err)
+               list_add(&watch->list, &watches);
+       return err;
+}
+
+void unregister_xenbus_watch(struct xenbus_watch *watch)
+{
+       char token[sizeof(watch) * 2 + 1];
+       int err;
+
+       sprintf(token, "%lX", (long)watch);
+       //BUG_ON(!find_watch(token));
+
+       err = xs_unwatch(watch->node, token);
+       list_del(&watch->list);
+
+       if (err)
+               printk("XENBUS Failed to release watch %s: %i\n",
+                      watch->node, err);
+}
+
+/* Re-register callbacks to all watches. */
+void reregister_xenbus_watches(void)
+{
+       struct xenbus_watch *watch;
+       char token[sizeof(watch) * 2 + 1];
+
+       list_for_each_entry(watch, &watches, list) {
+               sprintf(token, "%lX", (long)watch);
+               xs_watch(watch->node, token);
+       }
+}
+
+void watch_thread(void *unused)
+{
+       for (;;) {
+               char *token;
+               char *node = NULL;
+
+               wait_event(xb_waitq, xs_input_avail());
+
+               /* If this is a spurious wakeup caused by someone
+                * doing an op, they'll hold the lock and the buffer
+                * will be empty by the time we get there.               
+                */
+               down(&xenbus_lock);
+               if (xs_input_avail())
+                       node = xs_read_watch(&token);
+
+               if (node && !IS_ERR(node)) {
+                       struct xenbus_watch *w;
+                       int err;
+
+                       err = xs_acknowledge_watch(token);
+                       if (err)
+                               printk("XENBUS ack %s fail %i\n", node, err);
+                       w = find_watch(token);
+                       //BUG_ON(!w);
+                       w->callback(w, node);
+                       xfree(node);
+               } else
+                       printk("XENBUS xs_read_watch: %li\n", PTR_ERR(node));
+               up(&xenbus_lock);
+       }
+}
+
+
+static void ballon_changed(struct xenbus_watch *watch, const char *node)
+{
+    unsigned long new_target;
+    int err;
+    err = xenbus_scanf("memory", "target", "%lu", &new_target);
+
+    if(err != 1)
+    {
+        printk("Unable to read memory/target\n");
+        return;
+    }
+
+    printk("Memory target changed to: %ld bytes, ignoring.\n", new_target);
+}
+
+
+static struct xenbus_watch ballon_watch = {
+    .node = "memory/target",
+    .callback = ballon_changed,
+};
+
+
+
+int xs_init(void)
+{
+       int err;
+       struct thread *watcher;
+    printk("xb_init_comms\n");
+       err = xb_init_comms();
+       if (err)
+               return err;
+       
+       watcher = create_thread("kxwatch", watch_thread, NULL);
+    down(&xenbus_lock);
+    register_xenbus_watch(&ballon_watch);
+    up(&xenbus_lock);
+       return 0;
+}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] mini-os implementation of xenbus, some 64bit fixes, Grzegorz Milos <=