ia64/xen-unstable

changeset 6717:cdfa7dd00c44

merge?
author cl349@firebug.cl.cam.ac.uk
date Fri Sep 09 10:20:25 2005 +0000 (2005-09-09)
parents 2704a88c3295 df1348e72390
children 4856f000d35d
files extras/mini-os/Makefile extras/mini-os/events.c extras/mini-os/include/ctype.h extras/mini-os/include/err.h extras/mini-os/include/errno-base.h extras/mini-os/include/errno.h extras/mini-os/include/events.h extras/mini-os/include/fcntl.h extras/mini-os/include/hypervisor.h extras/mini-os/include/lib.h extras/mini-os/include/mm.h extras/mini-os/include/os.h extras/mini-os/include/sched.h extras/mini-os/include/semaphore.h extras/mini-os/include/time.h extras/mini-os/include/traps.h extras/mini-os/include/types.h extras/mini-os/include/wait.h extras/mini-os/include/xenbus.h extras/mini-os/kernel.c extras/mini-os/lib/printf.c extras/mini-os/lib/string.c extras/mini-os/mm.c extras/mini-os/sched.c extras/mini-os/time.c extras/mini-os/traps.c extras/mini-os/xenbus/Makefile extras/mini-os/xenbus/xenbus_comms.c extras/mini-os/xenbus/xenbus_comms.h extras/mini-os/xenbus/xenbus_xs.c linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/netback/interface.c linux-2.6-xen-sparse/drivers/xen/netback/loopback.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c linux-2.6-xen-sparse/drivers/xen/usbback/interface.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h tools/libxc/xc_domain.c tools/libxc/xc_linux_build.c tools/libxc/xc_linux_restore.c tools/libxc/xc_private.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c tools/python/xen/lowlevel/xs/xs.c tools/python/xen/xend/image.py xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/vmx_vmcs.c xen/arch/x86/x86_32/mm.c xen/common/grant_table.c xen/common/memory.c xen/common/page_alloc.c xen/common/trace.c xen/common/xmalloc.c xen/drivers/char/console.c xen/drivers/char/serial.c xen/include/asm-x86/page.h
line diff
     1.1 --- a/extras/mini-os/Makefile	Fri Sep 09 08:56:38 2005 +0000
     1.2 +++ b/extras/mini-os/Makefile	Fri Sep 09 10:20:25 2005 +0000
     1.3 @@ -31,16 +31,18 @@ TARGET := mini-os
     1.4  OBJS := $(TARGET_ARCH).o
     1.5  OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
     1.6  OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
     1.7 -
     1.8 +OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
     1.9 +										   
    1.10  HDRS := $(wildcard include/*.h)
    1.11  HDRS += $(wildcard include/xen/*.h)
    1.12  
    1.13  default: $(TARGET)
    1.14  
    1.15 -xen-public:
    1.16 +links:
    1.17  	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
    1.18 -
    1.19 -$(TARGET): xen-public $(OBJS)
    1.20 +	[ -e xenbus/xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h xenbus/xenstored.h
    1.21 +	
    1.22 +$(TARGET): links $(OBJS)
    1.23  	$(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
    1.24  	gzip -f -9 -c $@.elf >$@.gz
    1.25  
    1.26 @@ -55,3 +57,4 @@ clean:
    1.27  %.o: %.S $(HDRS) Makefile
    1.28  	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@
    1.29  
    1.30 +
     2.1 --- a/extras/mini-os/events.c	Fri Sep 09 08:56:38 2005 +0000
     2.2 +++ b/extras/mini-os/events.c	Fri Sep 09 10:20:25 2005 +0000
     2.3 @@ -17,13 +17,13 @@
     2.4   */
     2.5  
     2.6  #include <os.h>
     2.7 +#include <mm.h>
     2.8  #include <hypervisor.h>
     2.9  #include <events.h>
    2.10  #include <lib.h>
    2.11  
    2.12 -#include <xen/event_channel.h>
    2.13  static ev_action_t ev_actions[NR_EVS];
    2.14 -void default_handler(u32 port, struct pt_regs *regs);
    2.15 +void default_handler(int port, struct pt_regs *regs);
    2.16  
    2.17  
    2.18  /*
    2.19 @@ -32,7 +32,6 @@ void default_handler(u32 port, struct pt
    2.20  int do_event(u32 port, struct pt_regs *regs)
    2.21  {
    2.22      ev_action_t  *action;
    2.23 -
    2.24      if (port >= NR_EVS) {
    2.25          printk("Port number too large: %d\n", port);
    2.26          return 0;
    2.27 @@ -57,11 +56,23 @@ int do_event(u32 port, struct pt_regs *r
    2.28  
    2.29  }
    2.30  
    2.31 +void bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
    2.32 +{
    2.33 + 	if(ev_actions[port].handler)
    2.34 +        printk("WARN: Handler for port %d already registered, replacing\n",
    2.35 +				port);
    2.36 +
    2.37 +	ev_actions[port].handler = handler;
    2.38 +	ev_actions[port].status &= ~EVS_DISABLED;	  
    2.39 + 
    2.40 +	/* Finally unmask the port */
    2.41 +	unmask_evtchn(port);
    2.42 +}
    2.43 +
    2.44  int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
    2.45  {
    2.46  	evtchn_op_t op;
    2.47  	int ret = 0;
    2.48 -	u32 port;
    2.49  
    2.50  	/* Try to bind the virq to a port */
    2.51  	op.cmd = EVTCHNOP_bind_virq;
    2.52 @@ -73,22 +84,13 @@ int bind_virq( u32 virq, void (*handler)
    2.53  		printk("Failed to bind virtual IRQ %d\n", virq);
    2.54  		goto out;
    2.55      }
    2.56 -
    2.57 -    port = op.u.bind_virq.port;
    2.58 -	
    2.59 -	if(ev_actions[port].handler)
    2.60 -        printk("WARN: Handler for port %d already registered, replacing\n",
    2.61 -				port);
    2.62 -
    2.63 -	ev_actions[port].handler = handler;
    2.64 -	ev_actions[port].status &= ~EVS_DISABLED;
    2.65 -	
    2.66 -	/* Finally unmask the port */
    2.67 -	unmask_evtchn(port);
    2.68 +    bind_evtchn(op.u.bind_virq.port, handler);	
    2.69  out:
    2.70  	return ret;
    2.71  }
    2.72  
    2.73 +
    2.74 +
    2.75  /*
    2.76   * Initially all events are without a handler and disabled
    2.77   */
    2.78 @@ -100,10 +102,10 @@ void init_events(void)
    2.79      for ( i = 0; i < NR_EVS; i++ )
    2.80      {
    2.81          ev_actions[i].status  = EVS_DISABLED;
    2.82 -        ev_actions[i].handler = NULL;
    2.83 +        ev_actions[i].handler = default_handler;
    2.84      }
    2.85  }
    2.86  
    2.87 -void default_handler(u32 port, struct pt_regs *regs) {
    2.88 +void default_handler(int port, struct pt_regs *regs) {
    2.89      printk("[Port %d] - event received\n", port);
    2.90  }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/extras/mini-os/include/ctype.h	Fri Sep 09 10:20:25 2005 +0000
     3.3 @@ -0,0 +1,79 @@
     3.4 +#ifndef _CTYPE_H
     3.5 +#define _CTYPE_H
     3.6 +
     3.7 +/*
     3.8 + * NOTE! This ctype does not handle EOF like the standard C
     3.9 + * library is required to.
    3.10 + */
    3.11 +
    3.12 +#define _U	0x01	/* upper */
    3.13 +#define _L	0x02	/* lower */
    3.14 +#define _D	0x04	/* digit */
    3.15 +#define _C	0x08	/* cntrl */
    3.16 +#define _P	0x10	/* punct */
    3.17 +#define _S	0x20	/* white space (space/lf/tab) */
    3.18 +#define _X	0x40	/* hex digit */
    3.19 +#define _SP	0x80	/* hard space (0x20) */
    3.20 +
    3.21 +
    3.22 +unsigned char _ctype[] = {
    3.23 +_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
    3.24 +_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
    3.25 +_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
    3.26 +_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
    3.27 +_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
    3.28 +_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
    3.29 +_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
    3.30 +_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
    3.31 +_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
    3.32 +_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
    3.33 +_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
    3.34 +_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
    3.35 +_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
    3.36 +_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
    3.37 +_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
    3.38 +_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
    3.39 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
    3.40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
    3.41 +_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
    3.42 +_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
    3.43 +_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
    3.44 +_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
    3.45 +_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
    3.46 +_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
    3.47 +
    3.48 +#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
    3.49 +
    3.50 +#define isalnum(c)	((__ismask(c)&(_U|_L|_D)) != 0)
    3.51 +#define isalpha(c)	((__ismask(c)&(_U|_L)) != 0)
    3.52 +#define iscntrl(c)	((__ismask(c)&(_C)) != 0)
    3.53 +#define isdigit(c)	((__ismask(c)&(_D)) != 0)
    3.54 +#define isgraph(c)	((__ismask(c)&(_P|_U|_L|_D)) != 0)
    3.55 +#define islower(c)	((__ismask(c)&(_L)) != 0)
    3.56 +#define isprint(c)	((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
    3.57 +#define ispunct(c)	((__ismask(c)&(_P)) != 0)
    3.58 +#define isspace(c)	((__ismask(c)&(_S)) != 0)
    3.59 +#define isupper(c)	((__ismask(c)&(_U)) != 0)
    3.60 +#define isxdigit(c)	((__ismask(c)&(_D|_X)) != 0)
    3.61 +
    3.62 +#define isascii(c) (((unsigned char)(c))<=0x7f)
    3.63 +#define toascii(c) (((unsigned char)(c))&0x7f)
    3.64 +
    3.65 +static inline unsigned char __tolower(unsigned char c)
    3.66 +{
    3.67 +	if (isupper(c))
    3.68 +		c -= 'A'-'a';
    3.69 +	return c;
    3.70 +}
    3.71 +
    3.72 +static inline unsigned char __toupper(unsigned char c)
    3.73 +{
    3.74 +	if (islower(c))
    3.75 +		c -= 'a'-'A';
    3.76 +	return c;
    3.77 +}
    3.78 +
    3.79 +#define tolower(c) __tolower(c)
    3.80 +#define toupper(c) __toupper(c)
    3.81 +
    3.82 +#endif
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/extras/mini-os/include/err.h	Fri Sep 09 10:20:25 2005 +0000
     4.3 @@ -0,0 +1,31 @@
     4.4 +#ifndef _ERR_H
     4.5 +#define _ERR_H
     4.6 +
     4.7 +#include <errno.h>
     4.8 +
     4.9 +/*
    4.10 + * Kernel pointers have redundant information, so we can use a
    4.11 + * scheme where we can return either an error code or a dentry
    4.12 + * pointer with the same return value.
    4.13 + *
    4.14 + * This should be a per-architecture thing, to allow different
    4.15 + * error and pointer decisions.
    4.16 + */
    4.17 +#define IS_ERR_VALUE(x) ((x) > (unsigned long)-1000L)
    4.18 +
    4.19 +static inline void *ERR_PTR(long error)
    4.20 +{
    4.21 +	return (void *) error;
    4.22 +}
    4.23 +
    4.24 +static inline long PTR_ERR(const void *ptr)
    4.25 +{
    4.26 +	return (long) ptr;
    4.27 +}
    4.28 +
    4.29 +static inline long IS_ERR(const void *ptr)
    4.30 +{
    4.31 +	return IS_ERR_VALUE((unsigned long)ptr);
    4.32 +}
    4.33 +
    4.34 +#endif /* _LINUX_ERR_H */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/extras/mini-os/include/errno-base.h	Fri Sep 09 10:20:25 2005 +0000
     5.3 @@ -0,0 +1,39 @@
     5.4 +#ifndef _ERRNO_BASE_H
     5.5 +#define _ERRNO_BASE_H
     5.6 +
     5.7 +#define	EPERM		 1	/* Operation not permitted */
     5.8 +#define	ENOENT		 2	/* No such file or directory */
     5.9 +#define	ESRCH		 3	/* No such process */
    5.10 +#define	EINTR		 4	/* Interrupted system call */
    5.11 +#define	EIO		 5	/* I/O error */
    5.12 +#define	ENXIO		 6	/* No such device or address */
    5.13 +#define	E2BIG		 7	/* Argument list too long */
    5.14 +#define	ENOEXEC		 8	/* Exec format error */
    5.15 +#define	EBADF		 9	/* Bad file number */
    5.16 +#define	ECHILD		10	/* No child processes */
    5.17 +#define	EAGAIN		11	/* Try again */
    5.18 +#define	ENOMEM		12	/* Out of memory */
    5.19 +#define	EACCES		13	/* Permission denied */
    5.20 +#define	EFAULT		14	/* Bad address */
    5.21 +#define	ENOTBLK		15	/* Block device required */
    5.22 +#define	EBUSY		16	/* Device or resource busy */
    5.23 +#define	EEXIST		17	/* File exists */
    5.24 +#define	EXDEV		18	/* Cross-device link */
    5.25 +#define	ENODEV		19	/* No such device */
    5.26 +#define	ENOTDIR		20	/* Not a directory */
    5.27 +#define	EISDIR		21	/* Is a directory */
    5.28 +#define	EINVAL		22	/* Invalid argument */
    5.29 +#define	ENFILE		23	/* File table overflow */
    5.30 +#define	EMFILE		24	/* Too many open files */
    5.31 +#define	ENOTTY		25	/* Not a typewriter */
    5.32 +#define	ETXTBSY		26	/* Text file busy */
    5.33 +#define	EFBIG		27	/* File too large */
    5.34 +#define	ENOSPC		28	/* No space left on device */
    5.35 +#define	ESPIPE		29	/* Illegal seek */
    5.36 +#define	EROFS		30	/* Read-only file system */
    5.37 +#define	EMLINK		31	/* Too many links */
    5.38 +#define	EPIPE		32	/* Broken pipe */
    5.39 +#define	EDOM		33	/* Math argument out of domain of func */
    5.40 +#define	ERANGE		34	/* Math result not representable */
    5.41 +
    5.42 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/extras/mini-os/include/errno.h	Fri Sep 09 10:20:25 2005 +0000
     6.3 @@ -0,0 +1,109 @@
     6.4 +#ifndef _ERRNO_H
     6.5 +#define _ERRNO_H
     6.6 +
     6.7 +#include <errno-base.h>
     6.8 +
     6.9 +#define	EDEADLK		35	/* Resource deadlock would occur */
    6.10 +#define	ENAMETOOLONG	36	/* File name too long */
    6.11 +#define	ENOLCK		37	/* No record locks available */
    6.12 +#define	ENOSYS		38	/* Function not implemented */
    6.13 +#define	ENOTEMPTY	39	/* Directory not empty */
    6.14 +#define	ELOOP		40	/* Too many symbolic links encountered */
    6.15 +#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
    6.16 +#define	ENOMSG		42	/* No message of desired type */
    6.17 +#define	EIDRM		43	/* Identifier removed */
    6.18 +#define	ECHRNG		44	/* Channel number out of range */
    6.19 +#define	EL2NSYNC	45	/* Level 2 not synchronized */
    6.20 +#define	EL3HLT		46	/* Level 3 halted */
    6.21 +#define	EL3RST		47	/* Level 3 reset */
    6.22 +#define	ELNRNG		48	/* Link number out of range */
    6.23 +#define	EUNATCH		49	/* Protocol driver not attached */
    6.24 +#define	ENOCSI		50	/* No CSI structure available */
    6.25 +#define	EL2HLT		51	/* Level 2 halted */
    6.26 +#define	EBADE		52	/* Invalid exchange */
    6.27 +#define	EBADR		53	/* Invalid request descriptor */
    6.28 +#define	EXFULL		54	/* Exchange full */
    6.29 +#define	ENOANO		55	/* No anode */
    6.30 +#define	EBADRQC		56	/* Invalid request code */
    6.31 +#define	EBADSLT		57	/* Invalid slot */
    6.32 +
    6.33 +#define	EDEADLOCK	EDEADLK
    6.34 +
    6.35 +#define	EBFONT		59	/* Bad font file format */
    6.36 +#define	ENOSTR		60	/* Device not a stream */
    6.37 +#define	ENODATA		61	/* No data available */
    6.38 +#define	ETIME		62	/* Timer expired */
    6.39 +#define	ENOSR		63	/* Out of streams resources */
    6.40 +#define	ENONET		64	/* Machine is not on the network */
    6.41 +#define	ENOPKG		65	/* Package not installed */
    6.42 +#define	EREMOTE		66	/* Object is remote */
    6.43 +#define	ENOLINK		67	/* Link has been severed */
    6.44 +#define	EADV		68	/* Advertise error */
    6.45 +#define	ESRMNT		69	/* Srmount error */
    6.46 +#define	ECOMM		70	/* Communication error on send */
    6.47 +#define	EPROTO		71	/* Protocol error */
    6.48 +#define	EMULTIHOP	72	/* Multihop attempted */
    6.49 +#define	EDOTDOT		73	/* RFS specific error */
    6.50 +#define	EBADMSG		74	/* Not a data message */
    6.51 +#define	EOVERFLOW	75	/* Value too large for defined data type */
    6.52 +#define	ENOTUNIQ	76	/* Name not unique on network */
    6.53 +#define	EBADFD		77	/* File descriptor in bad state */
    6.54 +#define	EREMCHG		78	/* Remote address changed */
    6.55 +#define	ELIBACC		79	/* Can not access a needed shared library */
    6.56 +#define	ELIBBAD		80	/* Accessing a corrupted shared library */
    6.57 +#define	ELIBSCN		81	/* .lib section in a.out corrupted */
    6.58 +#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
    6.59 +#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
    6.60 +#define	EILSEQ		84	/* Illegal byte sequence */
    6.61 +#define	ERESTART	85	/* Interrupted system call should be restarted */
    6.62 +#define	ESTRPIPE	86	/* Streams pipe error */
    6.63 +#define	EUSERS		87	/* Too many users */
    6.64 +#define	ENOTSOCK	88	/* Socket operation on non-socket */
    6.65 +#define	EDESTADDRREQ	89	/* Destination address required */
    6.66 +#define	EMSGSIZE	90	/* Message too long */
    6.67 +#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
    6.68 +#define	ENOPROTOOPT	92	/* Protocol not available */
    6.69 +#define	EPROTONOSUPPORT	93	/* Protocol not supported */
    6.70 +#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
    6.71 +#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
    6.72 +#define	EPFNOSUPPORT	96	/* Protocol family not supported */
    6.73 +#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
    6.74 +#define	EADDRINUSE	98	/* Address already in use */
    6.75 +#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
    6.76 +#define	ENETDOWN	100	/* Network is down */
    6.77 +#define	ENETUNREACH	101	/* Network is unreachable */
    6.78 +#define	ENETRESET	102	/* Network dropped connection because of reset */
    6.79 +#define	ECONNABORTED	103	/* Software caused connection abort */
    6.80 +#define	ECONNRESET	104	/* Connection reset by peer */
    6.81 +#define	ENOBUFS		105	/* No buffer space available */
    6.82 +#define	EISCONN		106	/* Transport endpoint is already connected */
    6.83 +#define	ENOTCONN	107	/* Transport endpoint is not connected */
    6.84 +#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
    6.85 +#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
    6.86 +#define	ETIMEDOUT	110	/* Connection timed out */
    6.87 +#define	ECONNREFUSED	111	/* Connection refused */
    6.88 +#define	EHOSTDOWN	112	/* Host is down */
    6.89 +#define	EHOSTUNREACH	113	/* No route to host */
    6.90 +#define	EALREADY	114	/* Operation already in progress */
    6.91 +#define	EINPROGRESS	115	/* Operation now in progress */
    6.92 +#define	ESTALE		116	/* Stale NFS file handle */
    6.93 +#define	EUCLEAN		117	/* Structure needs cleaning */
    6.94 +#define	ENOTNAM		118	/* Not a XENIX named type file */
    6.95 +#define	ENAVAIL		119	/* No XENIX semaphores available */
    6.96 +#define	EISNAM		120	/* Is a named type file */
    6.97 +#define	EREMOTEIO	121	/* Remote I/O error */
    6.98 +#define	EDQUOT		122	/* Quota exceeded */
    6.99 +
   6.100 +#define	ENOMEDIUM	123	/* No medium found */
   6.101 +#define	EMEDIUMTYPE	124	/* Wrong medium type */
   6.102 +#define	ECANCELED	125	/* Operation Canceled */
   6.103 +#define	ENOKEY		126	/* Required key not available */
   6.104 +#define	EKEYEXPIRED	127	/* Key has expired */
   6.105 +#define	EKEYREVOKED	128	/* Key has been revoked */
   6.106 +#define	EKEYREJECTED	129	/* Key was rejected by service */
   6.107 +
   6.108 +/* for robust mutexes */
   6.109 +#define	EOWNERDEAD	130	/* Owner died */
   6.110 +#define	ENOTRECOVERABLE	131	/* State not recoverable */
   6.111 +
   6.112 +#endif
     7.1 --- a/extras/mini-os/include/events.h	Fri Sep 09 08:56:38 2005 +0000
     7.2 +++ b/extras/mini-os/include/events.h	Fri Sep 09 10:20:25 2005 +0000
     7.3 @@ -20,6 +20,7 @@
     7.4  #define _EVENTS_H_
     7.5  
     7.6  #include<traps.h>
     7.7 +#include <xen/event_channel.h>
     7.8  
     7.9  #define NR_EVS 1024
    7.10  
    7.11 @@ -39,6 +40,16 @@ typedef struct _ev_action_t {
    7.12  /* prototypes */
    7.13  int do_event(u32 port, struct pt_regs *regs);
    7.14  int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) );
    7.15 +void bind_evtchn( u32 virq, void (*handler)(int, struct pt_regs *) );
    7.16  void init_events(void);
    7.17  
    7.18 +static inline int notify_via_evtchn(int port)
    7.19 +{
    7.20 +    evtchn_op_t op;
    7.21 +    op.cmd = EVTCHNOP_send;
    7.22 +    op.u.send.local_port = port;
    7.23 +    return HYPERVISOR_event_channel_op(&op);
    7.24 +}
    7.25 +
    7.26 +
    7.27  #endif /* _EVENTS_H_ */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/extras/mini-os/include/fcntl.h	Fri Sep 09 10:20:25 2005 +0000
     8.3 @@ -0,0 +1,89 @@
     8.4 +#ifndef _I386_FCNTL_H
     8.5 +#define _I386_FCNTL_H
     8.6 +
     8.7 +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
     8.8 +   located on an ext2 file system */
     8.9 +#define O_ACCMODE	   0003
    8.10 +#define O_RDONLY	     00
    8.11 +#define O_WRONLY	     01
    8.12 +#define O_RDWR		     02
    8.13 +#define O_CREAT		   0100	/* not fcntl */
    8.14 +#define O_EXCL		   0200	/* not fcntl */
    8.15 +#define O_NOCTTY	   0400	/* not fcntl */
    8.16 +#define O_TRUNC		  01000	/* not fcntl */
    8.17 +#define O_APPEND	  02000
    8.18 +#define O_NONBLOCK	  04000
    8.19 +#define O_NDELAY	O_NONBLOCK
    8.20 +#define O_SYNC		 010000
    8.21 +#define FASYNC		 020000	/* fcntl, for BSD compatibility */
    8.22 +#define O_DIRECT	 040000	/* direct disk access hint */
    8.23 +#define O_LARGEFILE	0100000
    8.24 +#define O_DIRECTORY	0200000	/* must be a directory */
    8.25 +#define O_NOFOLLOW	0400000 /* don't follow links */
    8.26 +#define O_NOATIME	01000000
    8.27 +
    8.28 +#define F_DUPFD		0	/* dup */
    8.29 +#define F_GETFD		1	/* get close_on_exec */
    8.30 +#define F_SETFD		2	/* set/clear close_on_exec */
    8.31 +#define F_GETFL		3	/* get file->f_flags */
    8.32 +#define F_SETFL		4	/* set file->f_flags */
    8.33 +#define F_GETLK		5
    8.34 +#define F_SETLK		6
    8.35 +#define F_SETLKW	7
    8.36 +
    8.37 +#define F_SETOWN	8	/*  for sockets. */
    8.38 +#define F_GETOWN	9	/*  for sockets. */
    8.39 +#define F_SETSIG	10	/*  for sockets. */
    8.40 +#define F_GETSIG	11	/*  for sockets. */
    8.41 +
    8.42 +#define F_GETLK64	12	/*  using 'struct flock64' */
    8.43 +#define F_SETLK64	13
    8.44 +#define F_SETLKW64	14
    8.45 +
    8.46 +/* for F_[GET|SET]FL */
    8.47 +#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
    8.48 +
    8.49 +/* for posix fcntl() and lockf() */
    8.50 +#define F_RDLCK		0
    8.51 +#define F_WRLCK		1
    8.52 +#define F_UNLCK		2
    8.53 +
    8.54 +/* for old implementation of bsd flock () */
    8.55 +#define F_EXLCK		4	/* or 3 */
    8.56 +#define F_SHLCK		8	/* or 4 */
    8.57 +
    8.58 +/* for leases */
    8.59 +#define F_INPROGRESS	16
    8.60 +
    8.61 +/* operations for bsd flock(), also used by the kernel implementation */
    8.62 +#define LOCK_SH		1	/* shared lock */
    8.63 +#define LOCK_EX		2	/* exclusive lock */
    8.64 +#define LOCK_NB		4	/* or'd with one of the above to prevent
    8.65 +				   blocking */
    8.66 +#define LOCK_UN		8	/* remove lock */
    8.67 +
    8.68 +#define LOCK_MAND	32	/* This is a mandatory flock */
    8.69 +#define LOCK_READ	64	/* ... Which allows concurrent read operations */
    8.70 +#define LOCK_WRITE	128	/* ... Which allows concurrent write operations */
    8.71 +#define LOCK_RW		192	/* ... Which allows concurrent read & write ops */
    8.72 +
    8.73 +/*
    8.74 +struct flock {
    8.75 +	short l_type;
    8.76 +	short l_whence;
    8.77 +	off_t l_start;
    8.78 +	off_t l_len;
    8.79 +	pid_t l_pid;
    8.80 +};
    8.81 +
    8.82 +struct flock64 {
    8.83 +	short  l_type;
    8.84 +	short  l_whence;
    8.85 +	loff_t l_start;
    8.86 +	loff_t l_len;
    8.87 +	pid_t  l_pid;
    8.88 +};
    8.89 +
    8.90 +#define F_LINUX_SPECIFIC_BASE	1024
    8.91 +*/
    8.92 +#endif
     9.1 --- a/extras/mini-os/include/hypervisor.h	Fri Sep 09 08:56:38 2005 +0000
     9.2 +++ b/extras/mini-os/include/hypervisor.h	Fri Sep 09 10:20:25 2005 +0000
     9.3 @@ -13,7 +13,6 @@
     9.4  #define _HYPERVISOR_H_
     9.5  
     9.6  #include <types.h>
     9.7 -
     9.8  #include <xen/xen.h>
     9.9  #include <xen/io/domain_controller.h>
    9.10  
    9.11 @@ -40,48 +39,26 @@ void clear_evtchn(u32 port);
    9.12  /*
    9.13   * Assembler stubs for hyper-calls.
    9.14   */
    9.15 -
    9.16 -#ifdef __i386__
    9.17 -#define _a1 "b"
    9.18 -#define _a2 "c"
    9.19 -#define _a3 "d"
    9.20 -#define _a4 "S"
    9.21 -#else
    9.22 -#define _a1 "D"
    9.23 -#define _a2 "S"
    9.24 -#define _a3 "d"
    9.25 -#define _a4 "b"
    9.26 -#endif
    9.27 -
    9.28 -static __inline__ int HYPERVISOR_event_channel_op(
    9.29 -    void *op)
    9.30 +#if defined(__i386__)
    9.31 +static inline int
    9.32 +HYPERVISOR_set_trap_table(
    9.33 +    trap_info_t *table)
    9.34  {
    9.35      int ret;
    9.36      unsigned long ignore;
    9.37 +
    9.38      __asm__ __volatile__ (
    9.39          TRAP_INSTR
    9.40          : "=a" (ret), "=b" (ignore)
    9.41 -	: "0" (__HYPERVISOR_event_channel_op), "1" (op)
    9.42 +	: "0" (__HYPERVISOR_set_trap_table), "1" (table)
    9.43  	: "memory" );
    9.44  
    9.45      return ret;
    9.46  }
    9.47  
    9.48 -static __inline__ int HYPERVISOR_set_trap_table(trap_info_t *table)
    9.49 -{
    9.50 -    int ret;
    9.51 -    __asm__ __volatile__ (
    9.52 -        TRAP_INSTR
    9.53 -        : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table),
    9.54 -        _a1 (table) : "memory" );
    9.55 -
    9.56 -    return ret;
    9.57 -}
    9.58 -
    9.59 -static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, 
    9.60 -                                            int count, 
    9.61 -                                            int *success_count, 
    9.62 -                                            domid_t domid)
    9.63 +static inline int
    9.64 +HYPERVISOR_mmu_update(
    9.65 +    mmu_update_t *req, int count, int *success_count, domid_t domid)
    9.66  {
    9.67      int ret;
    9.68      unsigned long ign1, ign2, ign3, ign4;
    9.69 @@ -89,18 +66,16 @@ static __inline__ int HYPERVISOR_mmu_upd
    9.70      __asm__ __volatile__ (
    9.71          TRAP_INSTR
    9.72          : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    9.73 -        : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
    9.74 -          "3" (success_count), "4" (domid)
    9.75 -        : "memory" );
    9.76 +	: "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
    9.77 +        "3" (success_count), "4" (domid)
    9.78 +	: "memory" );
    9.79  
    9.80      return ret;
    9.81  }
    9.82  
    9.83 -
    9.84 -static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, 
    9.85 -                                           int count, 
    9.86 -                                           int *success_count, 
    9.87 -                                           domid_t domid)
    9.88 +static inline int
    9.89 +HYPERVISOR_mmuext_op(
    9.90 +    struct mmuext_op *op, int count, int *success_count, domid_t domid)
    9.91  {
    9.92      int ret;
    9.93      unsigned long ign1, ign2, ign3, ign4;
    9.94 @@ -108,70 +83,65 @@ static __inline__ int HYPERVISOR_mmuext_
    9.95      __asm__ __volatile__ (
    9.96          TRAP_INSTR
    9.97          : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    9.98 -        : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
    9.99 -          "3" (success_count), "4" (domid)
   9.100 -        : "memory" );
   9.101 +	: "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
   9.102 +        "3" (success_count), "4" (domid)
   9.103 +	: "memory" );
   9.104  
   9.105      return ret;
   9.106  }
   9.107  
   9.108 -
   9.109 -
   9.110 -static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
   9.111 +static inline int
   9.112 +HYPERVISOR_set_gdt(
   9.113 +    unsigned long *frame_list, int entries)
   9.114  {
   9.115      int ret;
   9.116 +    unsigned long ign1, ign2;
   9.117 +
   9.118      __asm__ __volatile__ (
   9.119          TRAP_INSTR
   9.120 -        : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), 
   9.121 -        _a1 (frame_list), _a2 (entries) : "memory" );
   9.122 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.123 +	: "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
   9.124 +	: "memory" );
   9.125  
   9.126  
   9.127      return ret;
   9.128  }
   9.129  
   9.130 -static __inline__ int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
   9.131 +static inline int
   9.132 +HYPERVISOR_stack_switch(
   9.133 +    unsigned long ss, unsigned long esp)
   9.134  {
   9.135      int ret;
   9.136 +    unsigned long ign1, ign2;
   9.137 +
   9.138      __asm__ __volatile__ (
   9.139          TRAP_INSTR
   9.140 -        : "=a" (ret) : "0" (__HYPERVISOR_stack_switch),
   9.141 -        _a1 (ss), _a2 (esp) : "memory" );
   9.142 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.143 +	: "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
   9.144 +	: "memory" );
   9.145  
   9.146      return ret;
   9.147  }
   9.148  
   9.149 -#ifdef __i386__
   9.150 -static __inline__ int HYPERVISOR_set_callbacks(
   9.151 +static inline int
   9.152 +HYPERVISOR_set_callbacks(
   9.153      unsigned long event_selector, unsigned long event_address,
   9.154      unsigned long failsafe_selector, unsigned long failsafe_address)
   9.155  {
   9.156      int ret;
   9.157 +    unsigned long ign1, ign2, ign3, ign4;
   9.158 +
   9.159      __asm__ __volatile__ (
   9.160          TRAP_INSTR
   9.161 -        : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
   9.162 -        _a1 (event_selector), _a2 (event_address), 
   9.163 -        _a3 (failsafe_selector), _a4 (failsafe_address) : "memory" );
   9.164 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   9.165 +	: "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
   9.166 +	  "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
   9.167 +	: "memory" );
   9.168  
   9.169      return ret;
   9.170  }
   9.171 -#else
   9.172 -static __inline__ int HYPERVISOR_set_callbacks(
   9.173 -    unsigned long event_address,
   9.174 -    unsigned long failsafe_address,
   9.175 -    unsigned long syscall_address)
   9.176 -{
   9.177 -    int ret;
   9.178 -    __asm__ __volatile__ (
   9.179 -        TRAP_INSTR
   9.180 -        : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks),
   9.181 -        _a1 (event_address), _a2 (failsafe_address), 
   9.182 -        _a3 (syscall_address) : "memory" );
   9.183  
   9.184 -    return ret;
   9.185 -}
   9.186 -#endif
   9.187 -
   9.188 -static __inline__ int
   9.189 +static inline int
   9.190  HYPERVISOR_fpu_taskswitch(
   9.191      int set)
   9.192  {
   9.193 @@ -187,67 +157,106 @@ HYPERVISOR_fpu_taskswitch(
   9.194      return ret;
   9.195  }
   9.196  
   9.197 -static __inline__ int HYPERVISOR_yield(void)
   9.198 +static inline int
   9.199 +HYPERVISOR_yield(
   9.200 +    void)
   9.201  {
   9.202      int ret;
   9.203 +    unsigned long ign;
   9.204 +
   9.205      __asm__ __volatile__ (
   9.206          TRAP_INSTR
   9.207 -        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
   9.208 -        _a1 (SCHEDOP_yield) : "memory" );
   9.209 -
   9.210 -    return ret;
   9.211 -}
   9.212 -
   9.213 -static __inline__ int HYPERVISOR_block(void)
   9.214 -{
   9.215 -    int ret;
   9.216 -    __asm__ __volatile__ (
   9.217 -        TRAP_INSTR
   9.218 -        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
   9.219 -        _a1 (SCHEDOP_block) : "memory" );
   9.220 +        : "=a" (ret), "=b" (ign)
   9.221 +	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
   9.222 +	: "memory", "ecx" );
   9.223  
   9.224      return ret;
   9.225  }
   9.226  
   9.227 -static __inline__ int HYPERVISOR_shutdown(void)
   9.228 +static inline int
   9.229 +HYPERVISOR_block(
   9.230 +    void)
   9.231  {
   9.232      int ret;
   9.233 +    unsigned long ign1;
   9.234      __asm__ __volatile__ (
   9.235          TRAP_INSTR
   9.236 -        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
   9.237 -        _a1 (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
   9.238 -        : "memory" );
   9.239 +        : "=a" (ret), "=b" (ign1)
   9.240 +	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
   9.241 +	: "memory", "ecx" );
   9.242  
   9.243      return ret;
   9.244  }
   9.245  
   9.246 -static __inline__ int HYPERVISOR_reboot(void)
   9.247 +static inline int
   9.248 +HYPERVISOR_shutdown(
   9.249 +    void)
   9.250  {
   9.251      int ret;
   9.252 +    unsigned long ign1;
   9.253      __asm__ __volatile__ (
   9.254          TRAP_INSTR
   9.255 -        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
   9.256 -        _a1 (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
   9.257 -        : "memory" );
   9.258 +        : "=a" (ret), "=b" (ign1)
   9.259 +	: "0" (__HYPERVISOR_sched_op),
   9.260 +	  "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
   9.261 +        : "memory", "ecx" );
   9.262  
   9.263      return ret;
   9.264  }
   9.265  
   9.266 -static __inline__ int HYPERVISOR_suspend(unsigned long srec)
   9.267 +static inline int
   9.268 +HYPERVISOR_reboot(
   9.269 +    void)
   9.270  {
   9.271      int ret;
   9.272 -    /* NB. On suspend, control software expects a suspend record in %esi. */
   9.273 +    unsigned long ign1;
   9.274      __asm__ __volatile__ (
   9.275          TRAP_INSTR
   9.276 -        : "=a" (ret) : "0" (__HYPERVISOR_sched_op),
   9.277 -        _a1 (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 
   9.278 -        "S" (srec) : "memory" );
   9.279 +        : "=a" (ret), "=b" (ign1)
   9.280 +	: "0" (__HYPERVISOR_sched_op),
   9.281 +	  "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
   9.282 +        : "memory", "ecx" );
   9.283  
   9.284      return ret;
   9.285  }
   9.286  
   9.287 -#ifdef __i386__
   9.288 -static __inline__ long HYPERVISOR_set_timer_op( u64 timeout )
   9.289 +static inline int
   9.290 +HYPERVISOR_suspend(
   9.291 +    unsigned long srec)
   9.292 +{
   9.293 +    int ret;
   9.294 +    unsigned long ign1, ign2;
   9.295 +
   9.296 +    /* NB. On suspend, control software expects a suspend record in %esi. */
   9.297 +    __asm__ __volatile__ (
   9.298 +        TRAP_INSTR
   9.299 +        : "=a" (ret), "=b" (ign1), "=S" (ign2)
   9.300 +	: "0" (__HYPERVISOR_sched_op),
   9.301 +        "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 
   9.302 +        "S" (srec) : "memory", "ecx");
   9.303 +
   9.304 +    return ret;
   9.305 +}
   9.306 +
   9.307 +static inline int
   9.308 +HYPERVISOR_crash(
   9.309 +    void)
   9.310 +{
   9.311 +    int ret;
   9.312 +    unsigned long ign1;
   9.313 +    __asm__ __volatile__ (
   9.314 +        TRAP_INSTR
   9.315 +        : "=a" (ret), "=b" (ign1)
   9.316 +	: "0" (__HYPERVISOR_sched_op),
   9.317 +	  "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift))
   9.318 +        : "memory", "ecx" );
   9.319 +
   9.320 +    return ret;
   9.321 +}
   9.322 +
   9.323 +static inline long
   9.324 +HYPERVISOR_set_timer_op(
   9.325 +    u64 timeout)
   9.326  {
   9.327      int ret;
   9.328      unsigned long timeout_hi = (unsigned long)(timeout>>32);
   9.329 @@ -262,8 +271,516 @@ static __inline__ long HYPERVISOR_set_ti
   9.330  
   9.331      return ret;
   9.332  }
   9.333 +
   9.334 +#if 0
   9.335 +static inline int
   9.336 +HYPERVISOR_dom0_op(
   9.337 +    dom0_op_t *dom0_op)
   9.338 +{
   9.339 +    int ret;
   9.340 +    unsigned long ign1;
   9.341 +
   9.342 +    dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   9.343 +    __asm__ __volatile__ (
   9.344 +        TRAP_INSTR
   9.345 +        : "=a" (ret), "=b" (ign1)
   9.346 +	: "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
   9.347 +	: "memory");
   9.348 +
   9.349 +    return ret;
   9.350 +}
   9.351 +#endif
   9.352 +
   9.353 +static inline int
   9.354 +HYPERVISOR_set_debugreg(
   9.355 +    int reg, unsigned long value)
   9.356 +{
   9.357 +    int ret;
   9.358 +    unsigned long ign1, ign2;
   9.359 +    __asm__ __volatile__ (
   9.360 +        TRAP_INSTR
   9.361 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.362 +	: "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
   9.363 +	: "memory" );
   9.364 +
   9.365 +    return ret;
   9.366 +}
   9.367 +
   9.368 +static inline unsigned long
   9.369 +HYPERVISOR_get_debugreg(
   9.370 +    int reg)
   9.371 +{
   9.372 +    unsigned long ret;
   9.373 +    unsigned long ign;
   9.374 +    __asm__ __volatile__ (
   9.375 +        TRAP_INSTR
   9.376 +        : "=a" (ret), "=b" (ign)
   9.377 +	: "0" (__HYPERVISOR_get_debugreg), "1" (reg)
   9.378 +	: "memory" );
   9.379 +
   9.380 +    return ret;
   9.381 +}
   9.382 +
   9.383 +static inline int
   9.384 +HYPERVISOR_update_descriptor(
   9.385 +    u64 ma, u64 desc)
   9.386 +{
   9.387 +    int ret;
   9.388 +    unsigned long ign1, ign2, ign3, ign4;
   9.389 +
   9.390 +    __asm__ __volatile__ (
   9.391 +        TRAP_INSTR
   9.392 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   9.393 +	: "0" (__HYPERVISOR_update_descriptor),
   9.394 +	  "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)),
   9.395 +	  "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32))
   9.396 +	: "memory" );
   9.397 +
   9.398 +    return ret;
   9.399 +}
   9.400 +
   9.401 +static inline int
   9.402 +HYPERVISOR_dom_mem_op(
   9.403 +    unsigned int op, unsigned long *extent_list,
   9.404 +    unsigned long nr_extents, unsigned int extent_order)
   9.405 +{
   9.406 +    int ret;
   9.407 +    unsigned long ign1, ign2, ign3, ign4, ign5;
   9.408 +
   9.409 +    __asm__ __volatile__ (
   9.410 +        TRAP_INSTR
   9.411 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
   9.412 +	  "=D" (ign5)
   9.413 +	: "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
   9.414 +	  "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
   9.415 +        : "memory" );
   9.416 +
   9.417 +    return ret;
   9.418 +}
   9.419 +
   9.420 +static inline int
   9.421 +HYPERVISOR_multicall(
   9.422 +    void *call_list, int nr_calls)
   9.423 +{
   9.424 +    int ret;
   9.425 +    unsigned long ign1, ign2;
   9.426 +
   9.427 +    __asm__ __volatile__ (
   9.428 +        TRAP_INSTR
   9.429 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.430 +	: "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
   9.431 +	: "memory" );
   9.432 +
   9.433 +    return ret;
   9.434 +}
   9.435 +
   9.436 +static inline int
   9.437 +HYPERVISOR_update_va_mapping(
   9.438 +    unsigned long va, pte_t new_val, unsigned long flags)
   9.439 +{
   9.440 +    int ret;
   9.441 +    unsigned long ign1, ign2, ign3, ign4;
   9.442 +
   9.443 +    __asm__ __volatile__ (
   9.444 +        TRAP_INSTR
   9.445 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   9.446 +	: "0" (__HYPERVISOR_update_va_mapping), 
   9.447 +          "1" (va), "2" ((new_val).pte_low),
   9.448 +#ifdef CONFIG_X86_PAE
   9.449 +	  "3" ((new_val).pte_high),
   9.450  #else
   9.451 -static __inline__ long HYPERVISOR_set_timer_op( u64 timeout )
   9.452 +	  "3" (0),
   9.453 +#endif
   9.454 +	  "4" (flags)
   9.455 +	: "memory" );
   9.456 +
   9.457 +    return ret;
   9.458 +}
   9.459 +
   9.460 +static inline int
   9.461 +HYPERVISOR_event_channel_op(
   9.462 +    void *op)
   9.463 +{
   9.464 +    int ret;
   9.465 +    unsigned long ignore;
   9.466 +    __asm__ __volatile__ (
   9.467 +        TRAP_INSTR
   9.468 +        : "=a" (ret), "=b" (ignore)
   9.469 +	: "0" (__HYPERVISOR_event_channel_op), "1" (op)
   9.470 +	: "memory" );
   9.471 +
   9.472 +    return ret;
   9.473 +}
   9.474 +
   9.475 +static inline int
   9.476 +HYPERVISOR_xen_version(
   9.477 +    int cmd)
   9.478 +{
   9.479 +    int ret;
   9.480 +    unsigned long ignore;
   9.481 +
   9.482 +    __asm__ __volatile__ (
   9.483 +        TRAP_INSTR
   9.484 +        : "=a" (ret), "=b" (ignore)
   9.485 +	: "0" (__HYPERVISOR_xen_version), "1" (cmd)
   9.486 +	: "memory" );
   9.487 +
   9.488 +    return ret;
   9.489 +}
   9.490 +
   9.491 +static inline int
   9.492 +HYPERVISOR_console_io(
   9.493 +    int cmd, int count, char *str)
   9.494 +{
   9.495 +    int ret;
   9.496 +    unsigned long ign1, ign2, ign3;
   9.497 +    __asm__ __volatile__ (
   9.498 +        TRAP_INSTR
   9.499 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
   9.500 +	: "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
   9.501 +	: "memory" );
   9.502 +
   9.503 +    return ret;
   9.504 +}
   9.505 +
   9.506 +static inline int
   9.507 +HYPERVISOR_physdev_op(
   9.508 +    void *physdev_op)
   9.509 +{
   9.510 +    int ret;
   9.511 +    unsigned long ign;
   9.512 +
   9.513 +    __asm__ __volatile__ (
   9.514 +        TRAP_INSTR
   9.515 +        : "=a" (ret), "=b" (ign)
   9.516 +	: "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
   9.517 +	: "memory" );
   9.518 +
   9.519 +    return ret;
   9.520 +}
   9.521 +
   9.522 +static inline int
   9.523 +HYPERVISOR_grant_table_op(
   9.524 +    unsigned int cmd, void *uop, unsigned int count)
   9.525 +{
   9.526 +    int ret;
   9.527 +    unsigned long ign1, ign2, ign3;
   9.528 +
   9.529 +    __asm__ __volatile__ (
   9.530 +        TRAP_INSTR
   9.531 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
   9.532 +	: "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
   9.533 +	: "memory" );
   9.534 +
   9.535 +    return ret;
   9.536 +}
   9.537 +
   9.538 +static inline int
   9.539 +HYPERVISOR_update_va_mapping_otherdomain(
   9.540 +    unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
   9.541 +{
   9.542 +    int ret;
   9.543 +    unsigned long ign1, ign2, ign3, ign4, ign5;
   9.544 +
   9.545 +    __asm__ __volatile__ (
   9.546 +        TRAP_INSTR
   9.547 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3),
   9.548 +	  "=S" (ign4), "=D" (ign5)
   9.549 +	: "0" (__HYPERVISOR_update_va_mapping_otherdomain),
   9.550 +          "1" (va), "2" ((new_val).pte_low),
   9.551 +#ifdef CONFIG_X86_PAE
   9.552 +	  "3" ((new_val).pte_high),
   9.553 +#else
   9.554 +	  "3" (0),
   9.555 +#endif
   9.556 +	  "4" (flags), "5" (domid) :
   9.557 +        "memory" );
   9.558 +    
   9.559 +    return ret;
   9.560 +}
   9.561 +
   9.562 +static inline int
   9.563 +HYPERVISOR_vm_assist(
   9.564 +    unsigned int cmd, unsigned int type)
   9.565 +{
   9.566 +    int ret;
   9.567 +    unsigned long ign1, ign2;
   9.568 +
   9.569 +    __asm__ __volatile__ (
   9.570 +        TRAP_INSTR
   9.571 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.572 +	: "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
   9.573 +	: "memory" );
   9.574 +
   9.575 +    return ret;
   9.576 +}
   9.577 +
   9.578 +static inline int
   9.579 +HYPERVISOR_boot_vcpu(
   9.580 +    unsigned long vcpu, vcpu_guest_context_t *ctxt)
   9.581 +{
   9.582 +    int ret;
   9.583 +    unsigned long ign1, ign2;
   9.584 +
   9.585 +    __asm__ __volatile__ (
   9.586 +        TRAP_INSTR
   9.587 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.588 +	: "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt)
   9.589 +	: "memory");
   9.590 +
   9.591 +    return ret;
   9.592 +}
   9.593 +
   9.594 +static inline int
   9.595 +HYPERVISOR_vcpu_down(
   9.596 +    int vcpu)
   9.597 +{
   9.598 +    int ret;
   9.599 +    unsigned long ign1;
   9.600 +    /* Yes, I really do want to clobber edx here: when we resume a
   9.601 +       vcpu after unpickling a multi-processor domain, it returns
   9.602 +       here, but clobbers all of the call clobbered registers. */
   9.603 +    __asm__ __volatile__ (
   9.604 +        TRAP_INSTR
   9.605 +        : "=a" (ret), "=b" (ign1)
   9.606 +	: "0" (__HYPERVISOR_sched_op),
   9.607 +	  "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift))
   9.608 +        : "memory", "ecx", "edx" );
   9.609 +
   9.610 +    return ret;
   9.611 +}
   9.612 +
   9.613 +static inline int
   9.614 +HYPERVISOR_vcpu_up(
   9.615 +    int vcpu)
   9.616 +{
   9.617 +    int ret;
   9.618 +    unsigned long ign1;
   9.619 +    __asm__ __volatile__ (
   9.620 +        TRAP_INSTR
   9.621 +        : "=a" (ret), "=b" (ign1)
   9.622 +	: "0" (__HYPERVISOR_sched_op),
   9.623 +	  "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift))
   9.624 +        : "memory", "ecx" );
   9.625 +
   9.626 +    return ret;
   9.627 +}
   9.628 +
   9.629 +static inline int
   9.630 +HYPERVISOR_vcpu_pickle(
   9.631 +    int vcpu, vcpu_guest_context_t *ctxt)
   9.632 +{
   9.633 +    int ret;
   9.634 +    unsigned long ign1, ign2;
   9.635 +    __asm__ __volatile__ (
   9.636 +        TRAP_INSTR
   9.637 +        : "=a" (ret), "=b" (ign1), "=c" (ign2)
   9.638 +	: "0" (__HYPERVISOR_sched_op),
   9.639 +	  "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)),
   9.640 +	  "2" (ctxt)
   9.641 +        : "memory" );
   9.642 +
   9.643 +    return ret;
   9.644 +}
   9.645 +#elif defined(__x86_64__)
   9.646 +
   9.647 +#define __syscall_clobber "r11","rcx","memory"
   9.648 +
   9.649 +/*
   9.650 + * Assembler stubs for hyper-calls.
   9.651 + */
   9.652 +static inline int
   9.653 +HYPERVISOR_set_trap_table(
   9.654 +    trap_info_t *table)
   9.655 +{
   9.656 +    int ret;
   9.657 +
   9.658 +    __asm__ __volatile__ (
   9.659 +        TRAP_INSTR
   9.660 +        : "=a" (ret)
   9.661 +	: "0" ((unsigned long)__HYPERVISOR_set_trap_table), "D" (table)
   9.662 +	: __syscall_clobber );
   9.663 +
   9.664 +    return ret;
   9.665 +}
   9.666 +
   9.667 +static inline int
   9.668 +HYPERVISOR_mmu_update(
   9.669 +    mmu_update_t *req, int count, int *success_count, domid_t domid)
   9.670 +{
   9.671 +    int ret;
   9.672 +
   9.673 +    __asm__ __volatile__ (
   9.674 +        "movq %5, %%r10;" TRAP_INSTR
   9.675 +        : "=a" (ret)
   9.676 +	: "0" ((unsigned long)__HYPERVISOR_mmu_update), "D" (req), "S" ((long)count),
   9.677 +	  "d" (success_count), "g" ((unsigned long)domid)
   9.678 +	: __syscall_clobber, "r10" );
   9.679 +
   9.680 +    return ret;
   9.681 +}
   9.682 +
   9.683 +static inline int
   9.684 +HYPERVISOR_mmuext_op(
   9.685 +    struct mmuext_op *op, int count, int *success_count, domid_t domid)
   9.686 +{
   9.687 +    int ret;
   9.688 +
   9.689 +    __asm__ __volatile__ (
   9.690 +        "movq %5, %%r10;" TRAP_INSTR
   9.691 +        : "=a" (ret)
   9.692 +        : "0" (__HYPERVISOR_mmuext_op), "D" (op), "S" ((long)count), 
   9.693 +          "d" (success_count), "g" ((unsigned long)domid)
   9.694 +        : __syscall_clobber, "r10" );
   9.695 +
   9.696 +    return ret;
   9.697 +}
   9.698 +
   9.699 +static inline int
   9.700 +HYPERVISOR_set_gdt(
   9.701 +    unsigned long *frame_list, int entries)
   9.702 +{
   9.703 +    int ret;
   9.704 +
   9.705 +    __asm__ __volatile__ (
   9.706 +        TRAP_INSTR
   9.707 +        : "=a" (ret)
   9.708 +	: "0" ((unsigned long)__HYPERVISOR_set_gdt), "D" (frame_list), "S" ((long)entries)
   9.709 +	: __syscall_clobber );
   9.710 +
   9.711 +
   9.712 +    return ret;
   9.713 +}
   9.714 +static inline int
   9.715 +HYPERVISOR_stack_switch(
   9.716 +    unsigned long ss, unsigned long esp)
   9.717 +{
   9.718 +    int ret;
   9.719 +
   9.720 +    __asm__ __volatile__ (
   9.721 +        TRAP_INSTR
   9.722 +        : "=a" (ret)
   9.723 +	: "0" ((unsigned long)__HYPERVISOR_stack_switch), "D" (ss), "S" (esp)
   9.724 +	: __syscall_clobber );
   9.725 +
   9.726 +    return ret;
   9.727 +}
   9.728 +
   9.729 +static inline int
   9.730 +HYPERVISOR_set_callbacks(
   9.731 +    unsigned long event_address, unsigned long failsafe_address, 
   9.732 +    unsigned long syscall_address)
   9.733 +{
   9.734 +    int ret;
   9.735 +
   9.736 +    __asm__ __volatile__ (
   9.737 +        TRAP_INSTR
   9.738 +        : "=a" (ret)
   9.739 +	: "0" ((unsigned long)__HYPERVISOR_set_callbacks), "D" (event_address),
   9.740 +	  "S" (failsafe_address), "d" (syscall_address)
   9.741 +	: __syscall_clobber );
   9.742 +
   9.743 +    return ret;
   9.744 +}
   9.745 +
   9.746 +static inline int
   9.747 +HYPERVISOR_fpu_taskswitch(
   9.748 +    int set)
   9.749 +{
   9.750 +    int ret;
   9.751 +    __asm__ __volatile__ (
   9.752 +        TRAP_INSTR
   9.753 +        : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_fpu_taskswitch),
   9.754 +          "D" ((unsigned long) set) : __syscall_clobber );
   9.755 +
   9.756 +    return ret;
   9.757 +}
   9.758 +
   9.759 +static inline int
   9.760 +HYPERVISOR_yield(
   9.761 +    void)
   9.762 +{
   9.763 +    int ret;
   9.764 +
   9.765 +    __asm__ __volatile__ (
   9.766 +        TRAP_INSTR
   9.767 +        : "=a" (ret)
   9.768 +	: "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_yield)
   9.769 +	: __syscall_clobber );
   9.770 +
   9.771 +    return ret;
   9.772 +}
   9.773 +
   9.774 +static inline int
   9.775 +HYPERVISOR_block(
   9.776 +    void)
   9.777 +{
   9.778 +    int ret;
   9.779 +    __asm__ __volatile__ (
   9.780 +        TRAP_INSTR
   9.781 +        : "=a" (ret)
   9.782 +	: "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_block)
   9.783 +	: __syscall_clobber );
   9.784 +
   9.785 +    return ret;
   9.786 +}
   9.787 +
   9.788 +static inline int
   9.789 +HYPERVISOR_shutdown(
   9.790 +    void)
   9.791 +{
   9.792 +    int ret;
   9.793 +    __asm__ __volatile__ (
   9.794 +        TRAP_INSTR
   9.795 +        : "=a" (ret)
   9.796 +	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   9.797 +	  "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)))
   9.798 +	: __syscall_clobber );
   9.799 +
   9.800 +    return ret;
   9.801 +}
   9.802 +
   9.803 +static inline int
   9.804 +HYPERVISOR_reboot(
   9.805 +    void)
   9.806 +{
   9.807 +    int ret;
   9.808 +
   9.809 +    __asm__ __volatile__ (
   9.810 +        TRAP_INSTR
   9.811 +        : "=a" (ret)
   9.812 +	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   9.813 +	  "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)))
   9.814 +	: __syscall_clobber );
   9.815 +
   9.816 +    return ret;
   9.817 +}
   9.818 +
   9.819 +static inline int
   9.820 +HYPERVISOR_suspend(
   9.821 +    unsigned long srec)
   9.822 +{
   9.823 +    int ret;
   9.824 +
   9.825 +    /* NB. On suspend, control software expects a suspend record in %esi. */
   9.826 +    __asm__ __volatile__ (
   9.827 +        TRAP_INSTR
   9.828 +        : "=a" (ret)
   9.829 +	: "0" ((unsigned long)__HYPERVISOR_sched_op),
   9.830 +        "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift))), 
   9.831 +        "S" (srec)
   9.832 +	: __syscall_clobber );
   9.833 +
   9.834 +    return ret;
   9.835 +}
   9.836 +
   9.837 +/*
   9.838 + * We can have the timeout value in a single argument for the hypercall, but
   9.839 + * that will break the common code. 
   9.840 + */
   9.841 +static inline long
   9.842 +HYPERVISOR_set_timer_op(
   9.843 +    u64 timeout)
   9.844  {
   9.845      int ret;
   9.846  
    10.1 --- a/extras/mini-os/include/lib.h	Fri Sep 09 08:56:38 2005 +0000
    10.2 +++ b/extras/mini-os/include/lib.h	Fri Sep 09 10:20:25 2005 +0000
    10.3 @@ -60,10 +60,22 @@
    10.4  /* printing */
    10.5  #define printk  printf
    10.6  #define kprintf printf
    10.7 -int printf(const char *fmt, ...);
    10.8 -int vprintf(const char *fmt, va_list ap);
    10.9 -int sprintf(char *buf, const char *cfmt, ...);
   10.10 -int vsprintf(char *buf, const char *cfmt, va_list ap);
   10.11 +#define _p(_x) ((void *)(unsigned long)(_x))
   10.12 +void printf(const char *fmt, ...);
   10.13 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
   10.14 +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
   10.15 +int snprintf(char * buf, size_t size, const char *fmt, ...);
   10.16 +int scnprintf(char * buf, size_t size, const char *fmt, ...);
   10.17 +int vsprintf(char *buf, const char *fmt, va_list args);
   10.18 +int sprintf(char * buf, const char *fmt, ...);
   10.19 +int vsscanf(const char * buf, const char * fmt, va_list args);
   10.20 +int sscanf(const char * buf, const char * fmt, ...);
   10.21 +
   10.22 +long simple_strtol(const char *cp,char **endp,unsigned int base);
   10.23 +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
   10.24 +long long simple_strtoll(const char *cp,char **endp,unsigned int base);
   10.25 +unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base);
   10.26 +
   10.27  
   10.28  /* string and memory manipulation */
   10.29  int    memcmp(const void *cs, const void *ct, size_t count);
   10.30 @@ -77,6 +89,16 @@ size_t strnlen(const char *s, size_t cou
   10.31  size_t strlen(const char *s);
   10.32  char  *strchr(const char *s, int c);
   10.33  char  *strstr(const char *s1, const char *s2);
   10.34 +char * strcat(char * dest, const char * src);
   10.35 +
   10.36 +
   10.37 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   10.38 +
   10.39 +struct kvec {
   10.40 +    void *iov_base;
   10.41 +    size_t iov_len;
   10.42 +};
   10.43 +
   10.44  
   10.45  
   10.46  #endif /* _LIB_H_ */
    11.1 --- a/extras/mini-os/include/mm.h	Fri Sep 09 08:56:38 2005 +0000
    11.2 +++ b/extras/mini-os/include/mm.h	Fri Sep 09 10:20:25 2005 +0000
    11.3 @@ -25,6 +25,15 @@
    11.4  #ifndef _MM_H_
    11.5  #define _MM_H_
    11.6  
    11.7 +#ifdef __i386__
    11.8 +#include <xen/arch-x86_32.h>
    11.9 +#endif
   11.10 +
   11.11 +#ifdef __x86_64__
   11.12 +#include <xen/arch-x86_64.h>
   11.13 +#endif
   11.14 +
   11.15 +
   11.16  #ifdef __x86_64__
   11.17  
   11.18  #define L1_PAGETABLE_SHIFT      12
   11.19 @@ -56,6 +65,8 @@
   11.20  
   11.21  #define L1_PAGETABLE_ENTRIES    1024
   11.22  #define L2_PAGETABLE_ENTRIES    1024
   11.23 +
   11.24 +#elif defined(__x86_64__)
   11.25  #endif
   11.26  
   11.27  /* Given a virtual address, get an entry offset into a page table. */
   11.28 @@ -97,13 +108,15 @@
   11.29  
   11.30  extern unsigned long *phys_to_machine_mapping;
   11.31  #define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
   11.32 -#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
   11.33  static __inline__ unsigned long phys_to_machine(unsigned long phys)
   11.34  {
   11.35      unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT);
   11.36      machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK);
   11.37      return machine;
   11.38  }
   11.39 +
   11.40 +
   11.41 +#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
   11.42  static __inline__ unsigned long machine_to_phys(unsigned long machine)
   11.43  {
   11.44      unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT);
   11.45 @@ -119,16 +132,15 @@ static __inline__ unsigned long machine_
   11.46  
   11.47  #define to_phys(x)                 ((unsigned long)(x)-VIRT_START)
   11.48  #define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
   11.49 -#define __va to_virt
   11.50 -#define __pa to_phys
   11.51  
   11.52  #define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
   11.53 +#define mach_to_virt(_mach)        (to_virt(machine_to_phys(_mach)))
   11.54 +#define mfn_to_virt(_mfn)          (mach_to_virt(_mfn << PAGE_SHIFT))
   11.55  
   11.56  void init_mm(void);
   11.57  unsigned long alloc_pages(int order);
   11.58  #define alloc_page()    alloc_pages(0);
   11.59  void free_pages(void *pointer, int order);
   11.60 -//int is_mfn_mapped(unsigned long mfn);
   11.61  
   11.62  static __inline__ int get_order(unsigned long size)
   11.63  {
    12.1 --- a/extras/mini-os/include/os.h	Fri Sep 09 08:56:38 2005 +0000
    12.2 +++ b/extras/mini-os/include/os.h	Fri Sep 09 10:20:25 2005 +0000
    12.3 @@ -15,16 +15,17 @@
    12.4  #define unlikely(x)  __builtin_expect((x),0)
    12.5  
    12.6  #define smp_processor_id() 0
    12.7 -#define preempt_disable() ((void)0)
    12.8 -#define preempt_enable() ((void)0)
    12.9  
   12.10 -#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0))
   12.11  
   12.12  #ifndef __ASSEMBLY__
   12.13  #include <types.h>
   12.14 +#include <hypervisor.h>
   12.15  #endif
   12.16  #include <xen/xen.h>
   12.17  
   12.18 +
   12.19 +#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0))
   12.20 +
   12.21  #define __KERNEL_CS  FLAT_KERNEL_CS
   12.22  #define __KERNEL_DS  FLAT_KERNEL_DS
   12.23  #define __KERNEL_SS  FLAT_KERNEL_SS
   12.24 @@ -54,8 +55,6 @@
   12.25  /* Everything below this point is not included by assembler (.S) files. */
   12.26  #ifndef __ASSEMBLY__
   12.27  
   12.28 -#define pt_regs xen_regs
   12.29 -
   12.30  void trap_init(void);
   12.31  
   12.32  /* 
   12.33 @@ -69,10 +68,8 @@ void trap_init(void);
   12.34  #define __cli()								\
   12.35  do {									\
   12.36  	vcpu_info_t *_vcpu;						\
   12.37 -	preempt_disable();						\
   12.38  	_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()];	\
   12.39  	_vcpu->evtchn_upcall_mask = 1;					\
   12.40 -	preempt_enable_no_resched();					\
   12.41  	barrier();							\
   12.42  } while (0)
   12.43  
   12.44 @@ -80,13 +77,11 @@ do {									\
   12.45  do {									\
   12.46  	vcpu_info_t *_vcpu;						\
   12.47  	barrier();							\
   12.48 -	preempt_disable();						\
   12.49  	_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()];	\
   12.50  	_vcpu->evtchn_upcall_mask = 0;					\
   12.51  	barrier(); /* unmask then check (avoid races) */		\
   12.52  	if ( unlikely(_vcpu->evtchn_upcall_pending) )			\
   12.53  		force_evtchn_callback();				\
   12.54 -	preempt_enable();						\
   12.55  } while (0)
   12.56  
   12.57  #define __save_flags(x)							\
   12.58 @@ -100,15 +95,12 @@ do {									\
   12.59  do {									\
   12.60  	vcpu_info_t *_vcpu;						\
   12.61  	barrier();							\
   12.62 -	preempt_disable();						\
   12.63  	_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()];	\
   12.64  	if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {			\
   12.65  		barrier(); /* unmask then check (avoid races) */	\
   12.66  		if ( unlikely(_vcpu->evtchn_upcall_pending) )		\
   12.67  			force_evtchn_callback();			\
   12.68 -		preempt_enable();					\
   12.69 -	} else								\
   12.70 -		preempt_enable_no_resched();				\
   12.71 +	}\
   12.72  } while (0)
   12.73  
   12.74  #define safe_halt()		((void)0)
   12.75 @@ -116,11 +108,9 @@ do {									\
   12.76  #define __save_and_cli(x)						\
   12.77  do {									\
   12.78  	vcpu_info_t *_vcpu;						\
   12.79 -	preempt_disable();						\
   12.80  	_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()];	\
   12.81  	(x) = _vcpu->evtchn_upcall_mask;				\
   12.82  	_vcpu->evtchn_upcall_mask = 1;					\
   12.83 -	preempt_enable_no_resched();					\
   12.84  	barrier();							\
   12.85  } while (0)
   12.86  
   12.87 @@ -136,6 +126,15 @@ do {									\
   12.88  /* This is a barrier for the compiler only, NOT the processor! */
   12.89  #define barrier() __asm__ __volatile__("": : :"memory")
   12.90  
   12.91 +#if defined(__i386__)
   12.92 +#define mb()    __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
   12.93 +#define rmb()   __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
   12.94 +#elif defined(__x86_64__)
   12.95 +#define mb()    __asm__ __volatile__ ("mfence":::"memory")
   12.96 +#define rmb()   __asm__ __volatile__ ("lfence":::"memory")
   12.97 +#endif
   12.98 +
   12.99 +
  12.100  #define LOCK_PREFIX ""
  12.101  #define LOCK ""
  12.102  #define ADDR (*(volatile long *) addr)
  12.103 @@ -147,39 +146,187 @@ do {									\
  12.104  typedef struct { volatile int counter; } atomic_t;
  12.105  
  12.106  
  12.107 -#define xchg(ptr,v) \
  12.108 -        ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
  12.109 +/************************** i386 *******************************/
  12.110 +#if defined (__i386__)
  12.111 +
  12.112 +#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
  12.113  struct __xchg_dummy { unsigned long a[100]; };
  12.114 -#define __xg(x) ((volatile struct __xchg_dummy *)(x))
  12.115 -static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr,
  12.116 -                                   int size)
  12.117 +#define __xg(x) ((struct __xchg_dummy *)(x))
  12.118 +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  12.119  {
  12.120 -    switch (size) {
  12.121 -    case 1:
  12.122 -        __asm__ __volatile__("xchgb %b0,%1"
  12.123 -                             :"=q" (x)
  12.124 -                             :"m" (*__xg(ptr)), "0" (x)
  12.125 -                             :"memory");
  12.126 -        break;
  12.127 -    case 2:
  12.128 -        __asm__ __volatile__("xchgw %w0,%1"
  12.129 -                             :"=r" (x)
  12.130 -                             :"m" (*__xg(ptr)), "0" (x)
  12.131 -                             :"memory");
  12.132 -        break;
  12.133 -    case 4:
  12.134 -        __asm__ __volatile__("xchgl %0,%1"
  12.135 -                             :"=r" (x)
  12.136 -                             :"m" (*__xg(ptr)), "0" (x)
  12.137 -                             :"memory");
  12.138 -        break;
  12.139 -    }
  12.140 -    return x;
  12.141 +	switch (size) {
  12.142 +		case 1:
  12.143 +			__asm__ __volatile__("xchgb %b0,%1"
  12.144 +				:"=q" (x)
  12.145 +				:"m" (*__xg(ptr)), "0" (x)
  12.146 +				:"memory");
  12.147 +			break;
  12.148 +		case 2:
  12.149 +			__asm__ __volatile__("xchgw %w0,%1"
  12.150 +				:"=r" (x)
  12.151 +				:"m" (*__xg(ptr)), "0" (x)
  12.152 +				:"memory");
  12.153 +			break;
  12.154 +		case 4:
  12.155 +			__asm__ __volatile__("xchgl %0,%1"
  12.156 +				:"=r" (x)
  12.157 +				:"m" (*__xg(ptr)), "0" (x)
  12.158 +				:"memory");
  12.159 +			break;
  12.160 +	}
  12.161 +	return x;
  12.162  }
  12.163  
  12.164  /**
  12.165   * test_and_clear_bit - Clear a bit and return its old value
  12.166 - * @nr: Bit to set
  12.167 + * @nr: Bit to clear
  12.168 + * @addr: Address to count from
  12.169 + *
  12.170 + * This operation is atomic and cannot be reordered.
  12.171 + * It can be reorderdered on other architectures other than x86.
  12.172 + * It also implies a memory barrier.
  12.173 + */
  12.174 +static inline int test_and_clear_bit(int nr, volatile unsigned long * addr)
  12.175 +{
  12.176 +	int oldbit;
  12.177 +
  12.178 +	__asm__ __volatile__( LOCK
  12.179 +		"btrl %2,%1\n\tsbbl %0,%0"
  12.180 +		:"=r" (oldbit),"=m" (ADDR)
  12.181 +		:"Ir" (nr) : "memory");
  12.182 +	return oldbit;
  12.183 +}
  12.184 +
  12.185 +static inline int constant_test_bit(int nr, const volatile unsigned long *addr)
  12.186 +{
  12.187 +	return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
  12.188 +}
  12.189 +
  12.190 +static inline int variable_test_bit(int nr, const volatile unsigned long * addr)
  12.191 +{
  12.192 +	int oldbit;
  12.193 +
  12.194 +	__asm__ __volatile__(
  12.195 +		"btl %2,%1\n\tsbbl %0,%0"
  12.196 +		:"=r" (oldbit)
  12.197 +		:"m" (ADDR),"Ir" (nr));
  12.198 +	return oldbit;
  12.199 +}
  12.200 +
  12.201 +#define test_bit(nr,addr) \
  12.202 +(__builtin_constant_p(nr) ? \
  12.203 + constant_test_bit((nr),(addr)) : \
  12.204 + variable_test_bit((nr),(addr)))
  12.205 +
  12.206 +/**
  12.207 + * set_bit - Atomically set a bit in memory
  12.208 + * @nr: the bit to set
  12.209 + * @addr: the address to start counting from
  12.210 + *
  12.211 + * This function is atomic and may not be reordered.  See __set_bit()
  12.212 + * if you do not require the atomic guarantees.
  12.213 + *
  12.214 + * Note: there are no guarantees that this function will not be reordered
  12.215 + * on non x86 architectures, so if you are writting portable code,
  12.216 + * make sure not to rely on its reordering guarantees.
  12.217 + *
  12.218 + * Note that @nr may be almost arbitrarily large; this function is not
  12.219 + * restricted to acting on a single-word quantity.
  12.220 + */
  12.221 +static inline void set_bit(int nr, volatile unsigned long * addr)
  12.222 +{
  12.223 +	__asm__ __volatile__( LOCK
  12.224 +		"btsl %1,%0"
  12.225 +		:"=m" (ADDR)
  12.226 +		:"Ir" (nr));
  12.227 +}
  12.228 +
  12.229 +/**
  12.230 + * clear_bit - Clears a bit in memory
  12.231 + * @nr: Bit to clear
  12.232 + * @addr: Address to start counting from
  12.233 + *
  12.234 + * clear_bit() is atomic and may not be reordered.  However, it does
  12.235 + * not contain a memory barrier, so if it is used for locking purposes,
  12.236 + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  12.237 + * in order to ensure changes are visible on other processors.
  12.238 + */
  12.239 +static inline void clear_bit(int nr, volatile unsigned long * addr)
  12.240 +{
  12.241 +	__asm__ __volatile__( LOCK
  12.242 +		"btrl %1,%0"
  12.243 +		:"=m" (ADDR)
  12.244 +		:"Ir" (nr));
  12.245 +}
  12.246 +
  12.247 +/**
  12.248 + * __ffs - find first bit in word.
  12.249 + * @word: The word to search
  12.250 + *
  12.251 + * Undefined if no bit exists, so code should check against 0 first.
  12.252 + */
  12.253 +static inline unsigned long __ffs(unsigned long word)
  12.254 +{
  12.255 +	__asm__("bsfl %1,%0"
  12.256 +		:"=r" (word)
  12.257 +		:"rm" (word));
  12.258 +	return word;
  12.259 +}
  12.260 +
  12.261 +
  12.262 +/*
  12.263 + * These have to be done with inline assembly: that way the bit-setting
  12.264 + * is guaranteed to be atomic. All bit operations return 0 if the bit
  12.265 + * was cleared before the operation and != 0 if it was not.
  12.266 + *
  12.267 + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  12.268 + */
  12.269 +#define ADDR (*(volatile long *) addr)
  12.270 +
  12.271 +#define rdtscll(val) \
  12.272 +     __asm__ __volatile__("rdtsc" : "=A" (val))
  12.273 +
  12.274 +
  12.275 +
  12.276 +#elif defined(__x86_64__)/* ifdef __i386__ */
  12.277 +/************************** x86_84 *******************************/
  12.278 +
  12.279 +#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
  12.280 +#define __xg(x) ((volatile long *)(x))
  12.281 +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  12.282 +{
  12.283 +	switch (size) {
  12.284 +		case 1:
  12.285 +			__asm__ __volatile__("xchgb %b0,%1"
  12.286 +				:"=q" (x)
  12.287 +				:"m" (*__xg(ptr)), "0" (x)
  12.288 +				:"memory");
  12.289 +			break;
  12.290 +		case 2:
  12.291 +			__asm__ __volatile__("xchgw %w0,%1"
  12.292 +				:"=r" (x)
  12.293 +				:"m" (*__xg(ptr)), "0" (x)
  12.294 +				:"memory");
  12.295 +			break;
  12.296 +		case 4:
  12.297 +			__asm__ __volatile__("xchgl %k0,%1"
  12.298 +				:"=r" (x)
  12.299 +				:"m" (*__xg(ptr)), "0" (x)
  12.300 +				:"memory");
  12.301 +			break;
  12.302 +		case 8:
  12.303 +			__asm__ __volatile__("xchgq %0,%1"
  12.304 +				:"=r" (x)
  12.305 +				:"m" (*__xg(ptr)), "0" (x)
  12.306 +				:"memory");
  12.307 +			break;
  12.308 +	}
  12.309 +	return x;
  12.310 +}
  12.311 +
  12.312 +/**
  12.313 + * test_and_clear_bit - Clear a bit and return its old value
  12.314 + * @nr: Bit to clear
  12.315   * @addr: Address to count from
  12.316   *
  12.317   * This operation is atomic and cannot be reordered.  
  12.318 @@ -187,29 +334,29 @@ static __inline__ unsigned long __xchg(u
  12.319   */
  12.320  static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
  12.321  {
  12.322 -        int oldbit;
  12.323 +	int oldbit;
  12.324  
  12.325 -        __asm__ __volatile__( LOCK_PREFIX
  12.326 -                "btrl %2,%1\n\tsbbl %0,%0"
  12.327 -                :"=r" (oldbit),"=m" (ADDR)
  12.328 -                :"Ir" (nr) : "memory");
  12.329 -        return oldbit;
  12.330 +	__asm__ __volatile__( LOCK_PREFIX
  12.331 +		"btrl %2,%1\n\tsbbl %0,%0"
  12.332 +		:"=r" (oldbit),"=m" (ADDR)
  12.333 +		:"dIr" (nr) : "memory");
  12.334 +	return oldbit;
  12.335  }
  12.336  
  12.337  static __inline__ int constant_test_bit(int nr, const volatile void * addr)
  12.338  {
  12.339 -    return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
  12.340 +	return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
  12.341  }
  12.342  
  12.343 -static __inline__ int variable_test_bit(int nr, volatile void * addr)
  12.344 +static __inline__ int variable_test_bit(int nr, volatile const void * addr)
  12.345  {
  12.346 -    int oldbit;
  12.347 -    
  12.348 -    __asm__ __volatile__(
  12.349 -        "btl %2,%1\n\tsbbl %0,%0"
  12.350 -        :"=r" (oldbit)
  12.351 -        :"m" (ADDR),"Ir" (nr));
  12.352 -    return oldbit;
  12.353 +	int oldbit;
  12.354 +
  12.355 +	__asm__ __volatile__(
  12.356 +		"btl %2,%1\n\tsbbl %0,%0"
  12.357 +		:"=r" (oldbit)
  12.358 +		:"m" (ADDR),"dIr" (nr));
  12.359 +	return oldbit;
  12.360  }
  12.361  
  12.362  #define test_bit(nr,addr) \
  12.363 @@ -230,10 +377,10 @@ static __inline__ int variable_test_bit(
  12.364   */
  12.365  static __inline__ void set_bit(int nr, volatile void * addr)
  12.366  {
  12.367 -        __asm__ __volatile__( LOCK_PREFIX
  12.368 -                "btsl %1,%0"
  12.369 -                :"=m" (ADDR)
  12.370 -                :"Ir" (nr));
  12.371 +	__asm__ __volatile__( LOCK_PREFIX
  12.372 +		"btsl %1,%0"
  12.373 +		:"=m" (ADDR)
  12.374 +		:"dIr" (nr) : "memory");
  12.375  }
  12.376  
  12.377  /**
  12.378 @@ -248,41 +395,44 @@ static __inline__ void set_bit(int nr, v
  12.379   */
  12.380  static __inline__ void clear_bit(int nr, volatile void * addr)
  12.381  {
  12.382 -        __asm__ __volatile__( LOCK_PREFIX
  12.383 -                "btrl %1,%0"
  12.384 -                :"=m" (ADDR)
  12.385 -                :"Ir" (nr));
  12.386 +	__asm__ __volatile__( LOCK_PREFIX
  12.387 +		"btrl %1,%0"
  12.388 +		:"=m" (ADDR)
  12.389 +		:"dIr" (nr));
  12.390  }
  12.391  
  12.392  /**
  12.393 - * atomic_inc - increment atomic variable
  12.394 - * @v: pointer of type atomic_t
  12.395 - * 
  12.396 - * Atomically increments @v by 1.  Note that the guaranteed
  12.397 - * useful range of an atomic_t is only 24 bits.
  12.398 - */ 
  12.399 -static __inline__ void atomic_inc(atomic_t *v)
  12.400 -{
  12.401 -        __asm__ __volatile__(
  12.402 -                LOCK "incl %0"
  12.403 -                :"=m" (v->counter)
  12.404 -                :"m" (v->counter));
  12.405 -}
  12.406 -
  12.407 -
  12.408 -#define rdtscll(val) \
  12.409 -     __asm__ __volatile__("rdtsc" : "=A" (val))
  12.410 -
  12.411 + * __ffs - find first bit in word.
  12.412 + * @word: The word to search
  12.413 + *
  12.414 + * Undefined if no bit exists, so code should check against 0 first.
  12.415 + */
  12.416  static __inline__ unsigned long __ffs(unsigned long word)
  12.417  {
  12.418 -        __asm__("bsfl %1,%0"
  12.419 -                :"=r" (word)
  12.420 -                :"rm" (word));
  12.421 -        return word;
  12.422 +	__asm__("bsfq %1,%0"
  12.423 +		:"=r" (word)
  12.424 +		:"rm" (word));
  12.425 +	return word;
  12.426  }
  12.427  
  12.428  #define ADDR (*(volatile long *) addr)
  12.429  
  12.430 +#define rdtscll(val) do { \
  12.431 +     unsigned int __a,__d; \
  12.432 +     asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
  12.433 +     (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
  12.434 +} while(0)
  12.435 +
  12.436 +
  12.437 +#else /* ifdef __x86_64__ */
  12.438 +#error "Unsupported architecture"
  12.439 +#endif
  12.440 +
  12.441 +
  12.442 +/********************* common i386 and x86_64  ****************************/
  12.443 +
  12.444 +
  12.445 +
  12.446  static __inline__ void synch_set_bit(int nr, volatile void * addr)
  12.447  {
  12.448      __asm__ __volatile__ ( 
  12.449 @@ -306,6 +456,14 @@ static __inline__ int synch_test_and_set
  12.450      return oldbit;
  12.451  }
  12.452  
  12.453 +static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
  12.454 +{
  12.455 +    int oldbit;
  12.456 +    __asm__ __volatile__ (
  12.457 +        "lock btrl %2,%1\n\tsbbl %0,%0"
  12.458 +        : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
  12.459 +    return oldbit;
  12.460 +}
  12.461  
  12.462  static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
  12.463  {
  12.464 @@ -326,9 +484,8 @@ static __inline__ int synch_var_test_bit
  12.465  (__builtin_constant_p(nr) ? \
  12.466   synch_const_test_bit((nr),(addr)) : \
  12.467   synch_var_test_bit((nr),(addr)))
  12.468 -#endif /* !__ASSEMBLY__ */
  12.469  
  12.470 -#define rdtsc(low,high) \
  12.471 -     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
  12.472  
  12.473 +
  12.474 +#endif /* not assembly */
  12.475  #endif /* _OS_H_ */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/extras/mini-os/include/sched.h	Fri Sep 09 10:20:25 2005 +0000
    13.3 @@ -0,0 +1,38 @@
    13.4 +#ifndef __SCHED_H__
    13.5 +#define __SCHED_H__
    13.6 +
    13.7 +#include <list.h>
    13.8 +
    13.9 +struct thread
   13.10 +{
   13.11 +    char *name;
   13.12 +    char *stack;
   13.13 +    unsigned long eps;
   13.14 +    unsigned long eip;
   13.15 +    struct list_head thread_list;
   13.16 +    u32 flags;
   13.17 +};
   13.18 +
   13.19 +
   13.20 +
   13.21 +void init_sched(void);
   13.22 +void run_idle_thread(void);
   13.23 +struct thread* create_thread(char *name, void (*function)(void *), void *data);
   13.24 +void schedule(void);
   13.25 +
   13.26 +static inline struct thread* get_current(void)
   13.27 +{
   13.28 +    struct thread **current;
   13.29 +#ifdef __i386__    
   13.30 +    __asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
   13.31 +#endif    
   13.32 +    return *current;
   13.33 +}
   13.34 +          
   13.35 +#define current get_current()
   13.36 +
   13.37 +
   13.38 +void wake(struct thread *thread);
   13.39 +void block(struct thread *thread);
   13.40 +
   13.41 +#endif /* __SCHED_H__ */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/extras/mini-os/include/semaphore.h	Fri Sep 09 10:20:25 2005 +0000
    14.3 @@ -0,0 +1,46 @@
    14.4 +#ifndef _SEMAPHORE_H_
    14.5 +#define _SEMAPHORE_H_
    14.6 +
    14.7 +#include <wait.h>
    14.8 +
    14.9 +/*
   14.10 + * Implementation of semaphore in Mini-os is simple, because 
   14.11 + * there are no preemptive threads, the atomicity is guaranteed.
   14.12 + */
   14.13 +
   14.14 +struct semaphore
   14.15 +{
   14.16 +	int count;
   14.17 +	struct wait_queue_head wait;
   14.18 +};
   14.19 +
   14.20 +
   14.21 +#define __SEMAPHORE_INITIALIZER(name, n)                            \
   14.22 +{                                                                   \
   14.23 +    .count    = n,                                                  \
   14.24 +    .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
   14.25 +}
   14.26 +
   14.27 +#define __MUTEX_INITIALIZER(name) \
   14.28 +    __SEMAPHORE_INITIALIZER(name,1)
   14.29 +                           
   14.30 +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
   14.31 +    struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
   14.32 +    
   14.33 +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
   14.34 +
   14.35 +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
   14.36 +
   14.37 +static void inline down(struct semaphore *sem)
   14.38 +{
   14.39 +    wait_event(sem->wait, sem->count > 0);
   14.40 +    sem->count--;
   14.41 +}
   14.42 +
   14.43 +static void inline up(struct semaphore *sem)
   14.44 +{
   14.45 +    sem->count++;
   14.46 +    wake_up(&sem->wait);
   14.47 +}
   14.48 +
   14.49 +#endif /* _SEMAPHORE_H */
    15.1 --- a/extras/mini-os/include/time.h	Fri Sep 09 08:56:38 2005 +0000
    15.2 +++ b/extras/mini-os/include/time.h	Fri Sep 09 10:20:25 2005 +0000
    15.3 @@ -58,6 +58,6 @@ void     init_time(void);
    15.4  s_time_t get_s_time(void);
    15.5  s_time_t get_v_time(void);
    15.6  void     gettimeofday(struct timeval *tv);
    15.7 -void     block(u32 millisecs);
    15.8 +void     block_domain(u32 millisecs);
    15.9  
   15.10  #endif /* _TIME_H_ */
    16.1 --- a/extras/mini-os/include/traps.h	Fri Sep 09 08:56:38 2005 +0000
    16.2 +++ b/extras/mini-os/include/traps.h	Fri Sep 09 10:20:25 2005 +0000
    16.3 @@ -17,6 +17,7 @@
    16.4  #ifndef _TRAPS_H_
    16.5  #define _TRAPS_H_
    16.6  
    16.7 +#ifdef __i386__
    16.8  struct pt_regs {
    16.9  	long ebx;
   16.10  	long ecx;
   16.11 @@ -34,7 +35,38 @@ struct pt_regs {
   16.12  	long esp;
   16.13  	int  xss;
   16.14  };
   16.15 +#elif __x86_64__
   16.16  
   16.17 +struct pt_regs {
   16.18 +	unsigned long r15;
   16.19 +	unsigned long r14;
   16.20 +	unsigned long r13;
   16.21 +	unsigned long r12;
   16.22 +	unsigned long rbp;
   16.23 +	unsigned long rbx;
   16.24 +/* arguments: non interrupts/non tracing syscalls only save upto here*/
   16.25 + 	unsigned long r11;
   16.26 +	unsigned long r10;	
   16.27 +	unsigned long r9;
   16.28 +	unsigned long r8;
   16.29 +	unsigned long rax;
   16.30 +	unsigned long rcx;
   16.31 +	unsigned long rdx;
   16.32 +	unsigned long rsi;
   16.33 +	unsigned long rdi;
   16.34 +	unsigned long orig_rax;
   16.35 +/* end of arguments */ 	
   16.36 +/* cpu exception frame or undefined */
   16.37 +	unsigned long rip;
   16.38 +	unsigned long cs;
   16.39 +	unsigned long eflags; 
   16.40 +	unsigned long rsp; 
   16.41 +	unsigned long ss;
   16.42 +/* top of stack page */ 
   16.43 +};
   16.44 +
   16.45 +
   16.46 +#endif
   16.47  
   16.48  void dump_regs(struct pt_regs *regs);
   16.49  
    17.1 --- a/extras/mini-os/include/types.h	Fri Sep 09 08:56:38 2005 +0000
    17.2 +++ b/extras/mini-os/include/types.h	Fri Sep 09 10:20:25 2005 +0000
    17.3 @@ -44,11 +44,19 @@ typedef unsigned long       u_long;
    17.4  typedef long long           quad_t;
    17.5  typedef unsigned long long  u_quad_t;
    17.6  typedef unsigned int        uintptr_t;
    17.7 +
    17.8 +typedef struct { unsigned long pte_low; } pte_t;
    17.9  #elif defined(__x86_64__)
   17.10  typedef long                quad_t;
   17.11  typedef unsigned long       u_quad_t;
   17.12  typedef unsigned long       uintptr_t;
   17.13 +
   17.14 +typedef struct { unsigned long pte; } pte_t;
   17.15  #endif
   17.16  
   17.17 +
   17.18 +
   17.19 +
   17.20 +#define INT_MAX         ((int)(~0U>>1))
   17.21  #define UINT_MAX            (~0U)
   17.22  #endif /* _TYPES_H_ */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/extras/mini-os/include/wait.h	Fri Sep 09 10:20:25 2005 +0000
    18.3 @@ -0,0 +1,91 @@
    18.4 +#ifndef __WAIT_H__
    18.5 +#define __WAIT_H__
    18.6 +
    18.7 +#include <sched.h>
    18.8 +#include <list.h>
    18.9 +#include <lib.h>
   18.10 +#include <os.h>
   18.11 +
   18.12 +struct wait_queue
   18.13 +{
   18.14 +    struct thread *thread;
   18.15 +    struct list_head thread_list;
   18.16 +};
   18.17 +
   18.18 +struct wait_queue_head
   18.19 +{
   18.20 +    /* TODO - lock required? */
   18.21 +    struct list_head thread_list;
   18.22 +};
   18.23 +
   18.24 +#define DECLARE_WAIT_QUEUE_HEAD(name) \
   18.25 +   struct wait_queue_head name =     \
   18.26 +        { .thread_list = { &(name).thread_list, &(name).thread_list} }
   18.27 +
   18.28 +#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                           \
   18.29 +    .thread_list      = { &(name).thread_list, &(name).thread_list } }
   18.30 +
   18.31 +
   18.32 +#define DEFINE_WAIT(name)                               \
   18.33 +struct wait_queue name = {                              \
   18.34 +    .thread       = current,                            \
   18.35 +    .thread_list  = LIST_HEAD_INIT((name).thread_list), \
   18.36 +}
   18.37 +
   18.38 +
   18.39 +
   18.40 +static inline void init_waitqueue_entry(struct wait_queue *q, struct thread *thread)
   18.41 +{
   18.42 +    q->thread = thread;
   18.43 +}
   18.44 +
   18.45 +
   18.46 +static inline void add_wait_queue(struct wait_queue_head *h, struct wait_queue *q)
   18.47 +{
   18.48 +    if (list_empty(&q->thread_list))
   18.49 +        list_add(&q->thread_list, &h->thread_list);   
   18.50 +}
   18.51 +
   18.52 +static inline void remove_wait_queue(struct wait_queue *q)
   18.53 +{
   18.54 +    list_del(&q->thread_list);
   18.55 +}
   18.56 +
   18.57 +static inline void wake_up(struct wait_queue_head *head)
   18.58 +{
   18.59 +    struct list_head *tmp, *next;
   18.60 +    list_for_each_safe(tmp, next, &head->thread_list)
   18.61 +    {
   18.62 +         struct wait_queue *curr;
   18.63 +         curr = list_entry(tmp, struct wait_queue, thread_list);
   18.64 +         wake(curr->thread);
   18.65 +    }
   18.66 +}
   18.67 +
   18.68 +#define wait_event(wq, condition) do{             \
   18.69 +    unsigned long flags;                          \
   18.70 +    if(condition)                                 \
   18.71 +        break;                                    \
   18.72 +    DEFINE_WAIT(__wait);                          \
   18.73 +    for(;;)                                       \
   18.74 +    {                                             \
   18.75 +        /* protect the list */                    \
   18.76 +        local_irq_save(flags);                    \
   18.77 +        add_wait_queue(&wq, &__wait);             \
   18.78 +        block(current);                           \
   18.79 +        local_irq_restore(flags);                 \
   18.80 +        if(condition)                             \
   18.81 +            break;                                \
   18.82 +        schedule();                               \
   18.83 +    }                                             \
   18.84 +    local_irq_save(flags);                        \
   18.85 +    /* need to wake up */                         \
   18.86 +    wake(current);                                \
   18.87 +    remove_wait_queue(&__wait);                   \
   18.88 +    local_irq_restore(flags);                     \
   18.89 +} while(0) 
   18.90 +
   18.91 +
   18.92 +
   18.93 +
   18.94 +#endif /* __WAIT_H__ */
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/extras/mini-os/include/xenbus.h	Fri Sep 09 10:20:25 2005 +0000
    19.3 @@ -0,0 +1,89 @@
    19.4 +/******************************************************************************
    19.5 + * xenbus.h
    19.6 + *
    19.7 + * Talks to Xen Store to figure out what devices we have.
    19.8 + *
    19.9 + * Copyright (C) 2005 Rusty Russell, IBM Corporation
   19.10 + * 
   19.11 + * This file may be distributed separately from the Linux kernel, or
   19.12 + * incorporated into other software packages, subject to the following license:
   19.13 + * 
   19.14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   19.15 + * of this source file (the "Software"), to deal in the Software without
   19.16 + * restriction, including without limitation the rights to use, copy, modify,
   19.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   19.18 + * and to permit persons to whom the Software is furnished to do so, subject to
   19.19 + * the following conditions:
   19.20 + * 
   19.21 + * The above copyright notice and this permission notice shall be included in
   19.22 + * all copies or substantial portions of the Software.
   19.23 + * 
   19.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   19.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   19.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   19.30 + * IN THE SOFTWARE.
   19.31 + */
   19.32 +
   19.33 +#ifndef _ASM_XEN_XENBUS_H
   19.34 +#define _ASM_XEN_XENBUS_H
   19.35 +
   19.36 +
   19.37 +/* Caller must hold this lock to call these functions: it's also held
   19.38 + * across watch callbacks. */
   19.39 +// TODO
   19.40 +//extern struct semaphore xenbus_lock;
   19.41 +
   19.42 +char **xenbus_directory(const char *dir, const char *node, unsigned int *num);
   19.43 +void *xenbus_read(const char *dir, const char *node, unsigned int *len);
   19.44 +int xenbus_write(const char *dir, const char *node,
   19.45 +		 const char *string, int createflags);
   19.46 +int xenbus_mkdir(const char *dir, const char *node);
   19.47 +int xenbus_exists(const char *dir, const char *node);
   19.48 +int xenbus_rm(const char *dir, const char *node);
   19.49 +int xenbus_transaction_start(const char *subtree);
   19.50 +int xenbus_transaction_end(int abort);
   19.51 +
   19.52 +/* Single read and scanf: returns -errno or num scanned if > 0. */
   19.53 +int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
   19.54 +	__attribute__((format(scanf, 3, 4)));
   19.55 +
   19.56 +/* Single printf and write: returns -errno or 0. */
   19.57 +int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
   19.58 +	__attribute__((format(printf, 3, 4)));
   19.59 +
   19.60 +/* Generic read function: NULL-terminated triples of name,
   19.61 + * sprintf-style type string, and pointer. Returns 0 or errno.*/
   19.62 +int xenbus_gather(const char *dir, ...);
   19.63 +
   19.64 +/* Register callback to watch this node. */
   19.65 +struct xenbus_watch
   19.66 +{
   19.67 +	struct list_head list;
   19.68 +	char *node;
   19.69 +	void (*callback)(struct xenbus_watch *, const char *node);
   19.70 +};
   19.71 +
   19.72 +int register_xenbus_watch(struct xenbus_watch *watch);
   19.73 +void unregister_xenbus_watch(struct xenbus_watch *watch);
   19.74 +void reregister_xenbus_watches(void);
   19.75 +
   19.76 +/* Called from xen core code. */
   19.77 +void xenbus_suspend(void);
   19.78 +void xenbus_resume(void);
   19.79 +
   19.80 +#define XENBUS_IS_ERR_READ(str) ({			\
   19.81 +	if (!IS_ERR(str) && strlen(str) == 0) {		\
   19.82 +		kfree(str);				\
   19.83 +		str = ERR_PTR(-ERANGE);			\
   19.84 +	}						\
   19.85 +	IS_ERR(str);					\
   19.86 +})
   19.87 +
   19.88 +#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
   19.89 +
   19.90 +int xs_init(void);
   19.91 +
   19.92 +#endif /* _ASM_XEN_XENBUS_H */
    20.1 --- a/extras/mini-os/kernel.c	Fri Sep 09 08:56:38 2005 +0000
    20.2 +++ b/extras/mini-os/kernel.c	Fri Sep 09 10:20:25 2005 +0000
    20.3 @@ -33,6 +33,8 @@
    20.4  #include <time.h>
    20.5  #include <types.h>
    20.6  #include <lib.h>
    20.7 +#include <sched.h>
    20.8 +#include <xenbus.h>
    20.9  
   20.10  /*
   20.11   * Shared page for communicating with the hypervisor.
   20.12 @@ -59,10 +61,12 @@ void failsafe_callback(void);
   20.13  
   20.14  extern char shared_info[PAGE_SIZE];
   20.15  
   20.16 +#define __pte(x) ((pte_t) { (0) } )
   20.17 +
   20.18  static shared_info_t *map_shared_info(unsigned long pa)
   20.19  {
   20.20      if ( HYPERVISOR_update_va_mapping(
   20.21 -        (unsigned long)shared_info, pa | 7, UVMF_INVLPG) )
   20.22 +        (unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG) )
   20.23      {
   20.24          printk("Failed to map shared_info!!\n");
   20.25          *(int*)0=0;
   20.26 @@ -77,7 +81,6 @@ static shared_info_t *map_shared_info(un
   20.27  void start_kernel(start_info_t *si)
   20.28  {
   20.29      static char hello[] = "Bootstrapping...\n";
   20.30 -    int i;
   20.31      (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
   20.32  
   20.33      /* Copy the start_info struct to a globally-accessible area. */
   20.34 @@ -96,7 +99,6 @@ void start_kernel(start_info_t *si)
   20.35          (unsigned long)hypervisor_callback,
   20.36          (unsigned long)failsafe_callback, 0);
   20.37  #endif
   20.38 -
   20.39      trap_init();
   20.40  
   20.41      /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
   20.42 @@ -119,7 +121,6 @@ void start_kernel(start_info_t *si)
   20.43       * If used for porting another OS, start here to figure out your
   20.44       * guest os entry point. Otherwise continue below...
   20.45       */
   20.46 -
   20.47      /* init memory management */
   20.48      init_mm();
   20.49  
   20.50 @@ -127,15 +128,15 @@ void start_kernel(start_info_t *si)
   20.51      init_events();
   20.52      /* init time and timers */
   20.53      init_time();
   20.54 +    
   20.55 +    /* init scheduler */
   20.56 +    init_sched();
   20.57  
   20.58 -    /* do nothing */
   20.59 -    i = 0;
   20.60 -    for ( ; ; ) 
   20.61 -    {      
   20.62 -//        HYPERVISOR_yield();
   20.63 -        block(100);
   20.64 -        i++;
   20.65 -    }
   20.66 +    /* init xenbus */
   20.67 +    xs_init();
   20.68 +    
   20.69 +    /* Everything initialised, start idle thread */
   20.70 +    run_idle_thread();
   20.71  }
   20.72  
   20.73  
    21.1 --- a/extras/mini-os/lib/printf.c	Fri Sep 09 08:56:38 2005 +0000
    21.2 +++ b/extras/mini-os/lib/printf.c	Fri Sep 09 10:20:25 2005 +0000
    21.3 @@ -1,21 +1,19 @@
    21.4 -/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
    21.5 +/* 
    21.6   ****************************************************************************
    21.7   * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
    21.8   ****************************************************************************
    21.9   *
   21.10   *        File: printf.c
   21.11   *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
   21.12 - *     Changes: 
   21.13 + *     Changes: Grzegorz Milos (gm281@cam.ac.uk) 
   21.14   *              
   21.15 - *        Date: Aug 2003
   21.16 + *        Date: Aug 2003, Aug 2005
   21.17   * 
   21.18   * Environment: Xen Minimal OS
   21.19   * Description: Library functions for printing
   21.20   *              (freebsd port, mainly sys/subr_prf.c)
   21.21   *
   21.22   ****************************************************************************
   21.23 - * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
   21.24 - ****************************************************************************
   21.25   *
   21.26   *-
   21.27   * Copyright (c) 1992, 1993
   21.28 @@ -60,409 +58,748 @@
   21.29  #include <types.h>
   21.30  #include <hypervisor.h>
   21.31  #include <lib.h>
   21.32 -
   21.33 -/****************************************************************************
   21.34 - * RN: printf family of routines
   21.35 - * taken mainly from sys/subr_prf.c
   21.36 - ****************************************************************************/
   21.37 -char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
   21.38 -#define hex2ascii(hex)  (hex2ascii_data[hex])
   21.39 -#define NBBY    8               /* number of bits in a byte */
   21.40 -#define MAXNBUF    (sizeof(quad_t) * NBBY + 1)
   21.41 -
   21.42 -static int kvprintf(char const *fmt, void *arg, int radix, va_list ap);
   21.43 -
   21.44 +#include <mm.h>
   21.45 +#include <ctype.h>
   21.46  
   21.47 -int
   21.48 -printf(const char *fmt, ...)
   21.49 +/**
   21.50 + * simple_strtoul - convert a string to an unsigned long
   21.51 + * @cp: The start of the string
   21.52 + * @endp: A pointer to the end of the parsed string will be placed here
   21.53 + * @base: The number base to use
   21.54 + */
   21.55 +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
   21.56  {
   21.57 -	va_list ap;
   21.58 -	int retval;
   21.59 -    static char printk_buf[1024];
   21.60 +    unsigned long result = 0,value;
   21.61  
   21.62 -	va_start(ap, fmt);
   21.63 -	retval = kvprintf(fmt, printk_buf, 10, ap);
   21.64 -    printk_buf[retval] = '\0';
   21.65 -	va_end(ap);
   21.66 -    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(printk_buf), 
   21.67 -                                printk_buf);
   21.68 -	return retval;
   21.69 +    if (!base) {
   21.70 +        base = 10;
   21.71 +        if (*cp == '0') {
   21.72 +            base = 8;
   21.73 +            cp++;
   21.74 +            if ((*cp == 'x') && isxdigit(cp[1])) {
   21.75 +                cp++;
   21.76 +                base = 16;
   21.77 +            }
   21.78 +        }
   21.79 +    }
   21.80 +    while (isxdigit(*cp) &&
   21.81 +           (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
   21.82 +        result = result*base + value;
   21.83 +        cp++;
   21.84 +    }
   21.85 +    if (endp)
   21.86 +        *endp = (char *)cp;
   21.87 +    return result;
   21.88  }
   21.89  
   21.90 -int
   21.91 -vprintf(const char *fmt, va_list ap)
   21.92 +/**
   21.93 + * simple_strtol - convert a string to a signed long
   21.94 + * @cp: The start of the string
   21.95 + * @endp: A pointer to the end of the parsed string will be placed here
   21.96 + * @base: The number base to use
   21.97 + */
   21.98 +long simple_strtol(const char *cp,char **endp,unsigned int base)
   21.99  {
  21.100 -	int retval;
  21.101 -    static char printk_buf[1024];
  21.102 -	retval = kvprintf(fmt, printk_buf, 10, ap);
  21.103 -    printk_buf[retval] = '\0';
  21.104 -    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(printk_buf),
  21.105 -                                printk_buf);
  21.106 -	return retval;
  21.107 +    if(*cp=='-')
  21.108 +        return -simple_strtoul(cp+1,endp,base);
  21.109 +    return simple_strtoul(cp,endp,base);
  21.110  }
  21.111  
  21.112 -int
  21.113 -sprintf(char *buf, const char *cfmt, ...)
  21.114 +/**
  21.115 + * simple_strtoull - convert a string to an unsigned long long
  21.116 + * @cp: The start of the string
  21.117 + * @endp: A pointer to the end of the parsed string will be placed here
  21.118 + * @base: The number base to use
  21.119 + */
  21.120 +unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
  21.121  {
  21.122 -	int retval;
  21.123 -	va_list ap;
  21.124 +    unsigned long long result = 0,value;
  21.125  
  21.126 -	va_start(ap, cfmt);
  21.127 -	retval = kvprintf(cfmt, (void *)buf, 10, ap);
  21.128 -	buf[retval] = '\0';
  21.129 -	va_end(ap);
  21.130 -	return retval;
  21.131 +    if (!base) {
  21.132 +        base = 10;
  21.133 +        if (*cp == '0') {
  21.134 +            base = 8;
  21.135 +            cp++;
  21.136 +            if ((*cp == 'x') && isxdigit(cp[1])) {
  21.137 +                cp++;
  21.138 +                base = 16;
  21.139 +            }
  21.140 +        }
  21.141 +    }
  21.142 +    while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
  21.143 +                                                               ? toupper(*cp) : *cp)-'A'+10) < base) {
  21.144 +        result = result*base + value;
  21.145 +        cp++;
  21.146 +    }
  21.147 +    if (endp)
  21.148 +        *endp = (char *)cp;
  21.149 +    return result;
  21.150  }
  21.151  
  21.152 -int
  21.153 -vsprintf(char *buf, const char *cfmt, va_list ap)
  21.154 +/**
  21.155 + * simple_strtoll - convert a string to a signed long long
  21.156 + * @cp: The start of the string
  21.157 + * @endp: A pointer to the end of the parsed string will be placed here
  21.158 + * @base: The number base to use
  21.159 + */
  21.160 +long long simple_strtoll(const char *cp,char **endp,unsigned int base)
  21.161  {
  21.162 -	int retval;
  21.163 +    if(*cp=='-')
  21.164 +        return -simple_strtoull(cp+1,endp,base);
  21.165 +    return simple_strtoull(cp,endp,base);
  21.166 +}
  21.167  
  21.168 -	retval = kvprintf(cfmt, (void *)buf, 10, ap);
  21.169 -	buf[retval] = '\0';
  21.170 -	return retval;
  21.171 +static int skip_atoi(const char **s)
  21.172 +{
  21.173 +    int i=0;
  21.174 +
  21.175 +    while (isdigit(**s))
  21.176 +        i = i*10 + *((*s)++) - '0';
  21.177 +    return i;
  21.178 +}
  21.179 +
  21.180 +#define ZEROPAD 1               /* pad with zero */
  21.181 +#define SIGN    2               /* unsigned/signed long */
  21.182 +#define PLUS    4               /* show plus */
  21.183 +#define SPACE   8               /* space if plus */
  21.184 +#define LEFT    16              /* left justified */
  21.185 +#define SPECIAL 32              /* 0x */
  21.186 +#define LARGE   64              /* use 'ABCDEF' instead of 'abcdef' */
  21.187 +
  21.188 +static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type)
  21.189 +{
  21.190 +    char c,sign,tmp[66];
  21.191 +    const char *digits;
  21.192 +    const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  21.193 +    const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  21.194 +    int i;
  21.195 +
  21.196 +    digits = (type & LARGE) ? large_digits : small_digits;
  21.197 +    if (type & LEFT)
  21.198 +        type &= ~ZEROPAD;
  21.199 +    if (base < 2 || base > 36)
  21.200 +        return buf;
  21.201 +    c = (type & ZEROPAD) ? '0' : ' ';
  21.202 +    sign = 0;
  21.203 +    if (type & SIGN) {
  21.204 +        if (num < 0) {
  21.205 +            sign = '-';
  21.206 +            num = -num;
  21.207 +            size--;
  21.208 +        } else if (type & PLUS) {
  21.209 +            sign = '+';
  21.210 +            size--;
  21.211 +        } else if (type & SPACE) {
  21.212 +            sign = ' ';
  21.213 +            size--;
  21.214 +        }
  21.215 +    }
  21.216 +    if (type & SPECIAL) {
  21.217 +        if (base == 16)
  21.218 +            size -= 2;
  21.219 +        else if (base == 8)
  21.220 +            size--;
  21.221 +    }
  21.222 +    i = 0;
  21.223 +    if (num == 0)
  21.224 +        tmp[i++]='0';
  21.225 +    else 
  21.226 +    {
  21.227 +        /* XXX KAF: force unsigned mod and div. */
  21.228 +        unsigned long long num2=(unsigned long long)num;
  21.229 +        unsigned int base2=(unsigned int)base;
  21.230 +        while (num2 != 0) { tmp[i++] = digits[num2%base2]; num2 /= base2; }
  21.231 +    }
  21.232 +    if (i > precision)
  21.233 +        precision = i;
  21.234 +    size -= precision;
  21.235 +    if (!(type&(ZEROPAD+LEFT))) {
  21.236 +        while(size-->0) {
  21.237 +            if (buf <= end)
  21.238 +                *buf = ' ';
  21.239 +            ++buf;
  21.240 +        }
  21.241 +    }
  21.242 +    if (sign) {
  21.243 +        if (buf <= end)
  21.244 +            *buf = sign;
  21.245 +        ++buf;
  21.246 +    }
  21.247 +    if (type & SPECIAL) {
  21.248 +        if (base==8) {
  21.249 +            if (buf <= end)
  21.250 +                *buf = '0';
  21.251 +            ++buf;
  21.252 +        } else if (base==16) {
  21.253 +            if (buf <= end)
  21.254 +                *buf = '0';
  21.255 +            ++buf;
  21.256 +            if (buf <= end)
  21.257 +                *buf = digits[33];
  21.258 +            ++buf;
  21.259 +        }
  21.260 +    }
  21.261 +    if (!(type & LEFT)) {
  21.262 +        while (size-- > 0) {
  21.263 +            if (buf <= end)
  21.264 +                *buf = c;
  21.265 +            ++buf;
  21.266 +        }
  21.267 +    }
  21.268 +    while (i < precision--) {
  21.269 +        if (buf <= end)
  21.270 +            *buf = '0';
  21.271 +        ++buf;
  21.272 +    }
  21.273 +    while (i-- > 0) {
  21.274 +        if (buf <= end)
  21.275 +            *buf = tmp[i];
  21.276 +        ++buf;
  21.277 +    }
  21.278 +    while (size-- > 0) {
  21.279 +        if (buf <= end)
  21.280 +            *buf = ' ';
  21.281 +        ++buf;
  21.282 +    }
  21.283 +    return buf;
  21.284 +}
  21.285 +
  21.286 +/**
  21.287 +* vsnprintf - Format a string and place it in a buffer
  21.288 +* @buf: The buffer to place the result into
  21.289 +* @size: The size of the buffer, including the trailing null space
  21.290 +* @fmt: The format string to use
  21.291 +* @args: Arguments for the format string
  21.292 +*
  21.293 +* Call this function if you are already dealing with a va_list.
  21.294 +* You probably want snprintf instead.
  21.295 + */
  21.296 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
  21.297 +{
  21.298 +    int len;
  21.299 +    unsigned long long num;
  21.300 +    int i, base;
  21.301 +    char *str, *end, c;
  21.302 +    const char *s;
  21.303 +
  21.304 +    int flags;          /* flags to number() */
  21.305 +
  21.306 +    int field_width;    /* width of output field */
  21.307 +    int precision;              /* min. # of digits for integers; max
  21.308 +                                   number of chars for from string */
  21.309 +    int qualifier;              /* 'h', 'l', or 'L' for integer fields */
  21.310 +                                /* 'z' support added 23/7/1999 S.H.    */
  21.311 +                                /* 'z' changed to 'Z' --davidm 1/25/99 */
  21.312 +
  21.313 +    str = buf;
  21.314 +    end = buf + size - 1;
  21.315 +
  21.316 +    if (end < buf - 1) {
  21.317 +        end = ((void *) -1);
  21.318 +        size = end - buf + 1;
  21.319 +    }
  21.320 +
  21.321 +    for (; *fmt ; ++fmt) {
  21.322 +        if (*fmt != '%') {
  21.323 +            if (str <= end)
  21.324 +                *str = *fmt;
  21.325 +            ++str;
  21.326 +            continue;
  21.327 +        }
  21.328 +
  21.329 +        /* process flags */
  21.330 +        flags = 0;
  21.331 +    repeat:
  21.332 +        ++fmt;          /* this also skips first '%' */
  21.333 +        switch (*fmt) {
  21.334 +        case '-': flags |= LEFT; goto repeat;
  21.335 +        case '+': flags |= PLUS; goto repeat;
  21.336 +        case ' ': flags |= SPACE; goto repeat;
  21.337 +        case '#': flags |= SPECIAL; goto repeat;
  21.338 +        case '0': flags |= ZEROPAD; goto repeat;
  21.339 +        }
  21.340 +
  21.341 +        /* get field width */
  21.342 +        field_width = -1;
  21.343 +        if (isdigit(*fmt))
  21.344 +            field_width = skip_atoi(&fmt);
  21.345 +        else if (*fmt == '*') {
  21.346 +            ++fmt;
  21.347 +            /* it's the next argument */
  21.348 +            field_width = va_arg(args, int);
  21.349 +            if (field_width < 0) {
  21.350 +                field_width = -field_width;
  21.351 +                flags |= LEFT;
  21.352 +            }
  21.353 +        }
  21.354 +
  21.355 +        /* get the precision */
  21.356 +        precision = -1;
  21.357 +        if (*fmt == '.') {
  21.358 +            ++fmt;
  21.359 +            if (isdigit(*fmt))
  21.360 +                precision = skip_atoi(&fmt);
  21.361 +            else if (*fmt == '*') {
  21.362 +                ++fmt;
  21.363 +                          /* it's the next argument */
  21.364 +                precision = va_arg(args, int);
  21.365 +            }
  21.366 +            if (precision < 0)
  21.367 +                precision = 0;
  21.368 +        }
  21.369 +
  21.370 +        /* get the conversion qualifier */
  21.371 +        qualifier = -1;
  21.372 +        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
  21.373 +            qualifier = *fmt;
  21.374 +            ++fmt;
  21.375 +            if (qualifier == 'l' && *fmt == 'l') {
  21.376 +                qualifier = 'L';
  21.377 +                ++fmt;
  21.378 +            }
  21.379 +        }
  21.380 +        if (*fmt == 'q') {
  21.381 +            qualifier = 'L';
  21.382 +            ++fmt;
  21.383 +        }
  21.384 +
  21.385 +        /* default base */
  21.386 +        base = 10;
  21.387 +
  21.388 +        switch (*fmt) {
  21.389 +        case 'c':
  21.390 +            if (!(flags & LEFT)) {
  21.391 +                while (--field_width > 0) {
  21.392 +                    if (str <= end)
  21.393 +                        *str = ' ';
  21.394 +                    ++str;
  21.395 +                }
  21.396 +            }
  21.397 +            c = (unsigned char) va_arg(args, int);
  21.398 +            if (str <= end)
  21.399 +                *str = c;
  21.400 +            ++str;
  21.401 +            while (--field_width > 0) {
  21.402 +                if (str <= end)
  21.403 +                    *str = ' ';
  21.404 +                ++str;
  21.405 +            }
  21.406 +            continue;
  21.407 +
  21.408 +        case 's':
  21.409 +            s = va_arg(args, char *);
  21.410 +            if (!s)
  21.411 +                s = "<NULL>";
  21.412 +
  21.413 +            len = strnlen(s, precision);
  21.414 +
  21.415 +            if (!(flags & LEFT)) {
  21.416 +                while (len < field_width--) {
  21.417 +                    if (str <= end)
  21.418 +                        *str = ' ';
  21.419 +                    ++str;
  21.420 +                }
  21.421 +            }
  21.422 +            for (i = 0; i < len; ++i) {
  21.423 +                if (str <= end)
  21.424 +                    *str = *s;
  21.425 +                ++str; ++s;
  21.426 +            }
  21.427 +            while (len < field_width--) {
  21.428 +                if (str <= end)
  21.429 +                    *str = ' ';
  21.430 +                ++str;
  21.431 +            }
  21.432 +            continue;
  21.433 +
  21.434 +        case 'p':
  21.435 +            if (field_width == -1) {
  21.436 +                field_width = 2*sizeof(void *);
  21.437 +                flags |= ZEROPAD;
  21.438 +            }
  21.439 +            str = number(str, end,
  21.440 +                         (unsigned long) va_arg(args, void *),
  21.441 +                         16, field_width, precision, flags);
  21.442 +            continue;
  21.443 +
  21.444 +
  21.445 +        case 'n':
  21.446 +            /* FIXME:
  21.447 +             * What does C99 say about the overflow case here? */
  21.448 +            if (qualifier == 'l') {
  21.449 +                long * ip = va_arg(args, long *);
  21.450 +                *ip = (str - buf);
  21.451 +            } else if (qualifier == 'Z') {
  21.452 +                size_t * ip = va_arg(args, size_t *);
  21.453 +                *ip = (str - buf);
  21.454 +            } else {
  21.455 +                int * ip = va_arg(args, int *);
  21.456 +                *ip = (str - buf);
  21.457 +            }
  21.458 +            continue;
  21.459 +
  21.460 +        case '%':
  21.461 +            if (str <= end)
  21.462 +                *str = '%';
  21.463 +            ++str;
  21.464 +            continue;
  21.465 +
  21.466 +                        /* integer number formats - set up the flags and "break" */
  21.467 +        case 'o':
  21.468 +            base = 8;
  21.469 +            break;
  21.470 +
  21.471 +        case 'X':
  21.472 +            flags |= LARGE;
  21.473 +        case 'x':
  21.474 +            base = 16;
  21.475 +            break;
  21.476 +
  21.477 +        case 'd':
  21.478 +        case 'i':
  21.479 +            flags |= SIGN;
  21.480 +        case 'u':
  21.481 +            break;
  21.482 +
  21.483 +        default:
  21.484 +            if (str <= end)
  21.485 +                *str = '%';
  21.486 +            ++str;
  21.487 +            if (*fmt) {
  21.488 +                if (str <= end)
  21.489 +                    *str = *fmt;
  21.490 +                ++str;
  21.491 +            } else {
  21.492 +                --fmt;
  21.493 +            }
  21.494 +            continue;
  21.495 +        }
  21.496 +        if (qualifier == 'L')
  21.497 +            num = va_arg(args, long long);
  21.498 +        else if (qualifier == 'l') {
  21.499 +            num = va_arg(args, unsigned long);
  21.500 +            if (flags & SIGN)
  21.501 +                num = (signed long) num;
  21.502 +        } else if (qualifier == 'Z') {
  21.503 +            num = va_arg(args, size_t);
  21.504 +        } else if (qualifier == 'h') {
  21.505 +            num = (unsigned short) va_arg(args, int);
  21.506 +            if (flags & SIGN)
  21.507 +                num = (signed short) num;
  21.508 +        } else {
  21.509 +            num = va_arg(args, unsigned int);
  21.510 +            if (flags & SIGN)
  21.511 +                num = (signed int) num;
  21.512 +        }
  21.513 +
  21.514 +        str = number(str, end, num, base,
  21.515 +                     field_width, precision, flags);
  21.516 +    }
  21.517 +    if (str <= end)
  21.518 +        *str = '\0';
  21.519 +    else if (size > 0)
  21.520 +        /* don't write out a null byte if the buf size is zero */
  21.521 +        *end = '\0';
  21.522 +    /* the trailing null byte doesn't count towards the total
  21.523 +     * ++str;
  21.524 +     */
  21.525 +    return str-buf;
  21.526 +}
  21.527 +
  21.528 +/**
  21.529 + * snprintf - Format a string and place it in a buffer
  21.530 + * @buf: The buffer to place the result into
  21.531 + * @size: The size of the buffer, including the trailing null space
  21.532 + * @fmt: The format string to use
  21.533 + * @...: Arguments for the format string
  21.534 + */
  21.535 +int snprintf(char * buf, size_t size, const char *fmt, ...)
  21.536 +{
  21.537 +    va_list args;
  21.538 +    int i;
  21.539 +
  21.540 +    va_start(args, fmt);
  21.541 +    i=vsnprintf(buf,size,fmt,args);
  21.542 +    va_end(args);
  21.543 +    return i;
  21.544 +}
  21.545 +
  21.546 +/**
  21.547 + * vsprintf - Format a string and place it in a buffer
  21.548 + * @buf: The buffer to place the result into
  21.549 + * @fmt: The format string to use
  21.550 + * @args: Arguments for the format string
  21.551 + *
  21.552 + * Call this function if you are already dealing with a va_list.
  21.553 + * You probably want sprintf instead.
  21.554 + */
  21.555 +int vsprintf(char *buf, const char *fmt, va_list args)
  21.556 +{
  21.557 +    return vsnprintf(buf, 0xFFFFFFFFUL, fmt, args);
  21.558  }
  21.559  
  21.560  
  21.561 -/*
  21.562 - * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
  21.563 - * order; return an optional length and a pointer to the last character
  21.564 - * written in the buffer (i.e., the first character of the string).
  21.565 - * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
  21.566 +/**
  21.567 + * sprintf - Format a string and place it in a buffer
  21.568 + * @buf: The buffer to place the result into
  21.569 + * @fmt: The format string to use
  21.570 + * @...: Arguments for the format string
  21.571   */
  21.572 -static char *
  21.573 -ksprintn(char *nbuf, u_long ul, int base, int *lenp)
  21.574 +int sprintf(char * buf, const char *fmt, ...)
  21.575  {
  21.576 -	char *p;
  21.577 +    va_list args;
  21.578 +    int i;
  21.579  
  21.580 -	p = nbuf;
  21.581 -	*p = '\0';
  21.582 -	do {
  21.583 -		*++p = hex2ascii(ul % base);
  21.584 -	} while (ul /= base);
  21.585 -	if (lenp)
  21.586 -		*lenp = p - nbuf;
  21.587 -	return (p);
  21.588 -}
  21.589 -/* ksprintn, but for a quad_t. */
  21.590 -static char *
  21.591 -ksprintqn(char *nbuf, u_quad_t uq, int base, int *lenp)
  21.592 -{
  21.593 -	char *p;
  21.594 -
  21.595 -	p = nbuf;
  21.596 -	*p = '\0';
  21.597 -	do {
  21.598 -		*++p = hex2ascii(uq % base);
  21.599 -	} while (uq /= base);
  21.600 -	if (lenp)
  21.601 -		*lenp = p - nbuf;
  21.602 -	return (p);
  21.603 +    va_start(args, fmt);
  21.604 +    i=vsprintf(buf,fmt,args);
  21.605 +    va_end(args);
  21.606 +    return i;
  21.607  }
  21.608  
  21.609 -/*
  21.610 - * Scaled down version of printf(3).
  21.611 - *
  21.612 - * Two additional formats:
  21.613 - *
  21.614 - * The format %b is supported to decode error registers.
  21.615 - * Its usage is:
  21.616 - *
  21.617 - *	printf("reg=%b\n", regval, "<base><arg>*");
  21.618 - *
  21.619 - * where <base> is the output base expressed as a control character, e.g.
  21.620 - * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
  21.621 - * the first of which gives the bit number to be inspected (origin 1), and
  21.622 - * the next characters (up to a control character, i.e. a character <= 32),
  21.623 - * give the name of the register.  Thus:
  21.624 - *
  21.625 - *	kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
  21.626 - *
  21.627 - * would produce output:
  21.628 - *
  21.629 - *	reg=3<BITTWO,BITONE>
  21.630 - *
  21.631 - * XXX:  %D  -- Hexdump, takes pointer and separator string:
  21.632 - *		("%6D", ptr, ":")   -> XX:XX:XX:XX:XX:XX
  21.633 - *		("%*D", len, ptr, " " -> XX XX XX XX ...
  21.634 - */
  21.635 -
  21.636 -/* RN: This normally takes a function for output. 
  21.637 - * we always print to a string and the use HYPERCALL for write to console */
  21.638 -static int
  21.639 -kvprintf(char const *fmt, void *arg, int radix, va_list ap)
  21.640 -{
  21.641 -
  21.642 -#define PCHAR(c) {int cc=(c); *d++ = cc; retval++; }
  21.643 -
  21.644 -	char nbuf[MAXNBUF];
  21.645 -	char *p, *q, *d;
  21.646 -	u_char *up;
  21.647 -	int ch, n;
  21.648 -	u_long ul;
  21.649 -	u_quad_t uq;
  21.650 -	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
  21.651 -	int dwidth;
  21.652 -	char padc;
  21.653 -	int retval = 0;
  21.654 -
  21.655 -	ul = 0;
  21.656 -	uq = 0;
  21.657 -    d = (char *) arg;
  21.658 -
  21.659 -	if (fmt == NULL)
  21.660 -		fmt = "(fmt null)\n";
  21.661 -
  21.662 -	if (radix < 2 || radix > 36)
  21.663 -		radix = 10;
  21.664  
  21.665 -	for (;;) {
  21.666 -		padc = ' ';
  21.667 -		width = 0;
  21.668 -		while ((ch = (u_char)*fmt++) != '%') {
  21.669 -			if (ch == '\0') 
  21.670 -				return retval;
  21.671 -			PCHAR(ch);
  21.672 +void printf(const char *fmt, ...)
  21.673 +{
  21.674 +    static char   buf[1024];
  21.675 +    va_list       args;
  21.676 +    
  21.677 +    va_start(args, fmt);
  21.678 +    (void)vsnprintf(buf, sizeof(buf), fmt, args);
  21.679 +    va_end(args);        
  21.680 +   
  21.681 +    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
  21.682 +}
  21.683 +
  21.684 +/**
  21.685 + * vsscanf - Unformat a buffer into a list of arguments
  21.686 + * @buf:	input buffer
  21.687 + * @fmt:	format of buffer
  21.688 + * @args:	arguments
  21.689 + */
  21.690 +int vsscanf(const char * buf, const char * fmt, va_list args)
  21.691 +{
  21.692 +	const char *str = buf;
  21.693 +	char *next;
  21.694 +	char digit;
  21.695 +	int num = 0;
  21.696 +	int qualifier;
  21.697 +	int base;
  21.698 +	int field_width;
  21.699 +	int is_sign = 0;
  21.700 +
  21.701 +	while(*fmt && *str) {
  21.702 +		/* skip any white space in format */
  21.703 +		/* white space in format matchs any amount of
  21.704 +		 * white space, including none, in the input.
  21.705 +		 */
  21.706 +		if (isspace(*fmt)) {
  21.707 +			while (isspace(*fmt))
  21.708 +				++fmt;
  21.709 +			while (isspace(*str))
  21.710 +				++str;
  21.711  		}
  21.712 -		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
  21.713 -		sign = 0; dot = 0; dwidth = 0;
  21.714 -reswitch:	switch (ch = (u_char)*fmt++) {
  21.715 -		case '.':
  21.716 -			dot = 1;
  21.717 -			goto reswitch;
  21.718 -		case '#':
  21.719 -			sharpflag = 1;
  21.720 -			goto reswitch;
  21.721 -		case '+':
  21.722 -			sign = 1;
  21.723 -			goto reswitch;
  21.724 -		case '-':
  21.725 -			ladjust = 1;
  21.726 -			goto reswitch;
  21.727 -		case '%':
  21.728 -			PCHAR(ch);
  21.729 +
  21.730 +		/* anything that is not a conversion must match exactly */
  21.731 +		if (*fmt != '%' && *fmt) {
  21.732 +			if (*fmt++ != *str++)
  21.733 +				break;
  21.734 +			continue;
  21.735 +		}
  21.736 +
  21.737 +		if (!*fmt)
  21.738  			break;
  21.739 -		case '*':
  21.740 -			if (!dot) {
  21.741 -				width = va_arg(ap, int);
  21.742 -				if (width < 0) {
  21.743 -					ladjust = !ladjust;
  21.744 -					width = -width;
  21.745 +		++fmt;
  21.746 +		
  21.747 +		/* skip this conversion.
  21.748 +		 * advance both strings to next white space
  21.749 +		 */
  21.750 +		if (*fmt == '*') {
  21.751 +			while (!isspace(*fmt) && *fmt)
  21.752 +				fmt++;
  21.753 +			while (!isspace(*str) && *str)
  21.754 +				str++;
  21.755 +			continue;
  21.756 +		}
  21.757 +
  21.758 +		/* get field width */
  21.759 +		field_width = -1;
  21.760 +		if (isdigit(*fmt))
  21.761 +			field_width = skip_atoi(&fmt);
  21.762 +
  21.763 +		/* get conversion qualifier */
  21.764 +		qualifier = -1;
  21.765 +		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
  21.766 +		    *fmt == 'Z' || *fmt == 'z') {
  21.767 +			qualifier = *fmt++;
  21.768 +			if (unlikely(qualifier == *fmt)) {
  21.769 +				if (qualifier == 'h') {
  21.770 +					qualifier = 'H';
  21.771 +					fmt++;
  21.772 +				} else if (qualifier == 'l') {
  21.773 +					qualifier = 'L';
  21.774 +					fmt++;
  21.775  				}
  21.776 -			} else {
  21.777 -				dwidth = va_arg(ap, int);
  21.778 -			}
  21.779 -			goto reswitch;
  21.780 -		case '0':
  21.781 -			if (!dot) {
  21.782 -				padc = '0';
  21.783 -				goto reswitch;
  21.784  			}
  21.785 -		case '1': case '2': case '3': case '4':
  21.786 -		case '5': case '6': case '7': case '8': case '9':
  21.787 -				for (n = 0;; ++fmt) {
  21.788 -					n = n * 10 + ch - '0';
  21.789 -					ch = *fmt;
  21.790 -					if (ch < '0' || ch > '9')
  21.791 -						break;
  21.792 -				}
  21.793 -			if (dot)
  21.794 -				dwidth = n;
  21.795 -			else
  21.796 -				width = n;
  21.797 -			goto reswitch;
  21.798 -		case 'b':
  21.799 -			ul = va_arg(ap, int);
  21.800 -			p = va_arg(ap, char *);
  21.801 -			for (q = ksprintn(nbuf, ul, *p++, NULL); *q;)
  21.802 -				PCHAR(*q--);
  21.803 +		}
  21.804 +		base = 10;
  21.805 +		is_sign = 0;
  21.806  
  21.807 -			if (!ul)
  21.808 +		if (!*fmt || !*str)
  21.809 +			break;
  21.810 +
  21.811 +		switch(*fmt++) {
  21.812 +		case 'c':
  21.813 +		{
  21.814 +			char *s = (char *) va_arg(args,char*);
  21.815 +			if (field_width == -1)
  21.816 +				field_width = 1;
  21.817 +			do {
  21.818 +				*s++ = *str++;
  21.819 +			} while (--field_width > 0 && *str);
  21.820 +			num++;
  21.821 +		}
  21.822 +		continue;
  21.823 +		case 's':
  21.824 +		{
  21.825 +			char *s = (char *) va_arg(args, char *);
  21.826 +			if(field_width == -1)
  21.827 +				field_width = INT_MAX;
  21.828 +			/* first, skip leading white space in buffer */
  21.829 +			while (isspace(*str))
  21.830 +				str++;
  21.831 +
  21.832 +			/* now copy until next white space */
  21.833 +			while (*str && !isspace(*str) && field_width--) {
  21.834 +				*s++ = *str++;
  21.835 +			}
  21.836 +			*s = '\0';
  21.837 +			num++;
  21.838 +		}
  21.839 +		continue;
  21.840 +		case 'n':
  21.841 +			/* return number of characters read so far */
  21.842 +		{
  21.843 +			int *i = (int *)va_arg(args,int*);
  21.844 +			*i = str - buf;
  21.845 +		}
  21.846 +		continue;
  21.847 +		case 'o':
  21.848 +			base = 8;
  21.849 +			break;
  21.850 +		case 'x':
  21.851 +		case 'X':
  21.852 +			base = 16;
  21.853 +			break;
  21.854 +		case 'i':
  21.855 +                        base = 0;
  21.856 +		case 'd':
  21.857 +			is_sign = 1;
  21.858 +		case 'u':
  21.859 +			break;
  21.860 +		case '%':
  21.861 +			/* looking for '%' in str */
  21.862 +			if (*str++ != '%') 
  21.863 +				return num;
  21.864 +			continue;
  21.865 +		default:
  21.866 +			/* invalid format; stop here */
  21.867 +			return num;
  21.868 +		}
  21.869 +
  21.870 +		/* have some sort of integer conversion.
  21.871 +		 * first, skip white space in buffer.
  21.872 +		 */
  21.873 +		while (isspace(*str))
  21.874 +			str++;
  21.875 +
  21.876 +		digit = *str;
  21.877 +		if (is_sign && digit == '-')
  21.878 +			digit = *(str + 1);
  21.879 +
  21.880 +		if (!digit
  21.881 +                    || (base == 16 && !isxdigit(digit))
  21.882 +                    || (base == 10 && !isdigit(digit))
  21.883 +                    || (base == 8 && (!isdigit(digit) || digit > '7'))
  21.884 +                    || (base == 0 && !isdigit(digit)))
  21.885  				break;
  21.886  
  21.887 -			for (tmp = 0; *p;) {
  21.888 -				n = *p++;
  21.889 -				if (ul & (1 << (n - 1))) {
  21.890 -					PCHAR(tmp ? ',' : '<');
  21.891 -					for (; (n = *p) > ' '; ++p)
  21.892 -						PCHAR(n);
  21.893 -					tmp = 1;
  21.894 -				} else
  21.895 -					for (; *p > ' '; ++p)
  21.896 -						continue;
  21.897 -			}
  21.898 -			if (tmp)
  21.899 -				PCHAR('>');
  21.900 -			break;
  21.901 -		case 'c':
  21.902 -			PCHAR(va_arg(ap, int));
  21.903 -			break;
  21.904 -		case 'D':
  21.905 -			up = va_arg(ap, u_char *);
  21.906 -			p = va_arg(ap, char *);
  21.907 -			if (!width)
  21.908 -				width = 16;
  21.909 -			while(width--) {
  21.910 -				PCHAR(hex2ascii(*up >> 4));
  21.911 -				PCHAR(hex2ascii(*up & 0x0f));
  21.912 -				up++;
  21.913 -				if (width)
  21.914 -					for (q=p;*q;q++)
  21.915 -						PCHAR(*q);
  21.916 +		switch(qualifier) {
  21.917 +		case 'H':	/* that's 'hh' in format */
  21.918 +			if (is_sign) {
  21.919 +				signed char *s = (signed char *) va_arg(args,signed char *);
  21.920 +				*s = (signed char) simple_strtol(str,&next,base);
  21.921 +			} else {
  21.922 +				unsigned char *s = (unsigned char *) va_arg(args, unsigned char *);
  21.923 +				*s = (unsigned char) simple_strtoul(str, &next, base);
  21.924  			}
  21.925  			break;
  21.926 -		case 'd':
  21.927 -			if (qflag)
  21.928 -				uq = va_arg(ap, quad_t);
  21.929 -			else if (lflag)
  21.930 -				ul = va_arg(ap, long);
  21.931 -			else
  21.932 -				ul = va_arg(ap, int);
  21.933 -			sign = 1;
  21.934 -			base = 10;
  21.935 -			goto number;
  21.936 -		case 'l':
  21.937 -			if (lflag) {
  21.938 -				lflag = 0;
  21.939 -				qflag = 1;
  21.940 -			} else
  21.941 -				lflag = 1;
  21.942 -			goto reswitch;
  21.943 -		case 'o':
  21.944 -			if (qflag)
  21.945 -				uq = va_arg(ap, u_quad_t);
  21.946 -			else if (lflag)
  21.947 -				ul = va_arg(ap, u_long);
  21.948 -			else
  21.949 -				ul = va_arg(ap, u_int);
  21.950 -			base = 8;
  21.951 -			goto nosign;
  21.952 -		case 'p':
  21.953 -			ul = (uintptr_t)va_arg(ap, void *);
  21.954 -			base = 16;
  21.955 -			sharpflag = 0;
  21.956 -            padc  = '0';
  21.957 -            width = sizeof(uintptr_t)*2;
  21.958 -			goto nosign;
  21.959 -		case 'q':
  21.960 -			qflag = 1;
  21.961 -			goto reswitch;
  21.962 -		case 'n':
  21.963 -		case 'r':
  21.964 -			if (qflag)
  21.965 -				uq = va_arg(ap, u_quad_t);
  21.966 -			else if (lflag)
  21.967 -				ul = va_arg(ap, u_long);
  21.968 -			else
  21.969 -				ul = sign ?
  21.970 -				    (u_long)va_arg(ap, int) : va_arg(ap, u_int);
  21.971 -			base = radix;
  21.972 -			goto number;
  21.973 -		case 's':
  21.974 -			p = va_arg(ap, char *);
  21.975 -			if (p == NULL)
  21.976 -				p = "(null)";
  21.977 -			if (!dot)
  21.978 -				n = strlen (p);
  21.979 -			else
  21.980 -				for (n = 0; n < dwidth && p[n]; n++)
  21.981 -					continue;
  21.982 -
  21.983 -			width -= n;
  21.984 -
  21.985 -			if (!ladjust && width > 0)
  21.986 -				while (width--)
  21.987 -					PCHAR(padc);
  21.988 -			while (n--)
  21.989 -				PCHAR(*p++);
  21.990 -			if (ladjust && width > 0)
  21.991 -				while (width--)
  21.992 -					PCHAR(padc);
  21.993 +		case 'h':
  21.994 +			if (is_sign) {
  21.995 +				short *s = (short *) va_arg(args,short *);
  21.996 +				*s = (short) simple_strtol(str,&next,base);
  21.997 +			} else {
  21.998 +				unsigned short *s = (unsigned short *) va_arg(args, unsigned short *);
  21.999 +				*s = (unsigned short) simple_strtoul(str, &next, base);
 21.1000 +			}
 21.1001  			break;
 21.1002 -		case 'u':
 21.1003 -			if (qflag)
 21.1004 -				uq = va_arg(ap, u_quad_t);
 21.1005 -			else if (lflag)
 21.1006 -				ul = va_arg(ap, u_long);
 21.1007 -			else
 21.1008 -				ul = va_arg(ap, u_int);
 21.1009 -			base = 10;
 21.1010 -			goto nosign;
 21.1011 -		case 'x':
 21.1012 -		case 'X':
 21.1013 -			if (qflag)
 21.1014 -				uq = va_arg(ap, u_quad_t);
 21.1015 -			else if (lflag)
 21.1016 -				ul = va_arg(ap, u_long);
 21.1017 -			else
 21.1018 -				ul = va_arg(ap, u_int);
 21.1019 -			base = 16;
 21.1020 -			goto nosign;
 21.1021 -		case 'z':
 21.1022 -			if (qflag)
 21.1023 -				uq = va_arg(ap, u_quad_t);
 21.1024 -			else if (lflag)
 21.1025 -				ul = va_arg(ap, u_long);
 21.1026 -			else
 21.1027 -				ul = sign ?
 21.1028 -				    (u_long)va_arg(ap, int) : va_arg(ap, u_int);
 21.1029 -			base = 16;
 21.1030 -			goto number;
 21.1031 -nosign:			sign = 0;
 21.1032 -number:			
 21.1033 -			if (qflag) {
 21.1034 -				if (sign && (quad_t)uq < 0) {
 21.1035 -					neg = 1;
 21.1036 -					uq = -(quad_t)uq;
 21.1037 -				}
 21.1038 -				p = ksprintqn(nbuf, uq, base, &tmp);
 21.1039 +		case 'l':
 21.1040 +			if (is_sign) {
 21.1041 +				long *l = (long *) va_arg(args,long *);
 21.1042 +				*l = simple_strtol(str,&next,base);
 21.1043  			} else {
 21.1044 -				if (sign && (long)ul < 0) {
 21.1045 -					neg = 1;
 21.1046 -					ul = -(long)ul;
 21.1047 -				}
 21.1048 -				p = ksprintn(nbuf, ul, base, &tmp);
 21.1049 -			}
 21.1050 -			if (sharpflag && (qflag ? uq != 0 : ul != 0)) {
 21.1051 -				if (base == 8)
 21.1052 -					tmp++;
 21.1053 -				else if (base == 16)
 21.1054 -					tmp += 2;
 21.1055 +				unsigned long *l = (unsigned long*) va_arg(args,unsigned long*);
 21.1056 +				*l = simple_strtoul(str,&next,base);
 21.1057  			}
 21.1058 -			if (neg)
 21.1059 -				tmp++;
 21.1060 -
 21.1061 -			if (!ladjust && width && (width -= tmp) > 0)
 21.1062 -				while (width--)
 21.1063 -					PCHAR(padc);
 21.1064 -			if (neg)
 21.1065 -				PCHAR('-');
 21.1066 -			if (sharpflag && (qflag ? uq != 0 : ul != 0)) {
 21.1067 -				if (base == 8) {
 21.1068 -					PCHAR('0');
 21.1069 -				} else if (base == 16) {
 21.1070 -					PCHAR('0');
 21.1071 -					PCHAR('x');
 21.1072 -				}
 21.1073 +			break;
 21.1074 +		case 'L':
 21.1075 +			if (is_sign) {
 21.1076 +				long long *l = (long long*) va_arg(args,long long *);
 21.1077 +				*l = simple_strtoll(str,&next,base);
 21.1078 +			} else {
 21.1079 +				unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*);
 21.1080 +				*l = simple_strtoull(str,&next,base);
 21.1081  			}
 21.1082 -
 21.1083 -			while (*p)
 21.1084 -				PCHAR(*p--);
 21.1085 -
 21.1086 -			if (ladjust && width && (width -= tmp) > 0)
 21.1087 -				while (width--)
 21.1088 -					PCHAR(padc);
 21.1089 -
 21.1090  			break;
 21.1091 +		case 'Z':
 21.1092 +		case 'z':
 21.1093 +		{
 21.1094 +			size_t *s = (size_t*) va_arg(args,size_t*);
 21.1095 +			*s = (size_t) simple_strtoul(str,&next,base);
 21.1096 +		}
 21.1097 +		break;
 21.1098  		default:
 21.1099 -			PCHAR('%');
 21.1100 -			if (lflag)
 21.1101 -				PCHAR('l');
 21.1102 -			PCHAR(ch);
 21.1103 +			if (is_sign) {
 21.1104 +				int *i = (int *) va_arg(args, int*);
 21.1105 +				*i = (int) simple_strtol(str,&next,base);
 21.1106 +			} else {
 21.1107 +				unsigned int *i = (unsigned int*) va_arg(args, unsigned int*);
 21.1108 +				*i = (unsigned int) simple_strtoul(str,&next,base);
 21.1109 +			}
 21.1110  			break;
 21.1111  		}
 21.1112 +		num++;
 21.1113 +
 21.1114 +		if (!next)
 21.1115 +			break;
 21.1116 +		str = next;
 21.1117  	}
 21.1118 -#undef PCHAR
 21.1119 +	return num;
 21.1120  }
 21.1121  
 21.1122 +/**
 21.1123 + * sscanf - Unformat a buffer into a list of arguments
 21.1124 + * @buf:	input buffer
 21.1125 + * @fmt:	formatting of buffer
 21.1126 + * @...:	resulting arguments
 21.1127 + */
 21.1128 +int sscanf(const char * buf, const char * fmt, ...)
 21.1129 +{
 21.1130 +	va_list args;
 21.1131 +	int i;
 21.1132 +
 21.1133 +	va_start(args,fmt);
 21.1134 +	i = vsscanf(buf,fmt,args);
 21.1135 +	va_end(args);
 21.1136 +	return i;
 21.1137 +}
 21.1138 +
 21.1139 +
    22.1 --- a/extras/mini-os/lib/string.c	Fri Sep 09 08:56:38 2005 +0000
    22.2 +++ b/extras/mini-os/lib/string.c	Fri Sep 09 10:20:25 2005 +0000
    22.3 @@ -107,6 +107,19 @@ size_t strnlen(const char * s, size_t co
    22.4          return sc - s;
    22.5  }
    22.6  
    22.7 +
    22.8 +char * strcat(char * dest, const char * src)
    22.9 +{
   22.10 +    char *tmp = dest;
   22.11 +    
   22.12 +    while (*dest)
   22.13 +        dest++;
   22.14 +    
   22.15 +    while ((*dest++ = *src++) != '\0');
   22.16 +    
   22.17 +    return tmp;
   22.18 +}
   22.19 +
   22.20  size_t strlen(const char * s)
   22.21  {
   22.22  	const char *sc;
    23.1 --- a/extras/mini-os/mm.c	Fri Sep 09 08:56:38 2005 +0000
    23.2 +++ b/extras/mini-os/mm.c	Fri Sep 09 10:20:25 2005 +0000
    23.3 @@ -198,7 +198,6 @@ static void print_chunks(void *start, in
    23.4  #endif
    23.5  
    23.6  
    23.7 -
    23.8  /*
    23.9   * Initialise allocator, placing addresses [@min,@max] in free pool.
   23.10   * @min and @max are PHYSICAL addresses.
   23.11 @@ -486,16 +485,17 @@ void init_mm(void)
   23.12      phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
   23.13     
   23.14      /* First page follows page table pages and 3 more pages (store page etc) */
   23.15 -    start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames + 3;
   23.16 +    start_pfn = PFN_UP(to_phys(start_info.pt_base)) + start_info.nr_pt_frames + 3;
   23.17      max_pfn = start_info.nr_pages;
   23.18  
   23.19      printk("  start_pfn:    %lx\n", start_pfn);
   23.20      printk("  max_pfn:      %lx\n", max_pfn);
   23.21  
   23.22  
   23.23 +#ifdef __i386__
   23.24      build_pagetable(&start_pfn, &max_pfn);
   23.25 -    
   23.26 -#ifdef __i386__
   23.27 +#endif
   23.28 +
   23.29      /*
   23.30       * now we can initialise the page allocator
   23.31       */
   23.32 @@ -503,7 +503,5 @@ void init_mm(void)
   23.33             (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
   23.34             (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
   23.35      init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));   
   23.36 -#endif
   23.37 -    
   23.38      printk("MM: done\n");
   23.39  }
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/extras/mini-os/sched.c	Fri Sep 09 10:20:25 2005 +0000
    24.3 @@ -0,0 +1,300 @@
    24.4 +/* 
    24.5 + ****************************************************************************
    24.6 + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
    24.7 + ****************************************************************************
    24.8 + *
    24.9 + *        File: sched.c
   24.10 + *      Author: Grzegorz Milos
   24.11 + *     Changes: 
   24.12 + *              
   24.13 + *        Date: Aug 2005
   24.14 + * 
   24.15 + * Environment: Xen Minimal OS
   24.16 + * Description: simple scheduler for Mini-Os
   24.17 + *
   24.18 + * The scheduler is non-preemptive (cooperative), and schedules according 
   24.19 + * to Round Robin algorithm.
   24.20 + *
   24.21 + ****************************************************************************
   24.22 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   24.23 + * of this software and associated documentation files (the "Software"), to
   24.24 + * deal in the Software without restriction, including without limitation the
   24.25 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   24.26 + * sell copies of the Software, and to permit persons to whom the Software is
   24.27 + * furnished to do so, subject to the following conditions:
   24.28 + * 
   24.29 + * The above copyright notice and this permission notice shall be included in
   24.30 + * all copies or substantial portions of the Software.
   24.31 + * 
   24.32 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
   24.33 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
   24.34 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
   24.35 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
   24.36 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
   24.37 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
   24.38 + * DEALINGS IN THE SOFTWARE.
   24.39 + */
   24.40 +
   24.41 +#include <os.h>
   24.42 +#include <hypervisor.h>
   24.43 +#include <time.h>
   24.44 +#include <mm.h>
   24.45 +#include <types.h>
   24.46 +#include <lib.h>
   24.47 +#include <xmalloc.h>
   24.48 +#include <list.h>
   24.49 +#include <sched.h>
   24.50 +#include <semaphore.h>
   24.51 +
   24.52 +#ifdef SCHED_DEBUG
   24.53 +#define DEBUG(_f, _a...) \
   24.54 +    printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
   24.55 +#else
   24.56 +#define DEBUG(_f, _a...)    ((void)0)
   24.57 +#endif
   24.58 +
   24.59 +
   24.60 +#define RUNNABLE_FLAG   0x00000001
   24.61 +
   24.62 +#define is_runnable(_thread)    (_thread->flags & RUNNABLE_FLAG)
   24.63 +#define set_runnable(_thread)   (_thread->flags |= RUNNABLE_FLAG)
   24.64 +#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
   24.65 +
   24.66 +
   24.67 +struct thread *idle_thread;
   24.68 +LIST_HEAD(exited_threads);
   24.69 +
   24.70 +void dump_stack(struct thread *thread)
   24.71 +{
   24.72 +    unsigned long *bottom = (unsigned long *)thread->stack + 2048; 
   24.73 +    unsigned long *pointer = (unsigned long *)thread->eps;
   24.74 +    int count;
   24.75 +    printk("The stack for \"%s\"\n", thread->name);
   24.76 +    for(count = 0; count < 15 && pointer < bottom; count ++)
   24.77 +    {
   24.78 +        printk("[0x%lx] 0x%lx\n", pointer, *pointer);
   24.79 +        pointer++;
   24.80 +    }
   24.81 +    
   24.82 +    if(pointer < bottom) printk("Not the whole stack printed\n");
   24.83 +}
   24.84 +
   24.85 +#ifdef __i386__
   24.86 +#define switch_threads(prev, next) do {                                 \
   24.87 +    unsigned long esi,edi;                                              \
   24.88 +    __asm__ __volatile__("pushfl\n\t"                                   \
   24.89 +                         "pushl %%ebp\n\t"                              \
   24.90 +                         "movl %%esp,%0\n\t"         /* save ESP */     \
   24.91 +                         "movl %4,%%esp\n\t"        /* restore ESP */   \
   24.92 +                         "movl $1f,%1\n\t"          /* save EIP */      \
   24.93 +                         "pushl %5\n\t"             /* restore EIP */   \
   24.94 +                         "ret\n\t"                                      \
   24.95 +                         "1:\t"                                         \
   24.96 +                         "popl %%ebp\n\t"                               \
   24.97 +                         "popfl"                                        \
   24.98 +                         :"=m" (prev->eps),"=m" (prev->eip),            \
   24.99 +                          "=S" (esi),"=D" (edi)             \
  24.100 +                         :"m" (next->eps),"m" (next->eip),              \
  24.101 +                          "2" (prev), "d" (next));                      \
  24.102 +} while (0)
  24.103 +#elif __x86_64__
  24.104 +/* FIXME */
  24.105 +#endif
  24.106 +
  24.107 +void inline print_runqueue(void)
  24.108 +{
  24.109 +    struct list_head *it;
  24.110 +    struct thread *th;
  24.111 +    list_for_each(it, &idle_thread->thread_list)
  24.112 +    {
  24.113 +        th = list_entry(it, struct thread, thread_list);
  24.114 +        printk("   Thread \"%s\", runnable=%d\n", th->name, is_runnable(th));
  24.115 +    }
  24.116 +    printk("\n");
  24.117 +}
  24.118 +
  24.119 +
  24.120 +void schedule(void)
  24.121 +{
  24.122 +    struct thread *prev, *next, *thread;
  24.123 +    struct list_head *iterator;
  24.124 +    unsigned long flags;
  24.125 +    prev = current;
  24.126 +    local_irq_save(flags); 
  24.127 +    list_for_each(iterator, &exited_threads)
  24.128 +    {
  24.129 +        thread = list_entry(iterator, struct thread, thread_list);
  24.130 +        if(thread != prev)
  24.131 +        {
  24.132 +            list_del(&thread->thread_list);
  24.133 +            free_pages(thread->stack, 1);
  24.134 +            xfree(thread);
  24.135 +        }
  24.136 +    }
  24.137 +    next = idle_thread;    
  24.138 +    /* Thread list needs to be protected */
  24.139 +    list_for_each(iterator, &idle_thread->thread_list)
  24.140 +    {
  24.141 +        thread = list_entry(iterator, struct thread, thread_list);
  24.142 +        if(is_runnable(thread)) 
  24.143 +        {
  24.144 +            next = thread;
  24.145 +            /* Put this thread on the end of the list */
  24.146 +            list_del(&thread->thread_list);
  24.147 +            list_add_tail(&thread->thread_list, &idle_thread->thread_list);
  24.148 +            break;
  24.149 +        }
  24.150 +    }
  24.151 +    local_irq_restore(flags);
  24.152 +    /* Interrupting the switch is equivalent to having the next thread
  24.153 +       inturrupted at the return instruction. And therefore at safe point. */
  24.154 +/* The thread switching only works for i386 at the moment */    
  24.155 +#ifdef __i386__    
  24.156 +    if(prev != next) switch_threads(prev, next);
  24.157 +#endif    
  24.158 +}
  24.159 +
  24.160 +
  24.161 +
  24.162 +void exit_thread(struct thread *thread)
  24.163 +{
  24.164 +    unsigned long flags;
  24.165 +    printk("Thread \"%s\" exited.\n", thread->name);
  24.166 +    local_irq_save(flags);
  24.167 +    /* Remove from the thread list */
  24.168 +    list_del(&thread->thread_list);
  24.169 +    clear_runnable(thread);
  24.170 +    /* Put onto exited list */
  24.171 +    list_add(&thread->thread_list, &exited_threads);
  24.172 +    local_irq_restore(flags);
  24.173 +    /* Schedule will free the resources */
  24.174 +    schedule();
  24.175 +}
  24.176 +
  24.177 +
  24.178 +struct thread* create_thread(char *name, void (*function)(void *), void *data)
  24.179 +{
  24.180 +    struct thread *thread;
  24.181 +    unsigned long flags;
  24.182 +    
  24.183 +    thread = xmalloc(struct thread);
  24.184 +    /* Allocate 2 pages for stack, stack will be 2pages aligned */
  24.185 +    thread->stack = (char *)alloc_pages(1);
  24.186 +    thread->name = name;
  24.187 +    printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread, 
  24.188 +            thread->stack);
  24.189 +    
  24.190 +    thread->eps = (unsigned long)thread->stack + 4096 * 2 - 4;
  24.191 +    /* Save pointer to the thread on the stack, used by current macro */
  24.192 +    *((unsigned long *)thread->stack) = (unsigned long)thread;
  24.193 +    *((unsigned long *)thread->eps) = (unsigned long)thread;
  24.194 +    thread->eps -= 4; 
  24.195 +    *((unsigned long *)thread->eps) = (unsigned long)data;
  24.196 +    
  24.197 +    /* No return address */
  24.198 +    thread->eps -= 4;
  24.199 +    *((unsigned long *)thread->eps) = (unsigned long)exit_thread;
  24.200 +    
  24.201 +    thread->eip = (unsigned long)function;
  24.202 +     
  24.203 +    /* Not runable, not exited */ 
  24.204 +    thread->flags = 0;
  24.205 +    set_runnable(thread);
  24.206 +    
  24.207 +    local_irq_save(flags);
  24.208 +    if(idle_thread != NULL)
  24.209 +        list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
  24.210 +    local_irq_restore(flags);
  24.211 +
  24.212 +    return thread;
  24.213 +}
  24.214 +
  24.215 +
  24.216 +void block(struct thread *thread)
  24.217 +{
  24.218 +    clear_runnable(thread);
  24.219 +}
  24.220 +
  24.221 +void wake(struct thread *thread)
  24.222 +{
  24.223 +    set_runnable(thread);
  24.224 +}
  24.225 +
  24.226 +void idle_thread_fn(void *unused)
  24.227 +{
  24.228 +    for(;;)
  24.229 +    {
  24.230 +        schedule();
  24.231 +        printk("Blocking the domain\n"); 
  24.232 +        block_domain(10000);
  24.233 +    }
  24.234 +}
  24.235 +
  24.236 +void run_idle_thread(void)
  24.237 +{
  24.238 +    /* Switch stacks and run the thread */ 
  24.239 +    __asm__ __volatile__("mov %0,%%esp\n\t"
  24.240 +                         "push %1\n\t" 
  24.241 +                         "ret"                                            
  24.242 +                         :"=m" (idle_thread->eps)
  24.243 +                         :"m" (idle_thread->eip));                          
  24.244 +}
  24.245 +
  24.246 +
  24.247 +
  24.248 +DECLARE_MUTEX(mutex);
  24.249 +
  24.250 +void th_f1(void *data)
  24.251 +{
  24.252 +    struct timeval tv1, tv2;
  24.253 +
  24.254 +    for(;;)
  24.255 +    {
  24.256 +        down(&mutex);
  24.257 +        printk("Thread \"%s\" got semaphore, runnable %d\n", current->name, is_runnable(current));
  24.258 +        schedule();
  24.259 +        printk("Thread \"%s\" releases the semaphore\n", current->name);
  24.260 +        up(&mutex);
  24.261 +        
  24.262 +        
  24.263 +        gettimeofday(&tv1);
  24.264 +        for(;;)
  24.265 +        {
  24.266 +            gettimeofday(&tv2);
  24.267 +            if(tv2.tv_sec - tv1.tv_sec > 2) break;
  24.268 +        }
  24.269 +                
  24.270 +        
  24.271 +        schedule(); 
  24.272 +    }
  24.273 +}
  24.274 +
  24.275 +void th_f2(void *data)
  24.276 +{
  24.277 +    for(;;)
  24.278 +    {
  24.279 +        printk("Thread OTHER executing, data 0x%lx\n", data);
  24.280 +        schedule();
  24.281 +    }
  24.282 +}
  24.283 +
  24.284 +
  24.285 +
  24.286 +void init_sched(void)
  24.287 +{
  24.288 +    printk("Initialising scheduler\n");
  24.289 +       
  24.290 +    idle_thread = create_thread("Idle", idle_thread_fn, NULL);
  24.291 +    INIT_LIST_HEAD(&idle_thread->thread_list);
  24.292 +
  24.293 +    
  24.294 +/*    create_thread("1", th_f1, (void *)0x1234);    
  24.295 +    create_thread("2", th_f1, (void *)0x1234);    
  24.296 +    create_thread("3", th_f1, (void *)0x1234);    
  24.297 +    create_thread("4", th_f1, (void *)0x1234);    
  24.298 +    create_thread("5", th_f1, (void *)0x1234);    
  24.299 +    create_thread("6", th_f1, (void *)0x1234);    
  24.300 +    create_thread("second", th_f2, NULL);
  24.301 +*/   
  24.302 +}
  24.303 +
    25.1 --- a/extras/mini-os/time.c	Fri Sep 09 08:56:38 2005 +0000
    25.2 +++ b/extras/mini-os/time.c	Fri Sep 09 10:20:25 2005 +0000
    25.3 @@ -203,7 +203,7 @@ static void print_current_time(void)
    25.4  }
    25.5  
    25.6  
    25.7 -void block(u32 millisecs)
    25.8 +void block_domain(u32 millisecs)
    25.9  {
   25.10      struct timeval tv;
   25.11      gettimeofday(&tv);
   25.12 @@ -232,5 +232,6 @@ static void timer_handler(int ev, struct
   25.13  
   25.14  void init_time(void)
   25.15  {
   25.16 +    printk("Initialising timer interface\n");
   25.17      bind_virq(VIRQ_TIMER, &timer_handler);
   25.18  }
    26.1 --- a/extras/mini-os/traps.c	Fri Sep 09 08:56:38 2005 +0000
    26.2 +++ b/extras/mini-os/traps.c	Fri Sep 09 10:20:25 2005 +0000
    26.3 @@ -33,36 +33,7 @@ extern void do_exit(void);
    26.4  
    26.5  void dump_regs(struct pt_regs *regs)
    26.6  {
    26.7 -    unsigned long esp;
    26.8 -    unsigned short ss;
    26.9 -
   26.10 -#ifdef __x86_64__
   26.11 -    esp = regs->rsp;
   26.12 -    ss  = regs->xss;
   26.13 -#else
   26.14 -    esp = (unsigned long) (&regs->esp);
   26.15 -    ss = __KERNEL_DS;
   26.16 -    if (regs->xcs & 2) {
   26.17 -printk("CS is true, esp is %x\n", regs->esp);
   26.18 -        esp = regs->esp;
   26.19 -        ss = regs->xss & 0xffff;
   26.20 -    }
   26.21 -#endif
   26.22 -    printf("EIP:    %04x:[<%p>]\n",
   26.23 -           0xffff & regs->xcs , regs->eip);
   26.24 -    printf("EFLAGS: %p\n",regs->eflags);
   26.25 -    printf("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
   26.26 -           regs->eax, regs->ebx, regs->ecx, regs->edx);
   26.27 -    printf("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
   26.28 -           regs->esi, regs->edi, regs->ebp, esp);
   26.29 -#ifdef __x86_64__
   26.30 -    printf("r8 : %p   r9 : %p   r10: %p   r11: %p\n",
   26.31 -           regs->r8,  regs->r9,  regs->r10, regs->r11);
   26.32 -    printf("r12: %p   r13: %p   r14: %p   r15: %p\n",
   26.33 -           regs->r12, regs->r13, regs->r14, regs->r15);
   26.34 -#endif
   26.35 -    printf("ds: %04x   es: %04x   ss: %04x\n",
   26.36 -           regs->xds & 0xffff, regs->xes & 0xffff, ss);
   26.37 +    printk("FIXME: proper register dump (with the stack dump)\n");
   26.38  }	
   26.39  
   26.40  
   26.41 @@ -105,6 +76,7 @@ void do_page_fault(struct pt_regs *regs,
   26.42      printk("Page fault at linear address %p\n", addr);
   26.43      dump_regs(regs);
   26.44  #ifdef __x86_64__
   26.45 +    /* FIXME: _PAGE_PSE */
   26.46      {
   26.47          unsigned long *tab = (unsigned long *)start_info.pt_base;
   26.48          unsigned long page;
   26.49 @@ -112,23 +84,16 @@ void do_page_fault(struct pt_regs *regs,
   26.50          printk("Pagetable walk from %p:\n", tab);
   26.51          
   26.52          page = tab[l4_table_offset(addr)];
   26.53 -        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   26.54 +        tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   26.55          printk(" L4 = %p (%p)\n", page, tab);
   26.56 -        if ( !(page & AGERESENT) )
   26.57 -            goto out;
   26.58  
   26.59          page = tab[l3_table_offset(addr)];
   26.60 -        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   26.61 +        tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   26.62          printk("  L3 = %p (%p)\n", page, tab);
   26.63 -        if ( !(page & AGERESENT) )
   26.64 -            goto out;
   26.65          
   26.66          page = tab[l2_table_offset(addr)];
   26.67 -        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   26.68 -        printk("   L2 = %p (%p) %s\n", page, tab,
   26.69 -               (page & AGESE) ? "(2MB)" : "");
   26.70 -        if ( !(page & AGERESENT) || (page & AGESE) )
   26.71 -            goto out;
   26.72 +        tab =  to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   26.73 +        printk("   L2 = %p (%p)\n", page, tab);
   26.74          
   26.75          page = tab[l1_table_offset(addr)];
   26.76          printk("    L1 = %p\n", page);
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/extras/mini-os/xenbus/Makefile	Fri Sep 09 10:20:25 2005 +0000
    27.3 @@ -0,0 +1,9 @@
    27.4 +all: xenstore.h xenbus_comms.o xenbus_xs.o xenbus_probe.o
    27.5 +
    27.6 +xenstore.h:
    27.7 +	[ -e xenstored.h ] || ln -sf ../../../tools/xenstore/xenstored.h xenstored.h
    27.8 +
    27.9 +clean:
   27.10 +	#Taken care of by main Makefile
   27.11 +	#rm xenstored.h
   27.12 +	#rm *.o
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/extras/mini-os/xenbus/xenbus_comms.c	Fri Sep 09 10:20:25 2005 +0000
    28.3 @@ -0,0 +1,231 @@
    28.4 +/******************************************************************************
    28.5 + * xenbus_comms.c
    28.6 + *
    28.7 + * Low level code to talks to Xen Store: ringbuffer and event channel.
    28.8 + *
    28.9 + * Copyright (C) 2005 Rusty Russell, IBM Corporation
   28.10 + * 
   28.11 + * This file may be distributed separately from the Linux kernel, or
   28.12 + * incorporated into other software packages, subject to the following license:
   28.13 + * 
   28.14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   28.15 + * of this source file (the "Software"), to deal in the Software without
   28.16 + * restriction, including without limitation the rights to use, copy, modify,
   28.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   28.18 + * and to permit persons to whom the Software is furnished to do so, subject to
   28.19 + * the following conditions:
   28.20 + * 
   28.21 + * The above copyright notice and this permission notice shall be included in
   28.22 + * all copies or substantial portions of the Software.
   28.23 + * 
   28.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   28.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   28.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   28.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   28.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   28.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   28.30 + * IN THE SOFTWARE.
   28.31 + */
   28.32 +#include <types.h>
   28.33 +#include <wait.h>
   28.34 +#include <mm.h>
   28.35 +#include <hypervisor.h>
   28.36 +#include <events.h>
   28.37 +#include <os.h>
   28.38 +#include <lib.h>
   28.39 +
   28.40 +
   28.41 +#ifdef XENBUS_COMMS_DEBUG
   28.42 +#define DEBUG(_f, _a...) \
   28.43 +    printk("MINI_OS(file=xenbus_comms.c, line=%d) " _f "\n", __LINE__, ## _a)
   28.44 +#else
   28.45 +#define DEBUG(_f, _a...)    ((void)0)
   28.46 +#endif
   28.47 +
   28.48 +
   28.49 +#define RINGBUF_DATASIZE ((PAGE_SIZE / 2) - sizeof(struct ringbuf_head))
   28.50 +struct ringbuf_head
   28.51 +{
   28.52 +	u32 write; /* Next place to write to */
   28.53 +	u32 read; /* Next place to read from */
   28.54 +	u8 flags;
   28.55 +	char buf[0];
   28.56 +} __attribute__((packed));
   28.57 +
   28.58 +DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
   28.59 +
   28.60 +static inline struct ringbuf_head *outbuf(void)
   28.61 +{
   28.62 +	return mfn_to_virt(start_info.store_mfn);
   28.63 +}
   28.64 +
   28.65 +static inline struct ringbuf_head *inbuf(void)
   28.66 +{
   28.67 +	return (struct ringbuf_head *)((char *)mfn_to_virt(start_info.store_mfn) + PAGE_SIZE/2);
   28.68 +}
   28.69 +
   28.70 +static void wake_waiting(int port, struct pt_regs *regs)
   28.71 +{
   28.72 +	wake_up(&xb_waitq);
   28.73 +}
   28.74 +
   28.75 +static int check_buffer(const struct ringbuf_head *h)
   28.76 +{
   28.77 +	return (h->write < RINGBUF_DATASIZE && h->read < RINGBUF_DATASIZE);
   28.78 +}
   28.79 +
   28.80 +/* We can't fill last byte: would look like empty buffer. */
   28.81 +static void *get_output_chunk(const struct ringbuf_head *h,
   28.82 +			      void *buf, u32 *len)
   28.83 +{
   28.84 +	u32 read_mark;
   28.85 +
   28.86 +	if (h->read == 0)
   28.87 +		read_mark = RINGBUF_DATASIZE - 1;
   28.88 +	else
   28.89 +		read_mark = h->read - 1;
   28.90 +
   28.91 +	/* Here to the end of buffer, unless they haven't read some out. */
   28.92 +	*len = RINGBUF_DATASIZE - h->write;
   28.93 +	if (read_mark >= h->write)
   28.94 +		*len = read_mark - h->write;
   28.95 +	return (void *)((char *)buf + h->write);
   28.96 +}
   28.97 +
   28.98 +static const void *get_input_chunk(const struct ringbuf_head *h,
   28.99 +				   const void *buf, u32 *len)
  28.100 +{
  28.101 +	/* Here to the end of buffer, unless they haven't written some. */
  28.102 +	*len = RINGBUF_DATASIZE - h->read;
  28.103 +	if (h->write >= h->read)
  28.104 +		*len = h->write - h->read;
  28.105 +	return (void *)((char *)buf + h->read);
  28.106 +}
  28.107 +
  28.108 +static void update_output_chunk(struct ringbuf_head *h, u32 len)
  28.109 +{
  28.110 +	h->write += len;
  28.111 +	if (h->write == RINGBUF_DATASIZE)
  28.112 +		h->write = 0;
  28.113 +}
  28.114 +
  28.115 +static void update_input_chunk(struct ringbuf_head *h, u32 len)
  28.116 +{
  28.117 +	h->read += len;
  28.118 +	if (h->read == RINGBUF_DATASIZE)
  28.119 +		h->read = 0;
  28.120 +}
  28.121 +
  28.122 +static int output_avail(struct ringbuf_head *out)
  28.123 +{
  28.124 +	unsigned int avail;
  28.125 +
  28.126 +	get_output_chunk(out, out->buf, &avail);
  28.127 +	return avail != 0;
  28.128 +}
  28.129 +
  28.130 +int xb_write(const void *data, unsigned len)
  28.131 +{
  28.132 +	struct ringbuf_head h;
  28.133 +	struct ringbuf_head *out = outbuf();
  28.134 +
  28.135 +	do {
  28.136 +		void *dst;
  28.137 +		unsigned int avail;
  28.138 +
  28.139 +		wait_event(xb_waitq, output_avail(out));
  28.140 +
  28.141 +		/* Read, then check: not that we don't trust store.
  28.142 +		 * Hell, some of my best friends are daemons.  But,
  28.143 +		 * in this post-911 world... */
  28.144 +		h = *out;
  28.145 +		mb();
  28.146 +		if (!check_buffer(&h)) {
  28.147 +			return -1; /* ETERRORIST! */
  28.148 +		}
  28.149 +
  28.150 +		dst = get_output_chunk(&h, out->buf, &avail);
  28.151 +		if (avail > len)
  28.152 +			avail = len;
  28.153 +		memcpy(dst, data, avail);
  28.154 +		data = (void *)((char *)data + avail);
  28.155 +		len -= avail;
  28.156 +		update_output_chunk(out, avail);
  28.157 +		notify_via_evtchn(start_info.store_evtchn);
  28.158 +	} while (len != 0);
  28.159 +
  28.160 +	return 0;
  28.161 +}
  28.162 +
  28.163 +int xs_input_avail(void)
  28.164 +{
  28.165 +	unsigned int avail;
  28.166 +	struct ringbuf_head *in = inbuf();
  28.167 +
  28.168 +	get_input_chunk(in, in->buf, &avail);
  28.169 +	return avail != 0;
  28.170 +}
  28.171 +
  28.172 +int xb_read(void *data, unsigned len)
  28.173 +{
  28.174 +	struct ringbuf_head h;
  28.175 +	struct ringbuf_head *in = inbuf();
  28.176 +	int was_full;
  28.177 +
  28.178 +	while (len != 0) {
  28.179 +		unsigned int avail;
  28.180 +		const char *src;
  28.181 +
  28.182 +		wait_event(xb_waitq, xs_input_avail());
  28.183 +		h = *in;
  28.184 +		mb();
  28.185 +		if (!check_buffer(&h)) {
  28.186 +			return -1;
  28.187 +		}
  28.188 +
  28.189 +		src = get_input_chunk(&h, in->buf, &avail);
  28.190 +		if (avail > len)
  28.191 +			avail = len;
  28.192 +		was_full = !output_avail(&h);
  28.193 +
  28.194 +		memcpy(data, src, avail);
  28.195 +		data = (void *)((char *)data + avail);
  28.196 +		len -= avail;
  28.197 +		update_input_chunk(in, avail);
  28.198 +		DEBUG("Finished read of %i bytes (%i to go)\n", avail, len);
  28.199 +		/* If it was full, tell them we've taken some. */
  28.200 +		if (was_full)
  28.201 +			notify_via_evtchn(start_info.store_evtchn);
  28.202 +	}
  28.203 +
  28.204 +	/* If we left something, wake watch thread to deal with it. */
  28.205 +	if (xs_input_avail())
  28.206 +		wake_up(&xb_waitq);
  28.207 +
  28.208 +	return 0;
  28.209 +}
  28.210 +
  28.211 +/* Set up interrupt handler off store event channel. */
  28.212 +int xb_init_comms(void)
  28.213 +{
  28.214 +    printk("Init xenbus comms, store event channel %d\n", start_info.store_evtchn);
  28.215 +	if (!start_info.store_evtchn)
  28.216 +		return 0;
  28.217 +    printk("Binding virq\n");
  28.218 +	bind_evtchn(start_info.store_evtchn, &wake_waiting);
  28.219 +
  28.220 +	/* FIXME zero out page -- domain builder should probably do this*/
  28.221 +	memset(mfn_to_virt(start_info.store_mfn), 0, PAGE_SIZE);
  28.222 +    notify_via_evtchn(start_info.store_evtchn);
  28.223 +	return 0;
  28.224 +}
  28.225 +
  28.226 +void xb_suspend_comms(void)
  28.227 +{
  28.228 +
  28.229 +	if (!start_info.store_evtchn)
  28.230 +		return;
  28.231 +
  28.232 +    // TODO
  28.233 +	//unbind_evtchn_from_irqhandler(xen_start_info.store_evtchn, &xb_waitq);
  28.234 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/extras/mini-os/xenbus/xenbus_comms.h	Fri Sep 09 10:20:25 2005 +0000
    29.3 @@ -0,0 +1,40 @@
    29.4 +/*
    29.5 + * Private include for xenbus communications.
    29.6 + * 
    29.7 + * Copyright (C) 2005 Rusty Russell, IBM Corporation
    29.8 + *
    29.9 + * This file may be distributed separately from the Linux kernel, or
   29.10 + * incorporated into other software packages, subject to the following license:
   29.11 + * 
   29.12 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   29.13 + * of this source file (the "Software"), to deal in the Software without
   29.14 + * restriction, including without limitation the rights to use, copy, modify,
   29.15 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   29.16 + * and to permit persons to whom the Software is furnished to do so, subject to
   29.17 + * the following conditions:
   29.18 + * 
   29.19 + * The above copyright notice and this permission notice shall be included in
   29.20 + * all copies or substantial portions of the Software.
   29.21 + * 
   29.22 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   29.23 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   29.24 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   29.25 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   29.26 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   29.27 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   29.28 + * IN THE SOFTWARE.
   29.29 + */
   29.30 +
   29.31 +#ifndef _XENBUS_COMMS_H
   29.32 +#define _XENBUS_COMMS_H
   29.33 +
   29.34 +int xb_init_comms(void);
   29.35 +void xb_suspend_comms(void);
   29.36 +
   29.37 +/* Low level routines. */
   29.38 +int xb_write(const void *data, unsigned len);
   29.39 +int xb_read(void *data, unsigned len);
   29.40 +int xs_input_avail(void);
   29.41 +extern struct wait_queue_head xb_waitq;
   29.42 +
   29.43 +#endif /* _XENBUS_COMMS_H */
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/extras/mini-os/xenbus/xenbus_xs.c	Fri Sep 09 10:20:25 2005 +0000
    30.3 @@ -0,0 +1,554 @@
    30.4 +/******************************************************************************
    30.5 + * xenbus_xs.c
    30.6 + *
    30.7 + * This is the kernel equivalent of the "xs" library.  We don't need everything
    30.8 + * and we use xenbus_comms for communication.
    30.9 + *
   30.10 + * Copyright (C) 2005 Rusty Russell, IBM Corporation
   30.11 + * 
   30.12 + * This file may be distributed separately from the Linux kernel, or
   30.13 + * incorporated into other software packages, subject to the following license:
   30.14 + * 
   30.15 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   30.16 + * of this source file (the "Software"), to deal in the Software without
   30.17 + * restriction, including without limitation the rights to use, copy, modify,
   30.18 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
   30.19 + * and to permit persons to whom the Software is furnished to do so, subject to
   30.20 + * the following conditions:
   30.21 + * 
   30.22 + * The above copyright notice and this permission notice shall be included in
   30.23 + * all copies or substantial portions of the Software.
   30.24 + * 
   30.25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   30.26 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   30.27 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   30.28 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   30.29 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   30.30 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   30.31 + * IN THE SOFTWARE.
   30.32 + */
   30.33 +#include <errno.h>
   30.34 +#include <types.h>
   30.35 +#include <list.h>
   30.36 +#include <lib.h>
   30.37 +#include <err.h>
   30.38 +#include <os.h>
   30.39 +#include <xmalloc.h>
   30.40 +#include <fcntl.h>
   30.41 +#include <xenbus.h>
   30.42 +#include <wait.h>
   30.43 +#include <sched.h>
   30.44 +#include <semaphore.h>
   30.45 +#include "xenstored.h"
   30.46 +#include "xenbus_comms.h"
   30.47 +
   30.48 +#define streq(a, b) (strcmp((a), (b)) == 0)
   30.49 +
   30.50 +static char printf_buffer[4096];
   30.51 +static LIST_HEAD(watches);
   30.52 +//TODO
   30.53 +DECLARE_MUTEX(xenbus_lock);
   30.54 +
   30.55 +static int get_error(const char *errorstring)
   30.56 +{
   30.57 +	unsigned int i;
   30.58 +
   30.59 +	for (i = 0; !streq(errorstring, xsd_errors[i].errstring); i++) {
   30.60 +		if (i == ARRAY_SIZE(xsd_errors) - 1) {
   30.61 +			printk("XENBUS xen store gave: unknown error %s",
   30.62 +			       errorstring);
   30.63 +			return EINVAL;
   30.64 +		}
   30.65 +	}
   30.66 +	return xsd_errors[i].errnum;
   30.67 +}
   30.68 +
   30.69 +static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
   30.70 +{
   30.71 +	struct xsd_sockmsg msg;
   30.72 +	void *ret;
   30.73 +	int err;
   30.74 +
   30.75 +	err = xb_read(&msg, sizeof(msg));
   30.76 +	if (err)
   30.77 +		return ERR_PTR(err);
   30.78 +
   30.79 +	ret = xmalloc_array(char, msg.len + 1);
   30.80 +	if (!ret)
   30.81 +		return ERR_PTR(-ENOMEM);
   30.82 +
   30.83 +	err = xb_read(ret, msg.len);
   30.84 +	if (err) {
   30.85 +		xfree(ret);
   30.86 +		return ERR_PTR(err);
   30.87 +	}
   30.88 +	((char*)ret)[msg.len] = '\0';
   30.89 +
   30.90 +	*type = msg.type;
   30.91 +	if (len)
   30.92 +		*len = msg.len;
   30.93 +	return ret;
   30.94 +}
   30.95 +
   30.96 +/* Emergency write. */
   30.97 +void xenbus_debug_write(const char *str, unsigned int count)
   30.98 +{
   30.99 +	struct xsd_sockmsg msg;
  30.100 +
  30.101 +	msg.type = XS_DEBUG;
  30.102 +	msg.len = sizeof("print") + count + 1;
  30.103 +
  30.104 +	xb_write(&msg, sizeof(msg));
  30.105 +	xb_write("print", sizeof("print"));
  30.106 +	xb_write(str, count);
  30.107 +	xb_write("", 1);
  30.108 +}
  30.109 +
  30.110 +/* Send message to xs, get kmalloc'ed reply.  ERR_PTR() on error. */
  30.111 +static void *xs_talkv(enum xsd_sockmsg_type type,
  30.112 +		      const struct kvec *iovec,
  30.113 +		      unsigned int num_vecs,
  30.114 +		      unsigned int *len)
  30.115 +{
  30.116 +	struct xsd_sockmsg msg;
  30.117 +	void *ret = NULL;
  30.118 +	unsigned int i;
  30.119 +	int err;
  30.120 +
  30.121 +	//WARN_ON(down_trylock(&xenbus_lock) == 0);
  30.122 +
  30.123 +	msg.type = type;
  30.124 +	msg.len = 0;
  30.125 +	for (i = 0; i < num_vecs; i++)
  30.126 +		msg.len += iovec[i].iov_len;
  30.127 +
  30.128 +	err = xb_write(&msg, sizeof(msg));
  30.129 +	if (err)
  30.130 +		return ERR_PTR(err);
  30.131 +
  30.132 +	for (i = 0; i < num_vecs; i++) {
  30.133 +		err = xb_write(iovec[i].iov_base, iovec[i].iov_len);;
  30.134 +		if (err)
  30.135 +			return ERR_PTR(err);
  30.136 +	}
  30.137 +
  30.138 +	/* Watches can have fired before reply comes: daemon detects
  30.139 +	 * and re-transmits, so we can ignore this. */
  30.140 +	do {
  30.141 +		xfree(ret);
  30.142 +		ret = read_reply(&msg.type, len);
  30.143 +		if (IS_ERR(ret))
  30.144 +			return ret;
  30.145 +	} while (msg.type == XS_WATCH_EVENT);
  30.146 +
  30.147 +	if (msg.type == XS_ERROR) {
  30.148 +		err = get_error(ret);
  30.149 +		xfree(ret);
  30.150 +		return ERR_PTR(-err);
  30.151 +	}
  30.152 +
  30.153 +	//BUG_ON(msg.type != type);
  30.154 +	return ret;
  30.155 +}
  30.156 +
  30.157 +/* Simplified version of xs_talkv: single message. */
  30.158 +static void *xs_single(enum xsd_sockmsg_type type,
  30.159 +		       const char *string, unsigned int *len)
  30.160 +{
  30.161 +	struct kvec iovec;
  30.162 +
  30.163 +	iovec.iov_base = (void *)string;
  30.164 +	iovec.iov_len = strlen(string) + 1;
  30.165 +	return xs_talkv(type, &iovec, 1, len);
  30.166 +}
  30.167 +
  30.168 +/* Many commands only need an ack, don't care what it says. */
  30.169 +static int xs_error(char *reply)
  30.170 +{
  30.171 +	if (IS_ERR(reply))
  30.172 +		return PTR_ERR(reply);
  30.173 +	xfree(reply);
  30.174 +	return 0;
  30.175 +}
  30.176 +
  30.177 +static unsigned int count_strings(const char *strings, unsigned int len)
  30.178 +{
  30.179 +	unsigned int num;
  30.180 +	const char *p;
  30.181 +
  30.182 +	for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1)
  30.183 +		num++;
  30.184 +
  30.185 +	return num;
  30.186 +}
  30.187 +
  30.188 +/* Return the path to dir with /name appended. */ 
  30.189 +static char *join(const char *dir, const char *name)
  30.190 +{
  30.191 +	static char buffer[4096];
  30.192 +
  30.193 +	//BUG_ON(down_trylock(&xenbus_lock) == 0);
  30.194 +	/* XXX FIXME: might not be correct if name == "" */
  30.195 +	//BUG_ON(strlen(dir) + strlen("/") + strlen(name) + 1 > sizeof(buffer));
  30.196 +
  30.197 +	strcpy(buffer, dir);
  30.198 +	if (!streq(name, "")) {
  30.199 +		strcat(buffer, "/");
  30.200 +		strcat(buffer, name);
  30.201 +	}
  30.202 +	return buffer;
  30.203 +}
  30.204 +
  30.205 +char **xenbus_directory(const char *dir, const char *node, unsigned int *num)
  30.206 +{
  30.207 +	char *strings, *p, **ret;
  30.208 +	unsigned int len;
  30.209 +
  30.210 +	strings = xs_single(XS_DIRECTORY, join(dir, node), &len);
  30.211 +	if (IS_ERR(strings))
  30.212 +		return (char **)strings;
  30.213 +
  30.214 +	/* Count the strings. */
  30.215 +	*num = count_strings(strings, len);
  30.216 +
  30.217 +	/* Transfer to one big alloc for easy freeing. */
  30.218 +	ret = (char **)xmalloc_array(char, *num * sizeof(char *) + len);
  30.219 +	if (!ret) {
  30.220 +		xfree(strings);
  30.221 +		return ERR_PTR(-ENOMEM);
  30.222 +	}
  30.223 +	memcpy(&ret[*num], strings, len);
  30.224 +	xfree(strings);
  30.225 +
  30.226 +	strings = (char *)&ret[*num];
  30.227 +	for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1)
  30.228 +		ret[(*num)++] = p;
  30.229 +	return ret;
  30.230 +}
  30.231 +
  30.232 +/* Check if a path exists. Return 1 if it does. */
  30.233 +int xenbus_exists(const char *dir, const char *node)
  30.234 +{
  30.235 +	char **d;
  30.236 +	int dir_n;
  30.237 +
  30.238 +	d = xenbus_directory(dir, node, &dir_n);
  30.239 +	if (IS_ERR(d))
  30.240 +		return 0;
  30.241 +	xfree(d);
  30.242 +	return 1;
  30.243 +}
  30.244 +
  30.245 +/* Get the value of a single file.
  30.246 + * Returns a kmalloced value: call free() on it after use.
  30.247 + * len indicates length in bytes.
  30.248 + */
  30.249 +void *xenbus_read(const char *dir, const char *node, unsigned int *len)
  30.250 +{
  30.251 +	return xs_single(XS_READ, join(dir, node), len);
  30.252 +}
  30.253 +
  30.254 +/* Write the value of a single file.
  30.255 + * Returns -err on failure.  createflags can be 0, O_CREAT, or O_CREAT|O_EXCL.
  30.256 + */
  30.257 +int xenbus_write(const char *dir, const char *node,
  30.258 +		 const char *string, int createflags)
  30.259 +{
  30.260 +	const char *flags, *path;
  30.261 +	struct kvec iovec[3];
  30.262 +
  30.263 +	path = join(dir, node);
  30.264 +	/* Format: Flags (as string), path, data. */
  30.265 +	if (createflags == 0)
  30.266 +		flags = XS_WRITE_NONE;
  30.267 +	else if (createflags == O_CREAT)
  30.268 +		flags = XS_WRITE_CREATE;
  30.269 +	else if (createflags == (O_CREAT|O_EXCL))
  30.270 +		flags = XS_WRITE_CREATE_EXCL;
  30.271 +	else
  30.272 +		return -EINVAL;
  30.273 +
  30.274 +	iovec[0].iov_base = (void *)path;
  30.275 +	iovec[0].iov_len = strlen(path) + 1;
  30.276 +	iovec[1].iov_base = (void *)flags;
  30.277 +	iovec[1].iov_len = strlen(flags) + 1;
  30.278 +	iovec[2].iov_base = (void *)string;
  30.279 +	iovec[2].iov_len = strlen(string);
  30.280 +
  30.281 +	return xs_error(xs_talkv(XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL));
  30.282 +}
  30.283 +
  30.284 +/* Create a new directory. */
  30.285 +int xenbus_mkdir(const char *dir, const char *node)
  30.286 +{
  30.287 +	return xs_error(xs_single(XS_MKDIR, join(dir, node), NULL));
  30.288 +}
  30.289 +
  30.290 +/* Destroy a file or directory (directories must be empty). */
  30.291 +int xenbus_rm(const char *dir, const char *node)
  30.292 +{
  30.293 +	return xs_error(xs_single(XS_RM, join(dir, node), NULL));
  30.294 +}
  30.295 +
  30.296 +/* Start a transaction: changes by others will not be seen during this
  30.297 + * transaction, and changes will not be visible to others until end.
  30.298 + * Transaction only applies to the given subtree.
  30.299 + * You can only have one transaction at any time.
  30.300 + */
  30.301 +int xenbus_transaction_start(const char *subtree)
  30.302 +{
  30.303 +	return xs_error(xs_single(XS_TRANSACTION_START, subtree, NULL));
  30.304 +}
  30.305 +
  30.306 +/* End a transaction.
  30.307 + * If abandon is true, transaction is discarded instead of committed.
  30.308 + */
  30.309 +int xenbus_transaction_end(int abort)
  30.310 +{
  30.311 +	char abortstr[2];
  30.312 +
  30.313 +	if (abort)
  30.314 +		strcpy(abortstr, "F");
  30.315 +	else
  30.316 +		strcpy(abortstr, "T");
  30.317 +	return xs_error(xs_single(XS_TRANSACTION_END, abortstr, NULL));
  30.318 +}
  30.319 +
  30.320 +/* Single read and scanf: returns -errno or num scanned. */
  30.321 +int xenbus_scanf(const char *dir, const char *node, const char *fmt, ...)
  30.322 +{
  30.323 +	va_list ap;
  30.324 +	int ret;
  30.325 +	char *val;
  30.326 +
  30.327 +	val = xenbus_read(dir, node, NULL);
  30.328 +	if (IS_ERR(val))
  30.329 +		return PTR_ERR(val);
  30.330 +
  30.331 +	va_start(ap, fmt);
  30.332 +	ret = vsscanf(val, fmt, ap);
  30.333 +	va_end(ap);
  30.334 +	xfree(val);
  30.335 +	/* Distinctive errno. */
  30.336 +	if (ret == 0)
  30.337 +		return -ERANGE;
  30.338 +	return ret;
  30.339 +}
  30.340 +
  30.341 +/* Single printf and write: returns -errno or 0. */
  30.342 +int xenbus_printf(const char *dir, const char *node, const char *fmt, ...)
  30.343 +{
  30.344 +	va_list ap;
  30.345 +	int ret;
  30.346 +
  30.347 +	//BUG_ON(down_trylock(&xenbus_lock) == 0);
  30.348 +	va_start(ap, fmt);
  30.349 +	ret = vsnprintf(printf_buffer, sizeof(printf_buffer), fmt, ap);
  30.350 +	va_end(ap);
  30.351 +
  30.352 +	//BUG_ON(ret > sizeof(printf_buffer)-1);
  30.353 +	return xenbus_write(dir, node, printf_buffer, O_CREAT);
  30.354 +}
  30.355 +
  30.356 +	
  30.357 +/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
  30.358 +int xenbus_gather(const char *dir, ...)
  30.359 +{
  30.360 +	va_list ap;
  30.361 +	const char *name;
  30.362 +	int ret = 0;
  30.363 +
  30.364 +	va_start(ap, dir);
  30.365 +	while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
  30.366 +		const char *fmt = va_arg(ap, char *);
  30.367 +		void *result = va_arg(ap, void *);
  30.368 +		char *p;
  30.369 +
  30.370 +		p = xenbus_read(dir, name, NULL);
  30.371 +		if (IS_ERR(p)) {
  30.372 +			ret = PTR_ERR(p);
  30.373 +			break;
  30.374 +		}
  30.375 +		if (fmt) {
  30.376 +			if (sscanf(p, fmt, result) == 0)
  30.377 +				ret = -EINVAL;
  30.378 +			xfree(p);
  30.379 +		} else
  30.380 +			*(char **)result = p;
  30.381 +	}
  30.382 +	va_end(ap);
  30.383 +	return ret;
  30.384 +}
  30.385 +
  30.386 +static int xs_watch(const char *path, const char *token)
  30.387 +{
  30.388 +	struct kvec iov[2];
  30.389 +
  30.390 +	iov[0].iov_base = (void *)path;
  30.391 +	iov[0].iov_len = strlen(path) + 1;
  30.392 +	iov[1].iov_base = (void *)token;
  30.393 +	iov[1].iov_len = strlen(token) + 1;
  30.394 +
  30.395 +	return xs_error(xs_talkv(XS_WATCH, iov, ARRAY_SIZE(iov), NULL));
  30.396 +}
  30.397 +
  30.398 +static char *xs_read_watch(char **token)
  30.399 +{
  30.400 +	enum xsd_sockmsg_type type;
  30.401 +	char *ret;
  30.402 +
  30.403 +	ret = read_reply(&type, NULL);
  30.404 +	if (IS_ERR(ret))
  30.405 +		return ret;
  30.406 +
  30.407 +	//BUG_ON(type != XS_WATCH_EVENT);
  30.408 +	*token = ret + strlen(ret) + 1;
  30.409 +	return ret;
  30.410 +}
  30.411 +
  30.412 +static int xs_acknowledge_watch(const char *token)
  30.413 +{
  30.414 +	return xs_error(xs_single(XS_WATCH_ACK, token, NULL));
  30.415 +}
  30.416 +
  30.417 +static int xs_unwatch(const char *path, const char *token)
  30.418 +{
  30.419 +	struct kvec iov[2];
  30.420 +
  30.421 +	iov[0].iov_base = (char *)path;
  30.422 +	iov[0].iov_len = strlen(path) + 1;
  30.423 +	iov[1].iov_base = (char *)token;
  30.424 +	iov[1].iov_len = strlen(token) + 1;
  30.425 +
  30.426 +	return xs_error(xs_talkv(XS_UNWATCH, iov, ARRAY_SIZE(iov), NULL));
  30.427 +}
  30.428 +
  30.429 +/* A little paranoia: we don't just trust token. */
  30.430 +static struct xenbus_watch *find_watch(const char *token)
  30.431 +{
  30.432 +	struct xenbus_watch *i, *cmp;
  30.433 +
  30.434 +	cmp = (void *)simple_strtoul(token, NULL, 16);
  30.435 +
  30.436 +	list_for_each_entry(i, &watches, list)
  30.437 +		if (i == cmp)
  30.438 +			return i;
  30.439 +	return NULL;
  30.440 +}
  30.441 +
  30.442 +/* Register callback to watch this node. */
  30.443 +int register_xenbus_watch(struct xenbus_watch *watch)
  30.444 +{
  30.445 +	/* Pointer in ascii is the token. */
  30.446 +	char token[sizeof(watch) * 2 + 1];
  30.447 +	int err;
  30.448 +
  30.449 +	sprintf(token, "%lX", (long)watch);
  30.450 +	//BUG_ON(find_watch(token));
  30.451 +printk("Registered watch for: %s\n", token);
  30.452 +	err = xs_watch(watch->node, token);
  30.453 +	if (!err)
  30.454 +		list_add(&watch->list, &watches);
  30.455 +	return err;
  30.456 +}
  30.457 +
  30.458 +void unregister_xenbus_watch(struct xenbus_watch *watch)
  30.459 +{
  30.460 +	char token[sizeof(watch) * 2 + 1];
  30.461 +	int err;
  30.462 +
  30.463 +	sprintf(token, "%lX", (long)watch);
  30.464 +	//BUG_ON(!find_watch(token));
  30.465 +
  30.466 +	err = xs_unwatch(watch->node, token);
  30.467 +	list_del(&watch->list);
  30.468 +
  30.469 +	if (err)
  30.470 +		printk("XENBUS Failed to release watch %s: %i\n",
  30.471 +		       watch->node, err);
  30.472 +}
  30.473 +
  30.474 +/* Re-register callbacks to all watches. */
  30.475 +void reregister_xenbus_watches(void)
  30.476 +{
  30.477 +	struct xenbus_watch *watch;
  30.478 +	char token[sizeof(watch) * 2 + 1];
  30.479 +
  30.480 +	list_for_each_entry(watch, &watches, list) {
  30.481 +		sprintf(token, "%lX", (long)watch);
  30.482 +		xs_watch(watch->node, token);
  30.483 +	}
  30.484 +}
  30.485 +
  30.486 +void watch_thread(void *unused)
  30.487 +{
  30.488 +	for (;;) {
  30.489 +		char *token;
  30.490 +		char *node = NULL;
  30.491 +
  30.492 +		wait_event(xb_waitq, xs_input_avail());
  30.493 +
  30.494 +		/* If this is a spurious wakeup caused by someone
  30.495 +		 * doing an op, they'll hold the lock and the buffer
  30.496 +		 * will be empty by the time we get there.		 
  30.497 +		 */
  30.498 +		down(&xenbus_lock);
  30.499 +		if (xs_input_avail())
  30.500 +			node = xs_read_watch(&token);
  30.501 +
  30.502 +		if (node && !IS_ERR(node)) {
  30.503 +			struct xenbus_watch *w;
  30.504 +			int err;
  30.505 +
  30.506 +			err = xs_acknowledge_watch(token);
  30.507 +			if (err)
  30.508 +				printk("XENBUS ack %s fail %i\n", node, err);
  30.509 +			w = find_watch(token);
  30.510 +			//BUG_ON(!w);
  30.511 +			w->callback(w, node);
  30.512 +			xfree(node);
  30.513 +		} else
  30.514 +			printk("XENBUS xs_read_watch: %li\n", PTR_ERR(node));
  30.515 +		up(&xenbus_lock);
  30.516 +	}
  30.517 +}
  30.518 +
  30.519 +
  30.520 +static void ballon_changed(struct xenbus_watch *watch, const char *node)
  30.521 +{
  30.522 +    unsigned long new_target;
  30.523 +    int err;
  30.524 +    err = xenbus_scanf("memory", "target", "%lu", &new_target);
  30.525 +
  30.526 +    if(err != 1)
  30.527 +    {
  30.528 +        printk("Unable to read memory/target\n");
  30.529 +        return;
  30.530 +    }
  30.531 +
  30.532 +    printk("Memory target changed to: %ld bytes, ignoring.\n", new_target);
  30.533 +}
  30.534 +
  30.535 +
  30.536 +static struct xenbus_watch ballon_watch = {
  30.537 +    .node = "memory/target",
  30.538 +    .callback = ballon_changed,
  30.539 +};
  30.540 +
  30.541 +
  30.542 +
  30.543 +int xs_init(void)
  30.544 +{
  30.545 +	int err;
  30.546 +	struct thread *watcher;
  30.547 +    printk("xb_init_comms\n");
  30.548 +	err = xb_init_comms();
  30.549 +	if (err)
  30.550 +		return err;
  30.551 +	
  30.552 +	watcher = create_thread("kxwatch", watch_thread, NULL);
  30.553 +    down(&xenbus_lock);
  30.554 +    register_xenbus_watch(&ballon_watch);
  30.555 +    up(&xenbus_lock);
  30.556 +	return 0;
  30.557 +}
    31.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Sep 09 08:56:38 2005 +0000
    31.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Sep 09 10:20:25 2005 +0000
    31.3 @@ -776,8 +776,8 @@ static void blkif_completion(struct blk_
    31.4  {
    31.5  	int i;
    31.6  	for (i = 0; i < s->req.nr_segments; i++)
    31.7 -		gnttab_free_grant_reference(
    31.8 -			blkif_gref_from_fas(s->req.frame_and_sects[i]));
    31.9 +		gnttab_end_foreign_access(
   31.10 +			blkif_gref_from_fas(s->req.frame_and_sects[i]), 0);
   31.11  }
   31.12  
   31.13  /*
    32.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Fri Sep 09 08:56:38 2005 +0000
    32.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c	Fri Sep 09 10:20:25 2005 +0000
    32.3 @@ -29,136 +29,163 @@
    32.4  #include <linux/skbuff.h>
    32.5  #include <net/dst.h>
    32.6  
    32.7 +static int nloopbacks = 1;
    32.8 +module_param(nloopbacks, int, 0);
    32.9 +MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create");
   32.10 +
   32.11  struct net_private {
   32.12 -    struct net_device *loopback_dev;
   32.13 -    struct net_device_stats stats;
   32.14 +	struct net_device *loopback_dev;
   32.15 +	struct net_device_stats stats;
   32.16  };
   32.17  
   32.18  static int loopback_open(struct net_device *dev)
   32.19  {
   32.20 -    struct net_private *np = netdev_priv(dev);
   32.21 -    memset(&np->stats, 0, sizeof(np->stats));
   32.22 -    netif_start_queue(dev);
   32.23 -    return 0;
   32.24 +	struct net_private *np = netdev_priv(dev);
   32.25 +	memset(&np->stats, 0, sizeof(np->stats));
   32.26 +	netif_start_queue(dev);
   32.27 +	return 0;
   32.28  }
   32.29  
   32.30  static int loopback_close(struct net_device *dev)
   32.31  {
   32.32 -    netif_stop_queue(dev);
   32.33 -    return 0;
   32.34 +	netif_stop_queue(dev);
   32.35 +	return 0;
   32.36  }
   32.37  
   32.38  static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
   32.39  {
   32.40 -    struct net_private *np = netdev_priv(dev);
   32.41 -
   32.42 -    dst_release(skb->dst);
   32.43 -    skb->dst = NULL;
   32.44 -
   32.45 -    skb_orphan(skb);
   32.46 -
   32.47 -    np->stats.tx_bytes += skb->len;
   32.48 -    np->stats.tx_packets++;
   32.49 -
   32.50 -    /* Switch to loopback context. */
   32.51 -    dev = np->loopback_dev;
   32.52 -    np  = netdev_priv(dev);
   32.53 -
   32.54 -    np->stats.rx_bytes += skb->len;
   32.55 -    np->stats.rx_packets++;
   32.56 +	struct net_private *np = netdev_priv(dev);
   32.57  
   32.58 -    if ( skb->ip_summed == CHECKSUM_HW )
   32.59 -    {
   32.60 -        /* Defer checksum calculation. */
   32.61 -        skb->proto_csum_blank = 1;
   32.62 -        /* Must be a local packet: assert its integrity. */
   32.63 -        skb->proto_csum_valid = 1;
   32.64 -    }
   32.65 +	dst_release(skb->dst);
   32.66 +	skb->dst = NULL;
   32.67  
   32.68 -    skb->ip_summed = skb->proto_csum_valid ?
   32.69 -        CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
   32.70 +	skb_orphan(skb);
   32.71  
   32.72 -    skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
   32.73 -    skb->protocol = eth_type_trans(skb, dev);
   32.74 -    skb->dev      = dev;
   32.75 -    dev->last_rx  = jiffies;
   32.76 -    netif_rx(skb);
   32.77 +	np->stats.tx_bytes += skb->len;
   32.78 +	np->stats.tx_packets++;
   32.79  
   32.80 -    return 0;
   32.81 +	/* Switch to loopback context. */
   32.82 +	dev = np->loopback_dev;
   32.83 +	np  = netdev_priv(dev);
   32.84 +
   32.85 +	np->stats.rx_bytes += skb->len;
   32.86 +	np->stats.rx_packets++;
   32.87 +
   32.88 +	if (skb->ip_summed == CHECKSUM_HW) {
   32.89 +		/* Defer checksum calculation. */
   32.90 +		skb->proto_csum_blank = 1;
   32.91 +		/* Must be a local packet: assert its integrity. */
   32.92 +		skb->proto_csum_valid = 1;
   32.93 +	}
   32.94 +
   32.95 +	skb->ip_summed = skb->proto_csum_valid ?
   32.96 +		CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
   32.97 +
   32.98 +	skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
   32.99 +	skb->protocol = eth_type_trans(skb, dev);
  32.100 +	skb->dev      = dev;
  32.101 +	dev->last_rx  = jiffies;
  32.102 +	netif_rx(skb);
  32.103 +
  32.104 +	return 0;
  32.105  }
  32.106  
  32.107  static struct net_device_stats *loopback_get_stats(struct net_device *dev)
  32.108  {
  32.109 -    struct net_private *np = netdev_priv(dev);
  32.110 -    return &np->stats;
  32.111 +	struct net_private *np = netdev_priv(dev);
  32.112 +	return &np->stats;
  32.113  }
  32.114  
  32.115  static void loopback_construct(struct net_device *dev, struct net_device *lo)
  32.116  {
  32.117 -    struct net_private *np = netdev_priv(dev);
  32.118 -
  32.119 -    np->loopback_dev     = lo;
  32.120 -
  32.121 -    dev->open            = loopback_open;
  32.122 -    dev->stop            = loopback_close;
  32.123 -    dev->hard_start_xmit = loopback_start_xmit;
  32.124 -    dev->get_stats       = loopback_get_stats;
  32.125 +	struct net_private *np = netdev_priv(dev);
  32.126  
  32.127 -    dev->tx_queue_len    = 0;
  32.128 -
  32.129 -    dev->features        = NETIF_F_HIGHDMA | NETIF_F_LLTX;
  32.130 +	np->loopback_dev     = lo;
  32.131  
  32.132 -    /*
  32.133 -     * We do not set a jumbo MTU on the interface. Otherwise the network
  32.134 -     * stack will try to send large packets that will get dropped by the
  32.135 -     * Ethernet bridge (unless the physical Ethernet interface is configured
  32.136 -     * to transfer jumbo packets). If a larger MTU is desired then the system
  32.137 -     * administrator can specify it using the 'ifconfig' command.
  32.138 -     */
  32.139 -    /*dev->mtu             = 16*1024;*/
  32.140 +	dev->open            = loopback_open;
  32.141 +	dev->stop            = loopback_close;
  32.142 +	dev->hard_start_xmit = loopback_start_xmit;
  32.143 +	dev->get_stats       = loopback_get_stats;
  32.144 +
  32.145 +	dev->tx_queue_len    = 0;
  32.146 +
  32.147 +	dev->features        = NETIF_F_HIGHDMA | NETIF_F_LLTX;
  32.148 +
  32.149 +	/*
  32.150 +	 * We do not set a jumbo MTU on the interface. Otherwise the network
  32.151 +	 * stack will try to send large packets that will get dropped by the
  32.152 +	 * Ethernet bridge (unless the physical Ethernet interface is
  32.153 +	 * configured to transfer jumbo packets). If a larger MTU is desired
  32.154 +	 * then the system administrator can specify it using the 'ifconfig'
  32.155 +	 * command.
  32.156 +	 */
  32.157 +	/*dev->mtu             = 16*1024;*/
  32.158 +}
  32.159 +
  32.160 +static int __init make_loopback(int i)
  32.161 +{
  32.162 +	struct net_device *dev1, *dev2;
  32.163 +	char dev_name[IFNAMSIZ];
  32.164 +	int err = -ENOMEM;
  32.165 +
  32.166 +	sprintf(dev_name, "vif0.%d", i);
  32.167 +	dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
  32.168 +	sprintf(dev_name, "veth%d", i);
  32.169 +	dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup);
  32.170 +	if ((dev1 == NULL) || (dev2 == NULL))
  32.171 +		goto fail;
  32.172 +
  32.173 +	loopback_construct(dev1, dev2);
  32.174 +	loopback_construct(dev2, dev1);
  32.175 +
  32.176 +	dev1->features |= NETIF_F_NO_CSUM;
  32.177 +	dev2->features |= NETIF_F_IP_CSUM;
  32.178 +
  32.179 +	/*
  32.180 +	 * Initialise a dummy MAC address for the 'dummy backend' interface. We
  32.181 +	 * choose the numerically largest non-broadcast address to prevent the
  32.182 +	 * address getting stolen by an Ethernet bridge for STP purposes.
  32.183 +	 */
  32.184 +	memset(dev1->dev_addr, 0xFF, ETH_ALEN);
  32.185 +	dev1->dev_addr[0] &= ~0x01;
  32.186 +
  32.187 +	if ((err = register_netdev(dev1)) != 0)
  32.188 +		goto fail;
  32.189 +
  32.190 +	if ((err = register_netdev(dev2)) != 0) {
  32.191 +		unregister_netdev(dev1);
  32.192 +		goto fail;
  32.193 +	}
  32.194 +
  32.195 +	return 0;
  32.196 +
  32.197 + fail:
  32.198 +	if (dev1 != NULL)
  32.199 +		kfree(dev1);
  32.200 +	if (dev2 != NULL)
  32.201 +		kfree(dev2);
  32.202 +	return err;
  32.203  }
  32.204  
  32.205  static int __init loopback_init(void)
  32.206  {
  32.207 -    struct net_device *dev1, *dev2;
  32.208 -    int err = -ENOMEM;
  32.209 -
  32.210 -    dev1 = alloc_netdev(sizeof(struct net_private), "vif0.0", ether_setup);
  32.211 -    dev2 = alloc_netdev(sizeof(struct net_private), "veth0", ether_setup);
  32.212 -    if ( (dev1 == NULL) || (dev2 == NULL) )
  32.213 -        goto fail;
  32.214 -
  32.215 -    loopback_construct(dev1, dev2);
  32.216 -    loopback_construct(dev2, dev1);
  32.217 -
  32.218 -    dev1->features |= NETIF_F_NO_CSUM;
  32.219 -    dev2->features |= NETIF_F_IP_CSUM;
  32.220 +	int i, err = 0;
  32.221  
  32.222 -    /*
  32.223 -     * Initialise a dummy MAC address for the 'dummy backend' interface. We
  32.224 -     * choose the numerically largest non-broadcast address to prevent the
  32.225 -     * address getting stolen by an Ethernet bridge for STP purposes.
  32.226 -     */
  32.227 -    memset(dev1->dev_addr, 0xFF, ETH_ALEN);
  32.228 -    dev1->dev_addr[0] &= ~0x01;
  32.229 -
  32.230 -    if ( (err = register_netdev(dev1)) != 0 )
  32.231 -        goto fail;
  32.232 +	for (i = 0; i < nloopbacks; i++)
  32.233 +		if ((err = make_loopback(i)) != 0)
  32.234 +			break;
  32.235  
  32.236 -    if ( (err = register_netdev(dev2)) != 0 )
  32.237 -    {
  32.238 -        unregister_netdev(dev1);
  32.239 -        goto fail;
  32.240 -    }
  32.241 -
  32.242 -    return 0;
  32.243 -
  32.244 - fail:
  32.245 -    if ( dev1 != NULL )
  32.246 -        kfree(dev1);
  32.247 -    if ( dev2 != NULL )
  32.248 -        kfree(dev2);
  32.249 -    return err;
  32.250 +	return err;
  32.251  }
  32.252  
  32.253  module_init(loopback_init);
  32.254 +
  32.255 +/*
  32.256 + * Local variables:
  32.257 + *  c-file-style: "linux"
  32.258 + *  indent-tabs-mode: t
  32.259 + *  c-indent-level: 8
  32.260 + *  c-basic-offset: 8
  32.261 + *  tab-width: 8
  32.262 + * End:
  32.263 + */
    33.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Fri Sep 09 08:56:38 2005 +0000
    33.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Fri Sep 09 10:20:25 2005 +0000
    33.3 @@ -93,7 +93,9 @@ static PyObject *xspy_read(PyObject *sel
    33.4      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
    33.5                                       &path))
    33.6          goto exit;
    33.7 +    Py_BEGIN_ALLOW_THREADS
    33.8      xsval = xs_read(xh, path, &xsval_n);
    33.9 +    Py_END_ALLOW_THREADS
   33.10      if (!xsval) {
   33.11          val = pyvalue_int(0);
   33.12          goto exit;
   33.13 @@ -140,7 +142,9 @@ static PyObject *xspy_write(PyObject *se
   33.14  	flags |= O_CREAT;
   33.15      if (excl)
   33.16  	flags |= O_EXCL;
   33.17 +    Py_BEGIN_ALLOW_THREADS
   33.18      xsval = xs_write(xh, path, data, data_n, flags);
   33.19 +    Py_END_ALLOW_THREADS
   33.20      val = pyvalue_int(xsval);
   33.21   exit:
   33.22      return val;
   33.23 @@ -170,7 +174,9 @@ static PyObject *xspy_ls(PyObject *self,
   33.24  	goto exit;
   33.25      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
   33.26          goto exit;
   33.27 +    Py_BEGIN_ALLOW_THREADS
   33.28      xsval = xs_directory(xh, path, &xsval_n);
   33.29 +    Py_END_ALLOW_THREADS
   33.30      if (!xsval) {
   33.31          val = pyvalue_int(0);
   33.32          goto exit;
   33.33 @@ -204,7 +210,9 @@ static PyObject *xspy_mkdir(PyObject *se
   33.34  	goto exit;
   33.35      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
   33.36          goto exit;
   33.37 +    Py_BEGIN_ALLOW_THREADS
   33.38      xsval = xs_mkdir(xh, path);
   33.39 +    Py_END_ALLOW_THREADS
   33.40      val = pyvalue_int(xsval);
   33.41   exit:
   33.42      return val;
   33.43 @@ -232,7 +240,9 @@ static PyObject *xspy_rm(PyObject *self,
   33.44  	goto exit;
   33.45      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
   33.46          goto exit;
   33.47 +    Py_BEGIN_ALLOW_THREADS
   33.48      xsval = xs_rm(xh, path);
   33.49 +    Py_END_ALLOW_THREADS
   33.50      val = pyvalue_int(xsval);
   33.51   exit:
   33.52      return val;
   33.53 @@ -263,7 +273,9 @@ static PyObject *xspy_get_permissions(Py
   33.54  	goto exit;
   33.55      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
   33.56          goto exit;
   33.57 +    Py_BEGIN_ALLOW_THREADS
   33.58      perms = xs_get_permissions(xh, path, &perms_n);
   33.59 +    Py_END_ALLOW_THREADS
   33.60      if (!perms) {
   33.61          PyErr_SetFromErrno(PyExc_RuntimeError);
   33.62          goto exit;
   33.63 @@ -339,7 +351,9 @@ static PyObject *xspy_set_permissions(Py
   33.64          if (p_write)
   33.65  	    xsperms[i].perms |= XS_PERM_WRITE;
   33.66      }
   33.67 +    Py_BEGIN_ALLOW_THREADS
   33.68      xsval = xs_set_permissions(xh, path, xsperms, xsperms_n);
   33.69 +    Py_END_ALLOW_THREADS
   33.70      val = pyvalue_int(xsval);
   33.71   exit:
   33.72      Py_XDECREF(tuple0);
   33.73 @@ -381,7 +395,9 @@ static PyObject *xspy_watch(PyObject *se
   33.74          goto exit;
   33.75      Py_INCREF(token);
   33.76      sprintf(token_str, "%li", (unsigned long)token);
   33.77 +    Py_BEGIN_ALLOW_THREADS
   33.78      xsval = xs_watch(xh, path, token_str);
   33.79 +    Py_END_ALLOW_THREADS
   33.80      if (!xsval) {
   33.81  	val = PyErr_SetFromErrno(PyExc_RuntimeError);
   33.82  	Py_DECREF(token);
   33.83 @@ -429,7 +445,9 @@ static PyObject *xspy_read_watch(PyObjec
   33.84  	goto exit;
   33.85      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
   33.86          goto exit;
   33.87 +    Py_BEGIN_ALLOW_THREADS
   33.88      xsval = xs_read_watch(xh);
   33.89 +    Py_END_ALLOW_THREADS
   33.90      if (!xsval) {
   33.91  	val = PyErr_SetFromErrno(PyExc_RuntimeError);
   33.92  	goto exit;
   33.93 @@ -479,7 +497,9 @@ static PyObject *xspy_acknowledge_watch(
   33.94      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &token))
   33.95          goto exit;
   33.96      sprintf(token_str, "%li", (unsigned long)token);
   33.97 +    Py_BEGIN_ALLOW_THREADS
   33.98      xsval = xs_acknowledge_watch(xh, token_str);
   33.99 +    Py_END_ALLOW_THREADS
  33.100      if (!xsval) {
  33.101  	val = PyErr_SetFromErrno(PyExc_RuntimeError);
  33.102  	goto exit;
  33.103 @@ -519,7 +539,9 @@ static PyObject *xspy_unwatch(PyObject *
  33.104  				     &token))
  33.105          goto exit;
  33.106      sprintf(token_str, "%li", (unsigned long)token);
  33.107 +    Py_BEGIN_ALLOW_THREADS
  33.108      xsval = xs_unwatch(xh, path, token_str);
  33.109 +    Py_END_ALLOW_THREADS
  33.110      if (!xsval)
  33.111  	val = PyErr_SetFromErrno(PyExc_RuntimeError);
  33.112      else {
  33.113 @@ -561,7 +583,9 @@ static PyObject *xspy_transaction_start(
  33.114  	goto exit;
  33.115      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
  33.116          goto exit;
  33.117 +    Py_BEGIN_ALLOW_THREADS
  33.118      xsval = xs_transaction_start(xh, path);
  33.119 +    Py_END_ALLOW_THREADS
  33.120      val = pyvalue_int(xsval);
  33.121   exit:
  33.122      return val;
  33.123 @@ -591,7 +615,9 @@ static PyObject *xspy_transaction_end(Py
  33.124  	goto exit;
  33.125      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort))
  33.126          goto exit;
  33.127 +    Py_BEGIN_ALLOW_THREADS
  33.128      xsval = xs_transaction_end(xh, abort);
  33.129 +    Py_END_ALLOW_THREADS
  33.130      val = pyvalue_int(xsval);
  33.131   exit:
  33.132      return val;
  33.133 @@ -627,7 +653,9 @@ static PyObject *xspy_introduce_domain(P
  33.134      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  33.135                                       &dom, &page, &port, &path))
  33.136          goto exit;
  33.137 +    Py_BEGIN_ALLOW_THREADS
  33.138      xsval = xs_introduce_domain(xh, dom, page, port, path);
  33.139 +    Py_END_ALLOW_THREADS
  33.140      val = pyvalue_int(xsval);
  33.141   exit:
  33.142      return val;
  33.143 @@ -658,7 +686,9 @@ static PyObject *xspy_release_domain(PyO
  33.144      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
  33.145                                       &dom))
  33.146          goto exit;
  33.147 +    Py_BEGIN_ALLOW_THREADS
  33.148      xsval = xs_release_domain(xh, dom);
  33.149 +    Py_END_ALLOW_THREADS
  33.150      val = pyvalue_int(xsval);
  33.151   exit:
  33.152      return val;
  33.153 @@ -718,7 +748,9 @@ static PyObject *xspy_shutdown(PyObject 
  33.154  	goto exit;
  33.155      if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec))
  33.156          goto exit;
  33.157 +    Py_BEGIN_ALLOW_THREADS
  33.158      xsval = xs_shutdown(xh);
  33.159 +    Py_END_ALLOW_THREADS
  33.160      val = pyvalue_int(xsval);
  33.161   exit:
  33.162      return val;