ia64/xen-unstable

changeset 9444:8c21c8ea5fff

Fix mini-os xenbus.

From: Grzegorz Milos <gm281@cam.ac.uk>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Mar 24 10:47:48 2006 +0100 (2006-03-24)
parents 96e3b02ec931
children 8286738ab7f9
files extras/mini-os/Makefile extras/mini-os/console/console.c extras/mini-os/console/xencons_ring.c extras/mini-os/events.c extras/mini-os/include/os.h extras/mini-os/include/wait.h extras/mini-os/include/xenbus.h extras/mini-os/kernel.c extras/mini-os/minios-x86_32.lds extras/mini-os/mm.c extras/mini-os/sched.c extras/mini-os/traps.c extras/mini-os/x86_32.S extras/mini-os/xenbus/xenbus.c
line diff
     1.1 --- a/extras/mini-os/Makefile	Thu Mar 23 18:57:21 2006 +0100
     1.2 +++ b/extras/mini-os/Makefile	Fri Mar 24 10:47:48 2006 +0100
     1.3 @@ -41,8 +41,7 @@ default: $(TARGET)
     1.4  
     1.5  links:
     1.6  	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
     1.7 -	[ -e xenbus/xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h xenbus/xenstored.h
     1.8 -	
     1.9 +
    1.10  $(TARGET): links $(OBJS)
    1.11  	$(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
    1.12  	gzip -f -9 -c $@.elf >$@.gz
     2.1 --- a/extras/mini-os/console/console.c	Thu Mar 23 18:57:21 2006 +0100
     2.2 +++ b/extras/mini-os/console/console.c	Fri Mar 24 10:47:48 2006 +0100
     2.3 @@ -116,12 +116,12 @@ void print(int direct, const char *fmt, 
     2.4      {
     2.5          (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
     2.6          return;
     2.7 +    } else {
     2.8 +        if(!console_initialised)
     2.9 +            (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
    2.10 +        
    2.11 +        console_print(buf, strlen(buf));
    2.12      }
    2.13 -    
    2.14 -    if(!console_initialised)
    2.15 -        (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
    2.16 -        
    2.17 -    console_print(buf, strlen(buf));
    2.18  }
    2.19  
    2.20  void printk(const char *fmt, ...)
     3.1 --- a/extras/mini-os/console/xencons_ring.c	Thu Mar 23 18:57:21 2006 +0100
     3.2 +++ b/extras/mini-os/console/xencons_ring.c	Fri Mar 24 10:47:48 2006 +0100
     3.3 @@ -10,7 +10,6 @@
     3.4  
     3.5  
     3.6  /* TODO - need to define BUG_ON for whole mini-os, need crash-dump as well */
     3.7 -extern void do_exit(void);
     3.8  #define BUG_ON(_cond)   do{if(_cond) do_exit();} while(0);
     3.9  
    3.10  static inline struct xencons_interface *xencons_interface(void)
    3.11 @@ -29,7 +28,6 @@ int xencons_ring_send_no_notify(const ch
    3.12      int sent = 0;
    3.13  	struct xencons_interface *intf = xencons_interface();
    3.14  	XENCONS_RING_IDX cons, prod;
    3.15 -
    3.16  	cons = intf->out_cons;
    3.17  	prod = intf->out_prod;
    3.18  	mb();
     4.1 --- a/extras/mini-os/events.c	Thu Mar 23 18:57:21 2006 +0100
     4.2 +++ b/extras/mini-os/events.c	Fri Mar 24 10:47:48 2006 +0100
     4.3 @@ -74,9 +74,9 @@ int bind_evtchn( u32 port, void (*handle
     4.4  
     4.5  void unbind_evtchn( u32 port )
     4.6  {
     4.7 -	if (ev_actions[port].handler)
     4.8 +	if (ev_actions[port].handler == default_handler)
     4.9  		printk("WARN: No handler for port %d when unbinding\n", port);
    4.10 -	ev_actions[port].handler = NULL;
    4.11 +	ev_actions[port].handler = default_handler;
    4.12  	ev_actions[port].status |= EVS_DISABLED;
    4.13  }
    4.14  
     5.1 --- a/extras/mini-os/include/os.h	Thu Mar 23 18:57:21 2006 +0100
     5.2 +++ b/extras/mini-os/include/os.h	Fri Mar 24 10:47:48 2006 +0100
     5.3 @@ -9,6 +9,7 @@
     5.4  
     5.5  #define NULL 0
     5.6  
     5.7 +
     5.8  #if __GNUC__ == 2 && __GNUC_MINOR__ < 96
     5.9  #define __builtin_expect(x, expected_value) (x)
    5.10  #endif
    5.11 @@ -20,6 +21,10 @@
    5.12  #ifndef __ASSEMBLY__
    5.13  #include <types.h>
    5.14  #include <hypervisor.h>
    5.15 +
    5.16 +extern void do_exit(void);
    5.17 +#define BUG do_exit
    5.18 +
    5.19  #endif
    5.20  #include <xen/xen.h>
    5.21  
     6.1 --- a/extras/mini-os/include/wait.h	Thu Mar 23 18:57:21 2006 +0100
     6.2 +++ b/extras/mini-os/include/wait.h	Fri Mar 24 10:47:48 2006 +0100
     6.3 @@ -66,6 +66,14 @@ static inline void wake_up(struct wait_q
     6.4      }
     6.5  }
     6.6  
     6.7 +#define add_waiter(w, wq) do {  \
     6.8 +    unsigned long flags;        \
     6.9 +    local_irq_save(flags);      \
    6.10 +    add_wait_queue(&wq, &w);    \
    6.11 +    block(current);             \
    6.12 +    local_irq_restore(flags);   \
    6.13 +} while (0)
    6.14 +
    6.15  #define wait_event(wq, condition) do{             \
    6.16      unsigned long flags;                          \
    6.17      if(condition)                                 \
     7.1 --- a/extras/mini-os/include/xenbus.h	Thu Mar 23 18:57:21 2006 +0100
     7.2 +++ b/extras/mini-os/include/xenbus.h	Fri Mar 24 10:47:48 2006 +0100
     7.3 @@ -1,224 +1,6 @@
     7.4 -/******************************************************************************
     7.5 - * xenbus.h
     7.6 - *
     7.7 - * Talks to Xen Store to figure out what devices we have.
     7.8 - *
     7.9 - * Copyright (C) 2005 Rusty Russell, IBM Corporation
    7.10 - * Copyright (C) 2005 XenSource Ltd.
    7.11 - * 
    7.12 - * This file may be distributed separately from the Linux kernel, or
    7.13 - * incorporated into other software packages, subject to the following license:
    7.14 - * 
    7.15 - * Permission is hereby granted, free of charge, to any person obtaining a copy
    7.16 - * of this source file (the "Software"), to deal in the Software without
    7.17 - * restriction, including without limitation the rights to use, copy, modify,
    7.18 - * merge, publish, distribute, sublicense, and/or sell copies of the Software,
    7.19 - * and to permit persons to whom the Software is furnished to do so, subject to
    7.20 - * the following conditions:
    7.21 - * 
    7.22 - * The above copyright notice and this permission notice shall be included in
    7.23 - * all copies or substantial portions of the Software.
    7.24 - * 
    7.25 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    7.26 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    7.27 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    7.28 - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    7.29 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    7.30 - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    7.31 - * IN THE SOFTWARE.
    7.32 - */
    7.33 -
    7.34 -#ifndef _ASM_XEN_XENBUS_H
    7.35 -#define _ASM_XEN_XENBUS_H
    7.36 -
    7.37 -#include <errno.h>
    7.38 -#include <xen/io/xenbus.h>
    7.39 -#include <xen/io/xs_wire.h>
    7.40 -
    7.41 -/* Register callback to watch this node. */
    7.42 -struct xenbus_watch
    7.43 -{
    7.44 -	struct list_head list;
    7.45 -
    7.46 -	/* Path being watched. */
    7.47 -	const char *node;
    7.48 -
    7.49 -	/* Callback (executed in a process context with no locks held). */
    7.50 -	void (*callback)(struct xenbus_watch *,
    7.51 -			 const char **vec, unsigned int len);
    7.52 -};
    7.53 -
    7.54 -
    7.55 -/* A xenbus device. */
    7.56 -struct xenbus_device {
    7.57 -	const char *devicetype;
    7.58 -	const char *nodename;
    7.59 -	const char *otherend;
    7.60 -	int otherend_id;
    7.61 -	struct xenbus_watch otherend_watch;
    7.62 -	int has_error;
    7.63 -	void *data;
    7.64 -};
    7.65 -
    7.66 -struct xenbus_device_id
    7.67 -{
    7.68 -	/* .../device/<device_type>/<identifier> */
    7.69 -	char devicetype[32]; 	/* General class of device. */
    7.70 -};
    7.71 -
    7.72 -/* A xenbus driver. */
    7.73 -struct xenbus_driver {
    7.74 -	char *name;
    7.75 -	struct module *owner;
    7.76 -	const struct xenbus_device_id *ids;
    7.77 -	int (*probe)(struct xenbus_device *dev,
    7.78 -		     const struct xenbus_device_id *id);
    7.79 -	void (*otherend_changed)(struct xenbus_device *dev,
    7.80 -				 XenbusState backend_state);
    7.81 -	int (*remove)(struct xenbus_device *dev);
    7.82 -	int (*suspend)(struct xenbus_device *dev);
    7.83 -	int (*resume)(struct xenbus_device *dev);
    7.84 -	int (*hotplug)(struct xenbus_device *, char **, int, char *, int);
    7.85 -	int (*read_otherend_details)(struct xenbus_device *dev);
    7.86 -};
    7.87 -
    7.88 -int xenbus_register_frontend(struct xenbus_driver *drv);
    7.89 -int xenbus_register_backend(struct xenbus_driver *drv);
    7.90 -void xenbus_unregister_driver(struct xenbus_driver *drv);
    7.91 -
    7.92 -struct xenbus_transaction;
    7.93 -
    7.94 -char **xenbus_directory(struct xenbus_transaction *t,
    7.95 -			const char *dir, const char *node, unsigned int *num);
    7.96 -void *xenbus_read(struct xenbus_transaction *t,
    7.97 -		  const char *dir, const char *node, unsigned int *len);
    7.98 -int xenbus_write(struct xenbus_transaction *t,
    7.99 -		 const char *dir, const char *node, const char *string);
   7.100 -int xenbus_mkdir(struct xenbus_transaction *t,
   7.101 -		 const char *dir, const char *node);
   7.102 -int xenbus_exists(struct xenbus_transaction *t,
   7.103 -		  const char *dir, const char *node);
   7.104 -int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
   7.105 -struct xenbus_transaction *xenbus_transaction_start(void);
   7.106 -int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
   7.107 -
   7.108 -/* Single read and scanf: returns -errno or num scanned if > 0. */
   7.109 -int xenbus_scanf(struct xenbus_transaction *t,
   7.110 -		 const char *dir, const char *node, const char *fmt, ...)
   7.111 -	__attribute__((format(scanf, 4, 5)));
   7.112 +#ifndef XENBUS_H__
   7.113 +#define XENBUS_H__
   7.114  
   7.115 -/* Single printf and write: returns -errno or 0. */
   7.116 -int xenbus_printf(struct xenbus_transaction *t,
   7.117 -		  const char *dir, const char *node, const char *fmt, ...)
   7.118 -	__attribute__((format(printf, 4, 5)));
   7.119 -
   7.120 -/* Generic read function: NULL-terminated triples of name,
   7.121 - * sprintf-style type string, and pointer. Returns 0 or errno.*/
   7.122 -int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
   7.123 -
   7.124 -int register_xenbus_watch(struct xenbus_watch *watch);
   7.125 -void unregister_xenbus_watch(struct xenbus_watch *watch);
   7.126 -void xs_suspend(void);
   7.127 -void xs_resume(void);
   7.128 -
   7.129 -/* Used by xenbus_dev to borrow kernel's store connection. */
   7.130 -void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
   7.131 -
   7.132 -/* Called from xen core code. */
   7.133 -void xenbus_suspend(void);
   7.134 -void xenbus_resume(void);
   7.135 -
   7.136 -#define XENBUS_IS_ERR_READ(str) ({			\
   7.137 -	if (!IS_ERR(str) && strlen(str) == 0) {		\
   7.138 -		kfree(str);				\
   7.139 -		str = ERR_PTR(-ERANGE);			\
   7.140 -	}						\
   7.141 -	IS_ERR(str);					\
   7.142 -})
   7.143 -
   7.144 -#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
   7.145 -
   7.146 -
   7.147 -/**
   7.148 - * Register a watch on the given path, using the given xenbus_watch structure
   7.149 - * for storage, and the given callback function as the callback.  Return 0 on
   7.150 - * success, or -errno on error.  On success, the given path will be saved as
   7.151 - * watch->node, and remains the caller's to free.  On error, watch->node will
   7.152 - * be NULL, the device will switch to XenbusStateClosing, and the error will
   7.153 - * be saved in the store.
   7.154 - */
   7.155 -int xenbus_watch_path(struct xenbus_device *dev, const char *path,
   7.156 -		      struct xenbus_watch *watch, 
   7.157 -		      void (*callback)(struct xenbus_watch *,
   7.158 -				       const char **, unsigned int));
   7.159 -
   7.160 +void init_xenbus(void);
   7.161  
   7.162 -/**
   7.163 - * Register a watch on the given path/path2, using the given xenbus_watch
   7.164 - * structure for storage, and the given callback function as the callback.
   7.165 - * Return 0 on success, or -errno on error.  On success, the watched path
   7.166 - * (path/path2) will be saved as watch->node, and becomes the caller's to
   7.167 - * kfree().  On error, watch->node will be NULL, so the caller has nothing to
   7.168 - * free, the device will switch to XenbusStateClosing, and the error will be
   7.169 - * saved in the store.
   7.170 - */
   7.171 -int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
   7.172 -		       const char *path2, struct xenbus_watch *watch, 
   7.173 -		       void (*callback)(struct xenbus_watch *,
   7.174 -					const char **, unsigned int));
   7.175 -
   7.176 -
   7.177 -/**
   7.178 - * Advertise in the store a change of the given driver to the given new_state.
   7.179 - * Perform the change inside the given transaction xbt.  xbt may be NULL, in
   7.180 - * which case this is performed inside its own transaction.  Return 0 on
   7.181 - * success, or -errno on error.  On error, the device will switch to
   7.182 - * XenbusStateClosing, and the error will be saved in the store.
   7.183 - */
   7.184 -int xenbus_switch_state(struct xenbus_device *dev,
   7.185 -			struct xenbus_transaction *xbt,
   7.186 -			XenbusState new_state);
   7.187 -
   7.188 -
   7.189 -/**
   7.190 - * Grant access to the given ring_mfn to the peer of the given device.  Return
   7.191 - * 0 on success, or -errno on error.  On error, the device will switch to
   7.192 - * XenbusStateClosing, and the error will be saved in the store.
   7.193 - */
   7.194 -int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
   7.195 -
   7.196 -
   7.197 -/**
   7.198 - * Allocate an event channel for the given xenbus_device, assigning the newly
   7.199 - * created local port to *port.  Return 0 on success, or -errno on error.  On
   7.200 - * error, the device will switch to XenbusStateClosing, and the error will be
   7.201 - * saved in the store.
   7.202 - */
   7.203 -int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
   7.204 -
   7.205 -
   7.206 -/**
   7.207 - * Return the state of the driver rooted at the given store path, or
   7.208 - * XenbusStateClosed if no state can be read.
   7.209 - */
   7.210 -XenbusState xenbus_read_driver_state(const char *path);
   7.211 -
   7.212 -
   7.213 -/***
   7.214 - * Report the given negative errno into the store, along with the given
   7.215 - * formatted message.
   7.216 - */
   7.217 -void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
   7.218 -		      ...);
   7.219 -
   7.220 -
   7.221 -/***
   7.222 - * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
   7.223 - * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
   7.224 - * closedown of this driver and its peer.
   7.225 - */
   7.226 -void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
   7.227 -		      ...);
   7.228 -
   7.229 -
   7.230 -#endif /* _ASM_XEN_XENBUS_H */
   7.231 +#endif /* XENBUS_H__ */
     8.1 --- a/extras/mini-os/kernel.c	Thu Mar 23 18:57:21 2006 +0100
     8.2 +++ b/extras/mini-os/kernel.c	Fri Mar 24 10:47:48 2006 +0100
     8.3 @@ -35,7 +35,6 @@
     8.4  #include <lib.h>
     8.5  #include <sched.h>
     8.6  #include <xenbus.h>
     8.7 -#include "xenbus/xenbus_comms.h"
     8.8  
     8.9  /*
    8.10   * Shared page for communicating with the hypervisor.
    8.11 @@ -76,7 +75,15 @@ static shared_info_t *map_shared_info(un
    8.12  }
    8.13  
    8.14  
    8.15 -extern void init_console(void);
    8.16 +void test_xenbus(void);
    8.17 +
    8.18 +/* Do initialisation from a thread once the scheduler's available */
    8.19 +static void init_xs(void *ign)
    8.20 +{
    8.21 +    init_xenbus();
    8.22 +
    8.23 +    test_xenbus();
    8.24 +}
    8.25  
    8.26  /*
    8.27   * INITIAL C ENTRY POINT.
    8.28 @@ -84,11 +91,13 @@ extern void init_console(void);
    8.29  void start_kernel(start_info_t *si)
    8.30  {
    8.31      static char hello[] = "Bootstrapping...\n";
    8.32 +
    8.33      (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
    8.34  
    8.35      /* Copy the start_info struct to a globally-accessible area. */
    8.36 +    /* WARN: don't do printk before here, it uses information from
    8.37 +       shared_info. Use xprintk instead. */
    8.38      memcpy(&start_info, si, sizeof(*si));
    8.39 -
    8.40      /* Grab the shared_info pointer and put it in a safe place. */
    8.41      HYPERVISOR_shared_info = map_shared_info(start_info.shared_info);
    8.42  
    8.43 @@ -120,28 +129,24 @@ void start_kernel(start_info_t *si)
    8.44             si->cmd_line ? (const char *)si->cmd_line : "NULL");
    8.45  
    8.46  
    8.47 -    /*
    8.48 -     * If used for porting another OS, start here to figure out your
    8.49 -     * guest os entry point. Otherwise continue below...
    8.50 -     */
    8.51 -    /* init memory management */
    8.52 +    /* Init memory management. */
    8.53      init_mm();
    8.54  
    8.55 -    /* set up events */
    8.56 +    /* Set up events. */
    8.57      init_events();
    8.58      
    8.59 -    /* init time and timers */
    8.60 +    /* Init time and timers. */
    8.61      init_time();
    8.62  
    8.63 -    /* init the console driver */
    8.64 +    /* Init the console driver. */
    8.65      init_console();
    8.66 -
    8.67 -    /* init scheduler */
    8.68 + 
    8.69 +   /* Init scheduler. */
    8.70      init_sched();
    8.71 -
    8.72 -    /* init xenbus */
    8.73 -    xs_init();
    8.74 -   
    8.75 + 
    8.76 +    /* Init XenBus from a separate thread */
    8.77 +    create_thread("init_xs", init_xs, NULL);
    8.78 +    
    8.79      /* Everything initialised, start idle thread */
    8.80      run_idle_thread();
    8.81  }
    8.82 @@ -156,6 +161,6 @@ void start_kernel(start_info_t *si)
    8.83  
    8.84  void do_exit(void)
    8.85  {
    8.86 -    printk("do_exit called!\n");
    8.87 +    printk("Do_exit called!\n");
    8.88      for ( ;; ) HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
    8.89  }
     9.1 --- a/extras/mini-os/minios-x86_32.lds	Thu Mar 23 18:57:21 2006 +0100
     9.2 +++ b/extras/mini-os/minios-x86_32.lds	Fri Mar 24 10:47:48 2006 +0100
     9.3 @@ -21,15 +21,6 @@ SECTIONS
     9.4  
     9.5    _edata = .;			/* End of data section */
     9.6  
     9.7 -  . = ALIGN(8192);		/* init_task */
     9.8 -  .data.init_task : { *(.data.init_task) }
     9.9 -
    9.10 -  . = ALIGN(4096);
    9.11 -  .data.page_aligned : { *(.data.idt) }
    9.12 -
    9.13 -  . = ALIGN(32);
    9.14 -  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
    9.15 -
    9.16    __bss_start = .;		/* BSS */
    9.17    .bss : {
    9.18  	*(.bss)
    10.1 --- a/extras/mini-os/mm.c	Thu Mar 23 18:57:21 2006 +0100
    10.2 +++ b/extras/mini-os/mm.c	Fri Mar 24 10:47:48 2006 +0100
    10.3 @@ -51,7 +51,6 @@
    10.4  unsigned long *phys_to_machine_mapping;
    10.5  extern char *stack;
    10.6  extern char _text, _etext, _edata, _end;
    10.7 -extern void do_exit(void);
    10.8  extern void page_walk(unsigned long virt_addr);
    10.9  
   10.10  /*********************
    11.1 --- a/extras/mini-os/sched.c	Thu Mar 23 18:57:21 2006 +0100
    11.2 +++ b/extras/mini-os/sched.c	Fri Mar 24 10:47:48 2006 +0100
    11.3 @@ -65,6 +65,8 @@
    11.4  struct thread *idle_thread = NULL;
    11.5  LIST_HEAD(exited_threads);
    11.6  
    11.7 +void idle_thread_fn(void *unused);
    11.8 +
    11.9  void dump_stack(struct thread *thread)
   11.10  {
   11.11      unsigned long *bottom = (unsigned long *)thread->stack + 2048; 
   11.12 @@ -132,7 +134,7 @@ void schedule(void)
   11.13              xfree(thread);
   11.14          }
   11.15      }
   11.16 -    next = idle_thread;    
   11.17 +    next = idle_thread;   
   11.18      /* Thread list needs to be protected */
   11.19      list_for_each(iterator, &idle_thread->thread_list)
   11.20      {
   11.21 @@ -203,8 +205,13 @@ struct thread* create_thread(char *name,
   11.22      set_runnable(thread);
   11.23      
   11.24      local_irq_save(flags);
   11.25 -    if(idle_thread != NULL)
   11.26 +    if(idle_thread != NULL) {
   11.27          list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
   11.28 +    } else if(function != idle_thread_fn)
   11.29 +    {
   11.30 +        printk("BUG: Not allowed to create thread before initialising scheduler.\n");
   11.31 +        BUG();
   11.32 +    }
   11.33      local_irq_restore(flags);
   11.34  
   11.35      return thread;
   11.36 @@ -282,19 +289,9 @@ void th_f2(void *data)
   11.37  
   11.38  void init_sched(void)
   11.39  {
   11.40 -    printk("Initialising scheduler\n");
   11.41 -       
   11.42 +    printk("Initialising scheduler, idle_thread %p\n", idle_thread);
   11.43 +
   11.44      idle_thread = create_thread("Idle", idle_thread_fn, NULL);
   11.45      INIT_LIST_HEAD(&idle_thread->thread_list);
   11.46 -
   11.47 -    
   11.48 -/*    create_thread("1", th_f1, (void *)0x1234);    
   11.49 -    create_thread("2", th_f1, (void *)0x1234);    
   11.50 -    create_thread("3", th_f1, (void *)0x1234);    
   11.51 -    create_thread("4", th_f1, (void *)0x1234);    
   11.52 -    create_thread("5", th_f1, (void *)0x1234);    
   11.53 -    create_thread("6", th_f1, (void *)0x1234);    
   11.54 -    create_thread("second", th_f2, NULL);
   11.55 -*/   
   11.56  }
   11.57  
    12.1 --- a/extras/mini-os/traps.c	Thu Mar 23 18:57:21 2006 +0100
    12.2 +++ b/extras/mini-os/traps.c	Fri Mar 24 10:47:48 2006 +0100
    12.3 @@ -29,11 +29,18 @@ void spurious_interrupt_bug(void);
    12.4  void machine_check(void);
    12.5  
    12.6  
    12.7 -extern void do_exit(void);
    12.8 -
    12.9  void dump_regs(struct pt_regs *regs)
   12.10  {
   12.11 -    printk("FIXME: proper register dump (with the stack dump)\n");
   12.12 +    printk("EIP: %x, EFLAGS %x.\n", regs->eip, regs->eflags);
   12.13 +    printk("EBX: %08x ECX: %08x EDX: %08x\n",
   12.14 +	   regs->ebx, regs->ecx, regs->edx);
   12.15 +    printk("ESI: %08x EDI: %08x EBP: %08x EAX: %08x\n",
   12.16 +	   regs->esi, regs->edi, regs->ebp, regs->eax);
   12.17 +    printk("DS: %04x ES: %04x orig_eax: %08x, eip: %08x\n",
   12.18 +	   regs->xds, regs->xes, regs->orig_eax, regs->eip);
   12.19 +    printk("CS: %04x EFLAGS: %08x esp: %08x ss: %04x\n",
   12.20 +	   regs->xcs, regs->eflags, regs->esp, regs->xss);
   12.21 +
   12.22  }	
   12.23  
   12.24  
   12.25 @@ -94,10 +101,14 @@ void page_walk(unsigned long virt_addres
   12.26  
   12.27  }
   12.28  
   12.29 -void do_page_fault(struct pt_regs *regs, unsigned long error_code,
   12.30 -								                     unsigned long addr)
   12.31 +#define read_cr2() \
   12.32 +        (HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
   12.33 +
   12.34 +void do_page_fault(struct pt_regs *regs, unsigned long error_code)
   12.35  {
   12.36 -    printk("Page fault at linear address %p\n", addr);
   12.37 +    unsigned long addr = read_cr2();
   12.38 +    printk("Page fault at linear address %p, regs %p, code %lx\n", addr, regs,
   12.39 +	   error_code);
   12.40      dump_regs(regs);
   12.41  #ifdef __x86_64__
   12.42      /* FIXME: _PAGE_PSE */
    13.1 --- a/extras/mini-os/x86_32.S	Thu Mar 23 18:57:21 2006 +0100
    13.2 +++ b/extras/mini-os/x86_32.S	Fri Mar 24 10:47:48 2006 +0100
    13.3 @@ -30,10 +30,10 @@ shared_info:
    13.4  hypercall_page:
    13.5          .org 0x3000
    13.6  
    13.7 -ES		= 0x20
    13.8 -ORIG_EAX	= 0x24
    13.9 -EIP		= 0x28
   13.10 -CS		= 0x2C
   13.11 +ES		= 0x1c
   13.12 +ORIG_EAX	= 0x20
   13.13 +EIP		= 0x24
   13.14 +CS		= 0x28
   13.15  
   13.16  #define ENTRY(X) .globl X ; X :
   13.17  
   13.18 @@ -94,32 +94,6 @@ do_exception:
   13.19  	call *%edi
   13.20      addl $8,%esp
   13.21      
   13.22 -/*    pushl %ds
   13.23 -	pushl %eax
   13.24 -	xorl %eax,%eax
   13.25 -	pushl %ebp
   13.26 -	pushl %edi
   13.27 -	pushl %esi
   13.28 -	pushl %edx
   13.29 -	decl %eax			# eax = -1
   13.30 -	pushl %ecx
   13.31 -	pushl %ebx
   13.32 -	cld
   13.33 -	movl %es,%ecx
   13.34 -	movl ORIG_EAX(%esp), %esi	# get the error code
   13.35 -	movl ES(%esp), %edi		# get the function address
   13.36 -	movl %eax, ORIG_EAX(%esp)
   13.37 -	movl %ecx, ES(%esp)
   13.38 -	movl %esp,%edx
   13.39 -	pushl %esi			# push the error code
   13.40 -	pushl %edx			# push the pt_regs pointer
   13.41 -	movl $(__KERNEL_DS),%edx
   13.42 -	movl %edx,%ds
   13.43 -	movl %edx,%es
   13.44 -	call *%edi
   13.45 -	addl $8,%esp  */
   13.46 -
   13.47 -        
   13.48  ret_from_exception:
   13.49          movb CS(%esp),%cl
   13.50  	test $2,%cl          # slow return to ring 2 or 3
   13.51 @@ -290,15 +264,16 @@ ENTRY(page_fault)
   13.52  	pushl %ecx
   13.53  	pushl %ebx
   13.54  	cld
   13.55 -	movl %es,%edi
   13.56 -	movl ES(%esp), %ecx		/* get the faulting address */
   13.57 -	movl ORIG_EAX(%esp), %edx	/* get the error code */
   13.58 +	movl ORIG_EAX(%esp), %edi
   13.59  	movl %eax, ORIG_EAX(%esp)
   13.60 -	movl %edi, ES(%esp)
   13.61 +	movl %es, %ecx
   13.62 +	movl %ecx, ES(%esp)
   13.63  	movl $(__KERNEL_DS),%eax
   13.64  	movl %eax, %ds
   13.65  	movl %eax, %es
   13.66 -	movl %esp,%eax			/* pt_regs pointer */
   13.67 +	pushl %edi
   13.68 +	movl %esp, %eax
   13.69 +	pushl %eax
   13.70  	call do_page_fault
   13.71  	jmp ret_from_exception
   13.72  
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/extras/mini-os/xenbus/xenbus.c	Fri Mar 24 10:47:48 2006 +0100
    14.3 @@ -0,0 +1,387 @@
    14.4 +/* 
    14.5 + ****************************************************************************
    14.6 + * (C) 2006 - Cambridge University
    14.7 + ****************************************************************************
    14.8 + *
    14.9 + *        File: mm.c
   14.10 + *      Author: Steven Smith (sos22@cam.ac.uk) 
   14.11 + *     Changes: Grzegorz Milos (gm281@cam.ac.uk)
   14.12 + *              
   14.13 + *        Date: Mar 2006, chages Aug 2005
   14.14 + * 
   14.15 + * Environment: Xen Minimal OS
   14.16 + * Description: Minimal implementation of xenbus
   14.17 + *
   14.18 + ****************************************************************************
   14.19 + **/
   14.20 +#include <os.h>
   14.21 +#include <mm.h>
   14.22 +#include <traps.h>
   14.23 +#include <lib.h>
   14.24 +#include <xenbus.h>
   14.25 +#include <events.h>
   14.26 +#include <errno.h>
   14.27 +#include <sched.h>
   14.28 +#include <wait.h>
   14.29 +#include <xen/io/xs_wire.h>
   14.30 +#include <spinlock.h>
   14.31 +#include <xmalloc.h>
   14.32 +
   14.33 +#define BUG_ON(x) do { \
   14.34 +    if (x) {printk("BUG at %s:%d\n", __FILE__, __LINE__); BUG(); } \
   14.35 +} while (0)
   14.36 +
   14.37 +#define min(x,y) ({                       \
   14.38 +        typeof(x) tmpx = (x);                 \
   14.39 +        typeof(y) tmpy = (y);                 \
   14.40 +        tmpx < tmpy ? tmpx : tmpy;            \
   14.41 +        })
   14.42 +
   14.43 +#ifdef XENBUS_DEBUG
   14.44 +#define DEBUG(_f, _a...) \
   14.45 +    printk("MINI_OS(file=xenbus.c, line=%d) " _f , __LINE__, ## _a)
   14.46 +#else
   14.47 +#define DEBUG(_f, _a...)    ((void)0)
   14.48 +#endif
   14.49 +
   14.50 +
   14.51 +static struct xenstore_domain_interface *xenstore_buf;
   14.52 +static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
   14.53 +struct xenbus_req_info 
   14.54 +{
   14.55 +    int in_use:1;
   14.56 +    struct wait_queue_head waitq;
   14.57 +    void *reply;
   14.58 +};
   14.59 +
   14.60 +#define NR_REQS 32
   14.61 +static struct xenbus_req_info req_info[NR_REQS];
   14.62 +
   14.63 +static void memcpy_from_ring(const void *Ring,
   14.64 +        void *Dest,
   14.65 +        int off,
   14.66 +        int len)
   14.67 +{
   14.68 +    int c1, c2;
   14.69 +    const char *ring = Ring;
   14.70 +    char *dest = Dest;
   14.71 +    c1 = min(len, XENSTORE_RING_SIZE - off);
   14.72 +    c2 = len - c1;
   14.73 +    memcpy(dest, ring + off, c1);
   14.74 +    memcpy(dest + c1, ring, c2);
   14.75 +}
   14.76 +
   14.77 +static void xenbus_thread_func(void *ign)
   14.78 +{
   14.79 +    struct xsd_sockmsg msg;
   14.80 +    unsigned prod;
   14.81 +
   14.82 +    for (;;) 
   14.83 +    {
   14.84 +        wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
   14.85 +        while (1) 
   14.86 +        {
   14.87 +            prod = xenstore_buf->rsp_prod;
   14.88 +            DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
   14.89 +                    xenstore_buf->rsp_prod);
   14.90 +            if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
   14.91 +                break;
   14.92 +            rmb();
   14.93 +            memcpy_from_ring(xenstore_buf->rsp,
   14.94 +                    &msg,
   14.95 +                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
   14.96 +                    sizeof(msg));
   14.97 +            DEBUG("Msg len %d, %d avail, id %d.\n",
   14.98 +                    msg.len + sizeof(msg),
   14.99 +                    xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
  14.100 +                    msg.req_id);
  14.101 +            if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
  14.102 +                    sizeof(msg) + msg.len)
  14.103 +                break;
  14.104 +
  14.105 +            DEBUG("Message is good.\n");
  14.106 +            req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len);
  14.107 +            memcpy_from_ring(xenstore_buf->rsp,
  14.108 +                    req_info[msg.req_id].reply,
  14.109 +                    MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
  14.110 +                    msg.len + sizeof(msg));
  14.111 +            wake_up(&req_info[msg.req_id].waitq);
  14.112 +            xenstore_buf->rsp_cons += msg.len + sizeof(msg);
  14.113 +        }
  14.114 +    }
  14.115 +}
  14.116 +
  14.117 +static void xenbus_evtchn_handler(int port, struct pt_regs *regs)
  14.118 +{
  14.119 +    wake_up(&xb_waitq);
  14.120 +}
  14.121 +
  14.122 +static int nr_live_reqs;
  14.123 +static spinlock_t req_lock = SPIN_LOCK_UNLOCKED;
  14.124 +static DECLARE_WAIT_QUEUE_HEAD(req_wq);
  14.125 +
  14.126 +/* Release a xenbus identifier */
  14.127 +static void release_xenbus_id(int id)
  14.128 +{
  14.129 +    BUG_ON(!req_info[id].in_use);
  14.130 +    spin_lock(&req_lock);
  14.131 +    nr_live_reqs--;
  14.132 +    if (nr_live_reqs == NR_REQS - 1)
  14.133 +        wake_up(&req_wq);
  14.134 +    spin_unlock(&req_lock);
  14.135 +}
  14.136 +
  14.137 +/* Allocate an identifier for a xenbus request.  Blocks if none are
  14.138 +   available. */
  14.139 +static int allocate_xenbus_id(void)
  14.140 +{
  14.141 +    static int probe;
  14.142 +    int o_probe;
  14.143 +
  14.144 +    while (1) 
  14.145 +    {
  14.146 +        spin_lock(&req_lock);
  14.147 +        if (nr_live_reqs < NR_REQS)
  14.148 +            break;
  14.149 +        spin_unlock(&req_lock);
  14.150 +        wait_event(req_wq, (nr_live_reqs < NR_REQS));
  14.151 +    }
  14.152 +
  14.153 +    o_probe = probe;
  14.154 +    for (;;) 
  14.155 +    {
  14.156 +        if (!req_info[o_probe].in_use)
  14.157 +            break;
  14.158 +        o_probe = (o_probe + 1) % NR_REQS;
  14.159 +        BUG_ON(o_probe == probe);
  14.160 +    }
  14.161 +    nr_live_reqs++;
  14.162 +    req_info[o_probe].in_use = 1;
  14.163 +    probe = o_probe + 1;
  14.164 +    spin_unlock(&req_lock);
  14.165 +    init_waitqueue_head(&req_info[o_probe].waitq);
  14.166 +    return o_probe;
  14.167 +}
  14.168 +
  14.169 +/* Initialise xenbus. */
  14.170 +void init_xenbus(void)
  14.171 +{
  14.172 +    int err;
  14.173 +    DEBUG("init_xenbus called.\n");
  14.174 +    xenstore_buf = mfn_to_virt(start_info.store_mfn);
  14.175 +    create_thread("xenstore", xenbus_thread_func, NULL);
  14.176 +    DEBUG("buf at %p.\n", xenstore_buf);
  14.177 +    err = bind_evtchn(start_info.store_evtchn,
  14.178 +            xenbus_evtchn_handler);
  14.179 +    DEBUG("xenbus on irq %d\n", err);
  14.180 +}
  14.181 +
  14.182 +struct write_req {
  14.183 +    const void *data;
  14.184 +    unsigned len;
  14.185 +};
  14.186 +
  14.187 +/* Send data to xenbus.  This can block.  All of the requests are seen
  14.188 +   by xenbus as if sent atomically.  The header is added
  14.189 +   automatically, using type %type, req_id %req_id, and trans_id
  14.190 +   %trans_id. */
  14.191 +static void xb_write(int type, int req_id, int trans_id,
  14.192 +        const struct write_req *req, int nr_reqs)
  14.193 +{
  14.194 +    XENSTORE_RING_IDX prod;
  14.195 +    int r;
  14.196 +    int len = 0;
  14.197 +    const struct write_req *cur_req;
  14.198 +    int req_off;
  14.199 +    int total_off;
  14.200 +    int this_chunk;
  14.201 +    struct xsd_sockmsg m = {.type = type, .req_id = req_id,
  14.202 +        .tx_id = trans_id };
  14.203 +    struct write_req header_req = { &m, sizeof(m) };
  14.204 +
  14.205 +    for (r = 0; r < nr_reqs; r++)
  14.206 +        len += req[r].len;
  14.207 +    m.len = len;
  14.208 +    len += sizeof(m);
  14.209 +
  14.210 +    cur_req = &header_req;
  14.211 +
  14.212 +    BUG_ON(len > XENSTORE_RING_SIZE);
  14.213 +    /* Wait for the ring to drain to the point where we can send the
  14.214 +       message. */
  14.215 +    prod = xenstore_buf->req_prod;
  14.216 +    if (prod + len - xenstore_buf->req_cons > XENSTORE_RING_SIZE) 
  14.217 +    {
  14.218 +        /* Wait for there to be space on the ring */
  14.219 +        DEBUG("prod %d, len %d, cons %d, size %d; waiting.\n",
  14.220 +                prod, len, xenstore_buf->req_cons, XENSTORE_RING_SIZE);
  14.221 +        wait_event(xb_waitq,
  14.222 +                xenstore_buf->req_prod + len - xenstore_buf->req_cons <=
  14.223 +                XENSTORE_RING_SIZE);
  14.224 +        DEBUG("Back from wait.\n");
  14.225 +        prod = xenstore_buf->req_prod;
  14.226 +    }
  14.227 +
  14.228 +    /* We're now guaranteed to be able to send the message without
  14.229 +       overflowing the ring.  Do so. */
  14.230 +    total_off = 0;
  14.231 +    req_off = 0;
  14.232 +    while (total_off < len) 
  14.233 +    {
  14.234 +        this_chunk = min(cur_req->len - req_off,
  14.235 +                XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod));
  14.236 +        memcpy((char *)xenstore_buf->req + MASK_XENSTORE_IDX(prod),
  14.237 +                (char *)cur_req->data + req_off, this_chunk);
  14.238 +        prod += this_chunk;
  14.239 +        req_off += this_chunk;
  14.240 +        total_off += this_chunk;
  14.241 +        if (req_off == cur_req->len) 
  14.242 +        {
  14.243 +            req_off = 0;
  14.244 +            if (cur_req == &header_req)
  14.245 +                cur_req = req;
  14.246 +            else
  14.247 +                cur_req++;
  14.248 +        }
  14.249 +    }
  14.250 +
  14.251 +    DEBUG("Complete main loop of xb_write.\n");
  14.252 +    BUG_ON(req_off != 0);
  14.253 +    BUG_ON(total_off != len);
  14.254 +    BUG_ON(prod > xenstore_buf->req_cons + XENSTORE_RING_SIZE);
  14.255 +
  14.256 +    /* Remote must see entire message before updating indexes */
  14.257 +    wmb();
  14.258 +
  14.259 +    xenstore_buf->req_prod += len;
  14.260 +
  14.261 +    /* Send evtchn to notify remote */
  14.262 +    notify_remote_via_evtchn(start_info.store_evtchn);
  14.263 +}
  14.264 +
  14.265 +/* Send a mesasge to xenbus, in the same fashion as xb_write, and
  14.266 +   block waiting for a reply.  The reply is malloced and should be
  14.267 +   freed by the caller. */
  14.268 +static void *xenbus_msg_reply(int type,
  14.269 +        int trans,
  14.270 +        struct write_req *io,
  14.271 +        int nr_reqs)
  14.272 +{
  14.273 +    int id;
  14.274 +    DEFINE_WAIT(w);
  14.275 +    void *rep;
  14.276 +    struct xsd_sockmsg *repmsg;
  14.277 +
  14.278 +    id = allocate_xenbus_id();
  14.279 +    add_waiter(w, req_info[id].waitq);
  14.280 +
  14.281 +    xb_write(type, id, trans, io, nr_reqs);
  14.282 +
  14.283 +    schedule();
  14.284 +    wake(current);
  14.285 +
  14.286 +    rep = req_info[id].reply;
  14.287 +    repmsg = rep;
  14.288 +    BUG_ON(repmsg->req_id != id);
  14.289 +    release_xenbus_id(id);
  14.290 +
  14.291 +    return rep;
  14.292 +}
  14.293 +
  14.294 +/* Send a debug message to xenbus.  Can block. */
  14.295 +static void xenbus_debug_msg(const char *msg)
  14.296 +{
  14.297 +    int len = strlen(msg);
  14.298 +    struct write_req req[] = {
  14.299 +        { "print", sizeof("print") },
  14.300 +        { msg, len },
  14.301 +        { "", 1 }};
  14.302 +    void *reply;
  14.303 +    struct xsd_sockmsg *repmsg;
  14.304 +
  14.305 +    reply = xenbus_msg_reply(XS_DEBUG, 0, req, 3);
  14.306 +    repmsg = reply;
  14.307 +    DEBUG("Got a reply, type %d, id %d, len %d.\n",
  14.308 +            repmsg->type, repmsg->req_id, repmsg->len);
  14.309 +}
  14.310 +
  14.311 +/* List the contents of a directory.  Returns a malloc()ed array of
  14.312 +   pointers to malloc()ed strings.  The array is NULL terminated.  May
  14.313 +   block. */
  14.314 +static char **xenbus_ls(const char *pre)
  14.315 +{
  14.316 +    void *reply;
  14.317 +    struct xsd_sockmsg *repmsg;
  14.318 +    struct write_req req[] = { { pre, strlen(pre)+1 } };
  14.319 +    int nr_elems, x, i;
  14.320 +    char **res;
  14.321 +
  14.322 +    repmsg = xenbus_msg_reply(XS_DIRECTORY, 0, req, 1);
  14.323 +    reply = repmsg + 1;
  14.324 +    for (x = nr_elems = 0; x < repmsg->len; x++)
  14.325 +        nr_elems += (((char *)reply)[x] == 0);
  14.326 +    res = malloc(sizeof(res[0]) * (nr_elems + 1));
  14.327 +    for (x = i = 0; i < nr_elems; i++) {
  14.328 +        int l = strlen((char *)reply + x);
  14.329 +        res[i] = malloc(l + 1);
  14.330 +        memcpy(res[i], (char *)reply + x, l + 1);
  14.331 +        x += l + 1;
  14.332 +    }
  14.333 +    res[i] = NULL;
  14.334 +    free(repmsg);
  14.335 +    return res;
  14.336 +}
  14.337 +
  14.338 +static char *xenbus_read(const char *path)
  14.339 +{
  14.340 +    struct write_req req[] = { {path, strlen(path) + 1}};
  14.341 +    struct xsd_sockmsg *rep;
  14.342 +    char *res;
  14.343 +    rep = xenbus_msg_reply(XS_READ, 0, req, 1);
  14.344 +    res = malloc(rep->len + 1);
  14.345 +    memcpy(res, rep + 1, rep->len);
  14.346 +    res[rep->len] = 0;
  14.347 +    free(rep);
  14.348 +    return res;
  14.349 +}
  14.350 +
  14.351 +static void do_ls_test(const char *pre)
  14.352 +{
  14.353 +    char **dirs;
  14.354 +    int x;
  14.355 +
  14.356 +    DEBUG("ls %s...\n", pre);
  14.357 +    dirs = xenbus_ls(pre);
  14.358 +    for (x = 0; dirs[x]; x++) 
  14.359 +    {
  14.360 +        DEBUG("ls %s[%d] -> %s\n", pre, x, dirs[x]);
  14.361 +        free(dirs[x]);
  14.362 +    }
  14.363 +    free(dirs);
  14.364 +}
  14.365 +
  14.366 +static void do_read_test(const char *path)
  14.367 +{
  14.368 +    char *res;
  14.369 +    DEBUG("Read %s...\n", path);
  14.370 +    res = xenbus_read(path);
  14.371 +    DEBUG("Read %s -> %s.\n", path, res);
  14.372 +    free(res);
  14.373 +}
  14.374 +
  14.375 +/* Simple testing thing */
  14.376 +void test_xenbus(void)
  14.377 +{
  14.378 +    DEBUG("Doing xenbus test.\n");
  14.379 +    xenbus_debug_msg("Testing xenbus...\n");
  14.380 +
  14.381 +    DEBUG("Doing ls test.\n");
  14.382 +    do_ls_test("device");
  14.383 +    do_ls_test("device/vif");
  14.384 +    do_ls_test("device/vif/0");
  14.385 +
  14.386 +    DEBUG("Doing read test.\n");
  14.387 +    do_read_test("device/vif/0/mac");
  14.388 +    do_read_test("device/vif/0/backend");
  14.389 +    printk("Xenbus initialised.\n");
  14.390 +}