direct-io.hg
changeset 6699:cdfa7dd00c44
merge?
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,43 @@ 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 +static inline int 9.50 +HYPERVISOR_mmu_update( 9.51 + mmu_update_t *req, int count, int *success_count, domid_t domid) 9.52 { 9.53 int ret; 9.54 + unsigned long ign1, ign2, ign3, ign4; 9.55 + 9.56 __asm__ __volatile__ ( 9.57 TRAP_INSTR 9.58 - : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table), 9.59 - _a1 (table) : "memory" ); 9.60 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 9.61 + : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), 9.62 + "3" (success_count), "4" (domid) 9.63 + : "memory" ); 9.64 9.65 return ret; 9.66 } 9.67 9.68 -static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, 9.69 - int count, 9.70 - int *success_count, 9.71 - domid_t domid) 9.72 +static inline int 9.73 +HYPERVISOR_mmuext_op( 9.74 + struct mmuext_op *op, int count, int *success_count, domid_t domid) 9.75 { 9.76 int ret; 9.77 unsigned long ign1, ign2, ign3, ign4; 9.78 @@ -89,18 +83,50 @@ static __inline__ int HYPERVISOR_mmu_upd 9.79 __asm__ __volatile__ ( 9.80 TRAP_INSTR 9.81 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 9.82 - : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), 9.83 - "3" (success_count), "4" (domid) 9.84 - : "memory" ); 9.85 + : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count), 9.86 + "3" (success_count), "4" (domid) 9.87 + : "memory" ); 9.88 9.89 return ret; 9.90 } 9.91 9.92 +static inline int 9.93 +HYPERVISOR_set_gdt( 9.94 + unsigned long *frame_list, int entries) 9.95 +{ 9.96 + int ret; 9.97 + unsigned long ign1, ign2; 9.98 9.99 -static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, 9.100 - int count, 9.101 - int *success_count, 9.102 - domid_t domid) 9.103 + __asm__ __volatile__ ( 9.104 + TRAP_INSTR 9.105 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.106 + : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries) 9.107 + : "memory" ); 9.108 + 9.109 + 9.110 + return ret; 9.111 +} 9.112 + 9.113 +static inline int 9.114 +HYPERVISOR_stack_switch( 9.115 + unsigned long ss, unsigned long esp) 9.116 +{ 9.117 + int ret; 9.118 + unsigned long ign1, ign2; 9.119 + 9.120 + __asm__ __volatile__ ( 9.121 + TRAP_INSTR 9.122 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.123 + : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp) 9.124 + : "memory" ); 9.125 + 9.126 + return ret; 9.127 +} 9.128 + 9.129 +static inline int 9.130 +HYPERVISOR_set_callbacks( 9.131 + unsigned long event_selector, unsigned long event_address, 9.132 + unsigned long failsafe_selector, unsigned long failsafe_address) 9.133 { 9.134 int ret; 9.135 unsigned long ign1, ign2, ign3, ign4; 9.136 @@ -108,70 +134,14 @@ static __inline__ int HYPERVISOR_mmuext_ 9.137 __asm__ __volatile__ ( 9.138 TRAP_INSTR 9.139 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 9.140 - : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count), 9.141 - "3" (success_count), "4" (domid) 9.142 - : "memory" ); 9.143 - 9.144 - return ret; 9.145 -} 9.146 - 9.147 - 9.148 - 9.149 -static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) 9.150 -{ 9.151 - int ret; 9.152 - __asm__ __volatile__ ( 9.153 - TRAP_INSTR 9.154 - : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), 9.155 - _a1 (frame_list), _a2 (entries) : "memory" ); 9.156 - 9.157 - 9.158 - return ret; 9.159 -} 9.160 - 9.161 -static __inline__ int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) 9.162 -{ 9.163 - int ret; 9.164 - __asm__ __volatile__ ( 9.165 - TRAP_INSTR 9.166 - : "=a" (ret) : "0" (__HYPERVISOR_stack_switch), 9.167 - _a1 (ss), _a2 (esp) : "memory" ); 9.168 + : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector), 9.169 + "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address) 9.170 + : "memory" ); 9.171 9.172 return ret; 9.173 } 9.174 9.175 -#ifdef __i386__ 9.176 -static __inline__ int HYPERVISOR_set_callbacks( 9.177 - unsigned long event_selector, unsigned long event_address, 9.178 - unsigned long failsafe_selector, unsigned long failsafe_address) 9.179 -{ 9.180 - int ret; 9.181 - __asm__ __volatile__ ( 9.182 - TRAP_INSTR 9.183 - : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), 9.184 - _a1 (event_selector), _a2 (event_address), 9.185 - _a3 (failsafe_selector), _a4 (failsafe_address) : "memory" ); 9.186 - 9.187 - return ret; 9.188 -} 9.189 -#else 9.190 -static __inline__ int HYPERVISOR_set_callbacks( 9.191 - unsigned long event_address, 9.192 - unsigned long failsafe_address, 9.193 - unsigned long syscall_address) 9.194 -{ 9.195 - int ret; 9.196 - __asm__ __volatile__ ( 9.197 - TRAP_INSTR 9.198 - : "=a" (ret) : "0" (__HYPERVISOR_set_callbacks), 9.199 - _a1 (event_address), _a2 (failsafe_address), 9.200 - _a3 (syscall_address) : "memory" ); 9.201 - 9.202 - return ret; 9.203 -} 9.204 -#endif 9.205 - 9.206 -static __inline__ int 9.207 +static inline int 9.208 HYPERVISOR_fpu_taskswitch( 9.209 int set) 9.210 { 9.211 @@ -187,67 +157,106 @@ HYPERVISOR_fpu_taskswitch( 9.212 return ret; 9.213 } 9.214 9.215 -static __inline__ int HYPERVISOR_yield(void) 9.216 +static inline int 9.217 +HYPERVISOR_yield( 9.218 + void) 9.219 { 9.220 int ret; 9.221 + unsigned long ign; 9.222 + 9.223 __asm__ __volatile__ ( 9.224 TRAP_INSTR 9.225 - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 9.226 - _a1 (SCHEDOP_yield) : "memory" ); 9.227 + : "=a" (ret), "=b" (ign) 9.228 + : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield) 9.229 + : "memory", "ecx" ); 9.230 9.231 return ret; 9.232 } 9.233 9.234 -static __inline__ int HYPERVISOR_block(void) 9.235 +static inline int 9.236 +HYPERVISOR_block( 9.237 + void) 9.238 { 9.239 int ret; 9.240 + unsigned long ign1; 9.241 __asm__ __volatile__ ( 9.242 TRAP_INSTR 9.243 - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 9.244 - _a1 (SCHEDOP_block) : "memory" ); 9.245 + : "=a" (ret), "=b" (ign1) 9.246 + : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block) 9.247 + : "memory", "ecx" ); 9.248 + 9.249 + return ret; 9.250 +} 9.251 + 9.252 +static inline int 9.253 +HYPERVISOR_shutdown( 9.254 + void) 9.255 +{ 9.256 + int ret; 9.257 + unsigned long ign1; 9.258 + __asm__ __volatile__ ( 9.259 + TRAP_INSTR 9.260 + : "=a" (ret), "=b" (ign1) 9.261 + : "0" (__HYPERVISOR_sched_op), 9.262 + "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) 9.263 + : "memory", "ecx" ); 9.264 9.265 return ret; 9.266 } 9.267 9.268 -static __inline__ int HYPERVISOR_shutdown(void) 9.269 +static inline int 9.270 +HYPERVISOR_reboot( 9.271 + void) 9.272 { 9.273 int ret; 9.274 + unsigned long ign1; 9.275 __asm__ __volatile__ ( 9.276 TRAP_INSTR 9.277 - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 9.278 - _a1 (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) 9.279 - : "memory" ); 9.280 + : "=a" (ret), "=b" (ign1) 9.281 + : "0" (__HYPERVISOR_sched_op), 9.282 + "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) 9.283 + : "memory", "ecx" ); 9.284 9.285 return ret; 9.286 } 9.287 9.288 -static __inline__ int HYPERVISOR_reboot(void) 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) : "0" (__HYPERVISOR_sched_op), 9.300 - _a1 (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) 9.301 - : "memory" ); 9.302 + : "=a" (ret), "=b" (ign1), "=S" (ign2) 9.303 + : "0" (__HYPERVISOR_sched_op), 9.304 + "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 9.305 + "S" (srec) : "memory", "ecx"); 9.306 9.307 return ret; 9.308 } 9.309 9.310 -static __inline__ int HYPERVISOR_suspend(unsigned long srec) 9.311 +static inline int 9.312 +HYPERVISOR_crash( 9.313 + void) 9.314 { 9.315 int ret; 9.316 - /* NB. On suspend, control software expects a suspend record in %esi. */ 9.317 + unsigned long ign1; 9.318 __asm__ __volatile__ ( 9.319 TRAP_INSTR 9.320 - : "=a" (ret) : "0" (__HYPERVISOR_sched_op), 9.321 - _a1 (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 9.322 - "S" (srec) : "memory" ); 9.323 + : "=a" (ret), "=b" (ign1) 9.324 + : "0" (__HYPERVISOR_sched_op), 9.325 + "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift)) 9.326 + : "memory", "ecx" ); 9.327 9.328 return ret; 9.329 } 9.330 9.331 -#ifdef __i386__ 9.332 -static __inline__ long HYPERVISOR_set_timer_op( u64 timeout ) 9.333 +static inline long 9.334 +HYPERVISOR_set_timer_op( 9.335 + u64 timeout) 9.336 { 9.337 int ret; 9.338 unsigned long timeout_hi = (unsigned long)(timeout>>32); 9.339 @@ -262,8 +271,516 @@ static __inline__ long HYPERVISOR_set_ti 9.340 9.341 return ret; 9.342 } 9.343 + 9.344 +#if 0 9.345 +static inline int 9.346 +HYPERVISOR_dom0_op( 9.347 + dom0_op_t *dom0_op) 9.348 +{ 9.349 + int ret; 9.350 + unsigned long ign1; 9.351 + 9.352 + dom0_op->interface_version = DOM0_INTERFACE_VERSION; 9.353 + __asm__ __volatile__ ( 9.354 + TRAP_INSTR 9.355 + : "=a" (ret), "=b" (ign1) 9.356 + : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op) 9.357 + : "memory"); 9.358 + 9.359 + return ret; 9.360 +} 9.361 +#endif 9.362 + 9.363 +static inline int 9.364 +HYPERVISOR_set_debugreg( 9.365 + int reg, unsigned long value) 9.366 +{ 9.367 + int ret; 9.368 + unsigned long ign1, ign2; 9.369 + __asm__ __volatile__ ( 9.370 + TRAP_INSTR 9.371 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.372 + : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value) 9.373 + : "memory" ); 9.374 + 9.375 + return ret; 9.376 +} 9.377 + 9.378 +static inline unsigned long 9.379 +HYPERVISOR_get_debugreg( 9.380 + int reg) 9.381 +{ 9.382 + unsigned long ret; 9.383 + unsigned long ign; 9.384 + __asm__ __volatile__ ( 9.385 + TRAP_INSTR 9.386 + : "=a" (ret), "=b" (ign) 9.387 + : "0" (__HYPERVISOR_get_debugreg), "1" (reg) 9.388 + : "memory" ); 9.389 + 9.390 + return ret; 9.391 +} 9.392 + 9.393 +static inline int 9.394 +HYPERVISOR_update_descriptor( 9.395 + u64 ma, u64 desc) 9.396 +{ 9.397 + int ret; 9.398 + unsigned long ign1, ign2, ign3, ign4; 9.399 + 9.400 + __asm__ __volatile__ ( 9.401 + TRAP_INSTR 9.402 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 9.403 + : "0" (__HYPERVISOR_update_descriptor), 9.404 + "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)), 9.405 + "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32)) 9.406 + : "memory" ); 9.407 + 9.408 + return ret; 9.409 +} 9.410 + 9.411 +static inline int 9.412 +HYPERVISOR_dom_mem_op( 9.413 + unsigned int op, unsigned long *extent_list, 9.414 + unsigned long nr_extents, unsigned int extent_order) 9.415 +{ 9.416 + int ret; 9.417 + unsigned long ign1, ign2, ign3, ign4, ign5; 9.418 + 9.419 + __asm__ __volatile__ ( 9.420 + TRAP_INSTR 9.421 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4), 9.422 + "=D" (ign5) 9.423 + : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list), 9.424 + "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF) 9.425 + : "memory" ); 9.426 + 9.427 + return ret; 9.428 +} 9.429 + 9.430 +static inline int 9.431 +HYPERVISOR_multicall( 9.432 + void *call_list, int nr_calls) 9.433 +{ 9.434 + int ret; 9.435 + unsigned long ign1, ign2; 9.436 + 9.437 + __asm__ __volatile__ ( 9.438 + TRAP_INSTR 9.439 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.440 + : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls) 9.441 + : "memory" ); 9.442 + 9.443 + return ret; 9.444 +} 9.445 + 9.446 +static inline int 9.447 +HYPERVISOR_update_va_mapping( 9.448 + unsigned long va, pte_t new_val, unsigned long flags) 9.449 +{ 9.450 + int ret; 9.451 + unsigned long ign1, ign2, ign3, ign4; 9.452 + 9.453 + __asm__ __volatile__ ( 9.454 + TRAP_INSTR 9.455 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 9.456 + : "0" (__HYPERVISOR_update_va_mapping), 9.457 + "1" (va), "2" ((new_val).pte_low), 9.458 +#ifdef CONFIG_X86_PAE 9.459 + "3" ((new_val).pte_high), 9.460 #else 9.461 -static __inline__ long HYPERVISOR_set_timer_op( u64 timeout ) 9.462 + "3" (0), 9.463 +#endif 9.464 + "4" (flags) 9.465 + : "memory" ); 9.466 + 9.467 + return ret; 9.468 +} 9.469 + 9.470 +static inline int 9.471 +HYPERVISOR_event_channel_op( 9.472 + void *op) 9.473 +{ 9.474 + int ret; 9.475 + unsigned long ignore; 9.476 + __asm__ __volatile__ ( 9.477 + TRAP_INSTR 9.478 + : "=a" (ret), "=b" (ignore) 9.479 + : "0" (__HYPERVISOR_event_channel_op), "1" (op) 9.480 + : "memory" ); 9.481 + 9.482 + return ret; 9.483 +} 9.484 + 9.485 +static inline int 9.486 +HYPERVISOR_xen_version( 9.487 + int cmd) 9.488 +{ 9.489 + int ret; 9.490 + unsigned long ignore; 9.491 + 9.492 + __asm__ __volatile__ ( 9.493 + TRAP_INSTR 9.494 + : "=a" (ret), "=b" (ignore) 9.495 + : "0" (__HYPERVISOR_xen_version), "1" (cmd) 9.496 + : "memory" ); 9.497 + 9.498 + return ret; 9.499 +} 9.500 + 9.501 +static inline int 9.502 +HYPERVISOR_console_io( 9.503 + int cmd, int count, char *str) 9.504 +{ 9.505 + int ret; 9.506 + unsigned long ign1, ign2, ign3; 9.507 + __asm__ __volatile__ ( 9.508 + TRAP_INSTR 9.509 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 9.510 + : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str) 9.511 + : "memory" ); 9.512 + 9.513 + return ret; 9.514 +} 9.515 + 9.516 +static inline int 9.517 +HYPERVISOR_physdev_op( 9.518 + void *physdev_op) 9.519 +{ 9.520 + int ret; 9.521 + unsigned long ign; 9.522 + 9.523 + __asm__ __volatile__ ( 9.524 + TRAP_INSTR 9.525 + : "=a" (ret), "=b" (ign) 9.526 + : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op) 9.527 + : "memory" ); 9.528 + 9.529 + return ret; 9.530 +} 9.531 + 9.532 +static inline int 9.533 +HYPERVISOR_grant_table_op( 9.534 + unsigned int cmd, void *uop, unsigned int count) 9.535 +{ 9.536 + int ret; 9.537 + unsigned long ign1, ign2, ign3; 9.538 + 9.539 + __asm__ __volatile__ ( 9.540 + TRAP_INSTR 9.541 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 9.542 + : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count) 9.543 + : "memory" ); 9.544 + 9.545 + return ret; 9.546 +} 9.547 + 9.548 +static inline int 9.549 +HYPERVISOR_update_va_mapping_otherdomain( 9.550 + unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) 9.551 +{ 9.552 + int ret; 9.553 + unsigned long ign1, ign2, ign3, ign4, ign5; 9.554 + 9.555 + __asm__ __volatile__ ( 9.556 + TRAP_INSTR 9.557 + : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), 9.558 + "=S" (ign4), "=D" (ign5) 9.559 + : "0" (__HYPERVISOR_update_va_mapping_otherdomain), 9.560 + "1" (va), "2" ((new_val).pte_low), 9.561 +#ifdef CONFIG_X86_PAE 9.562 + "3" ((new_val).pte_high), 9.563 +#else 9.564 + "3" (0), 9.565 +#endif 9.566 + "4" (flags), "5" (domid) : 9.567 + "memory" ); 9.568 + 9.569 + return ret; 9.570 +} 9.571 + 9.572 +static inline int 9.573 +HYPERVISOR_vm_assist( 9.574 + unsigned int cmd, unsigned int type) 9.575 +{ 9.576 + int ret; 9.577 + unsigned long ign1, ign2; 9.578 + 9.579 + __asm__ __volatile__ ( 9.580 + TRAP_INSTR 9.581 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.582 + : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type) 9.583 + : "memory" ); 9.584 + 9.585 + return ret; 9.586 +} 9.587 + 9.588 +static inline int 9.589 +HYPERVISOR_boot_vcpu( 9.590 + unsigned long vcpu, vcpu_guest_context_t *ctxt) 9.591 +{ 9.592 + int ret; 9.593 + unsigned long ign1, ign2; 9.594 + 9.595 + __asm__ __volatile__ ( 9.596 + TRAP_INSTR 9.597 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.598 + : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt) 9.599 + : "memory"); 9.600 + 9.601 + return ret; 9.602 +} 9.603 + 9.604 +static inline int 9.605 +HYPERVISOR_vcpu_down( 9.606 + int vcpu) 9.607 +{ 9.608 + int ret; 9.609 + unsigned long ign1; 9.610 + /* Yes, I really do want to clobber edx here: when we resume a 9.611 + vcpu after unpickling a multi-processor domain, it returns 9.612 + here, but clobbers all of the call clobbered registers. */ 9.613 + __asm__ __volatile__ ( 9.614 + TRAP_INSTR 9.615 + : "=a" (ret), "=b" (ign1) 9.616 + : "0" (__HYPERVISOR_sched_op), 9.617 + "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift)) 9.618 + : "memory", "ecx", "edx" ); 9.619 + 9.620 + return ret; 9.621 +} 9.622 + 9.623 +static inline int 9.624 +HYPERVISOR_vcpu_up( 9.625 + int vcpu) 9.626 +{ 9.627 + int ret; 9.628 + unsigned long ign1; 9.629 + __asm__ __volatile__ ( 9.630 + TRAP_INSTR 9.631 + : "=a" (ret), "=b" (ign1) 9.632 + : "0" (__HYPERVISOR_sched_op), 9.633 + "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift)) 9.634 + : "memory", "ecx" ); 9.635 + 9.636 + return ret; 9.637 +} 9.638 + 9.639 +static inline int 9.640 +HYPERVISOR_vcpu_pickle( 9.641 + int vcpu, vcpu_guest_context_t *ctxt) 9.642 +{ 9.643 + int ret; 9.644 + unsigned long ign1, ign2; 9.645 + __asm__ __volatile__ ( 9.646 + TRAP_INSTR 9.647 + : "=a" (ret), "=b" (ign1), "=c" (ign2) 9.648 + : "0" (__HYPERVISOR_sched_op), 9.649 + "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)), 9.650 + "2" (ctxt) 9.651 + : "memory" ); 9.652 + 9.653 + return ret; 9.654 +} 9.655 +#elif defined(__x86_64__) 9.656 + 9.657 +#define __syscall_clobber "r11","rcx","memory" 9.658 + 9.659 +/* 9.660 + * Assembler stubs for hyper-calls. 9.661 + */ 9.662 +static inline int 9.663 +HYPERVISOR_set_trap_table( 9.664 + trap_info_t *table) 9.665 +{ 9.666 + int ret; 9.667 + 9.668 + __asm__ __volatile__ ( 9.669 + TRAP_INSTR 9.670 + : "=a" (ret) 9.671 + : "0" ((unsigned long)__HYPERVISOR_set_trap_table), "D" (table) 9.672 + : __syscall_clobber ); 9.673 + 9.674 + return ret; 9.675 +} 9.676 + 9.677 +static inline int 9.678 +HYPERVISOR_mmu_update( 9.679 + mmu_update_t *req, int count, int *success_count, domid_t domid) 9.680 +{ 9.681 + int ret; 9.682 + 9.683 + __asm__ __volatile__ ( 9.684 + "movq %5, %%r10;" TRAP_INSTR 9.685 + : "=a" (ret) 9.686 + : "0" ((unsigned long)__HYPERVISOR_mmu_update), "D" (req), "S" ((long)count), 9.687 + "d" (success_count), "g" ((unsigned long)domid) 9.688 + : __syscall_clobber, "r10" ); 9.689 + 9.690 + return ret; 9.691 +} 9.692 + 9.693 +static inline int 9.694 +HYPERVISOR_mmuext_op( 9.695 + struct mmuext_op *op, int count, int *success_count, domid_t domid) 9.696 +{ 9.697 + int ret; 9.698 + 9.699 + __asm__ __volatile__ ( 9.700 + "movq %5, %%r10;" TRAP_INSTR 9.701 + : "=a" (ret) 9.702 + : "0" (__HYPERVISOR_mmuext_op), "D" (op), "S" ((long)count), 9.703 + "d" (success_count), "g" ((unsigned long)domid) 9.704 + : __syscall_clobber, "r10" ); 9.705 + 9.706 + return ret; 9.707 +} 9.708 + 9.709 +static inline int 9.710 +HYPERVISOR_set_gdt( 9.711 + unsigned long *frame_list, int entries) 9.712 +{ 9.713 + int ret; 9.714 + 9.715 + __asm__ __volatile__ ( 9.716 + TRAP_INSTR 9.717 + : "=a" (ret) 9.718 + : "0" ((unsigned long)__HYPERVISOR_set_gdt), "D" (frame_list), "S" ((long)entries) 9.719 + : __syscall_clobber ); 9.720 + 9.721 + 9.722 + return ret; 9.723 +} 9.724 +static inline int 9.725 +HYPERVISOR_stack_switch( 9.726 + unsigned long ss, unsigned long esp) 9.727 +{ 9.728 + int ret; 9.729 + 9.730 + __asm__ __volatile__ ( 9.731 + TRAP_INSTR 9.732 + : "=a" (ret) 9.733 + : "0" ((unsigned long)__HYPERVISOR_stack_switch), "D" (ss), "S" (esp) 9.734 + : __syscall_clobber ); 9.735 + 9.736 + return ret; 9.737 +} 9.738 + 9.739 +static inline int 9.740 +HYPERVISOR_set_callbacks( 9.741 + unsigned long event_address, unsigned long failsafe_address, 9.742 + unsigned long syscall_address) 9.743 +{ 9.744 + int ret; 9.745 + 9.746 + __asm__ __volatile__ ( 9.747 + TRAP_INSTR 9.748 + : "=a" (ret) 9.749 + : "0" ((unsigned long)__HYPERVISOR_set_callbacks), "D" (event_address), 9.750 + "S" (failsafe_address), "d" (syscall_address) 9.751 + : __syscall_clobber ); 9.752 + 9.753 + return ret; 9.754 +} 9.755 + 9.756 +static inline int 9.757 +HYPERVISOR_fpu_taskswitch( 9.758 + int set) 9.759 +{ 9.760 + int ret; 9.761 + __asm__ __volatile__ ( 9.762 + TRAP_INSTR 9.763 + : "=a" (ret) : "0" ((unsigned long)__HYPERVISOR_fpu_taskswitch), 9.764 + "D" ((unsigned long) set) : __syscall_clobber ); 9.765 + 9.766 + return ret; 9.767 +} 9.768 + 9.769 +static inline int 9.770 +HYPERVISOR_yield( 9.771 + void) 9.772 +{ 9.773 + int ret; 9.774 + 9.775 + __asm__ __volatile__ ( 9.776 + TRAP_INSTR 9.777 + : "=a" (ret) 9.778 + : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_yield) 9.779 + : __syscall_clobber ); 9.780 + 9.781 + return ret; 9.782 +} 9.783 + 9.784 +static inline int 9.785 +HYPERVISOR_block( 9.786 + void) 9.787 +{ 9.788 + int ret; 9.789 + __asm__ __volatile__ ( 9.790 + TRAP_INSTR 9.791 + : "=a" (ret) 9.792 + : "0" ((unsigned long)__HYPERVISOR_sched_op), "D" ((unsigned long)SCHEDOP_block) 9.793 + : __syscall_clobber ); 9.794 + 9.795 + return ret; 9.796 +} 9.797 + 9.798 +static inline int 9.799 +HYPERVISOR_shutdown( 9.800 + void) 9.801 +{ 9.802 + int ret; 9.803 + __asm__ __volatile__ ( 9.804 + TRAP_INSTR 9.805 + : "=a" (ret) 9.806 + : "0" ((unsigned long)__HYPERVISOR_sched_op), 9.807 + "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))) 9.808 + : __syscall_clobber ); 9.809 + 9.810 + return ret; 9.811 +} 9.812 + 9.813 +static inline int 9.814 +HYPERVISOR_reboot( 9.815 + void) 9.816 +{ 9.817 + int ret; 9.818 + 9.819 + __asm__ __volatile__ ( 9.820 + TRAP_INSTR 9.821 + : "=a" (ret) 9.822 + : "0" ((unsigned long)__HYPERVISOR_sched_op), 9.823 + "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))) 9.824 + : __syscall_clobber ); 9.825 + 9.826 + return ret; 9.827 +} 9.828 + 9.829 +static inline int 9.830 +HYPERVISOR_suspend( 9.831 + unsigned long srec) 9.832 +{ 9.833 + int ret; 9.834 + 9.835 + /* NB. On suspend, control software expects a suspend record in %esi. */ 9.836 + __asm__ __volatile__ ( 9.837 + TRAP_INSTR 9.838 + : "=a" (ret) 9.839 + : "0" ((unsigned long)__HYPERVISOR_sched_op), 9.840 + "D" ((unsigned long)(SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift))), 9.841 + "S" (srec) 9.842 + : __syscall_clobber ); 9.843 + 9.844 + return ret; 9.845 +} 9.846 + 9.847 +/* 9.848 + * We can have the timeout value in a single argument for the hypercall, but 9.849 + * that will break the common code. 9.850 + */ 9.851 +static inline long 9.852 +HYPERVISOR_set_timer_op( 9.853 + u64 timeout) 9.854 { 9.855 int ret; 9.856
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 + 12.471 12.472 -#define rdtsc(low,high) \ 12.473 - __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) 12.474 - 12.475 +#endif /* not assembly */ 12.476 #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 +#include <mm.h> 21.33 +#include <ctype.h> 21.34 21.35 -/**************************************************************************** 21.36 - * RN: printf family of routines 21.37 - * taken mainly from sys/subr_prf.c 21.38 - ****************************************************************************/ 21.39 -char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 21.40 -#define hex2ascii(hex) (hex2ascii_data[hex]) 21.41 -#define NBBY 8 /* number of bits in a byte */ 21.42 -#define MAXNBUF (sizeof(quad_t) * NBBY + 1) 21.43 +/** 21.44 + * simple_strtoul - convert a string to an unsigned long 21.45 + * @cp: The start of the string 21.46 + * @endp: A pointer to the end of the parsed string will be placed here 21.47 + * @base: The number base to use 21.48 + */ 21.49 +unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) 21.50 +{ 21.51 + unsigned long result = 0,value; 21.52 + 21.53 + if (!base) { 21.54 + base = 10; 21.55 + if (*cp == '0') { 21.56 + base = 8; 21.57 + cp++; 21.58 + if ((*cp == 'x') && isxdigit(cp[1])) { 21.59 + cp++; 21.60 + base = 16; 21.61 + } 21.62 + } 21.63 + } 21.64 + while (isxdigit(*cp) && 21.65 + (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { 21.66 + result = result*base + value; 21.67 + cp++; 21.68 + } 21.69 + if (endp) 21.70 + *endp = (char *)cp; 21.71 + return result; 21.72 +} 21.73 + 21.74 +/** 21.75 + * simple_strtol - convert a string to a signed long 21.76 + * @cp: The start of the string 21.77 + * @endp: A pointer to the end of the parsed string will be placed here 21.78 + * @base: The number base to use 21.79 + */ 21.80 +long simple_strtol(const char *cp,char **endp,unsigned int base) 21.81 +{ 21.82 + if(*cp=='-') 21.83 + return -simple_strtoul(cp+1,endp,base); 21.84 + return simple_strtoul(cp,endp,base); 21.85 +} 21.86 21.87 -static int kvprintf(char const *fmt, void *arg, int radix, va_list ap); 21.88 +/** 21.89 + * simple_strtoull - convert a string to an unsigned long long 21.90 + * @cp: The start of the string 21.91 + * @endp: A pointer to the end of the parsed string will be placed here 21.92 + * @base: The number base to use 21.93 + */ 21.94 +unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) 21.95 +{ 21.96 + unsigned long long result = 0,value; 21.97 21.98 + if (!base) { 21.99 + base = 10; 21.100 + if (*cp == '0') { 21.101 + base = 8; 21.102 + cp++; 21.103 + if ((*cp == 'x') && isxdigit(cp[1])) { 21.104 + cp++; 21.105 + base = 16; 21.106 + } 21.107 + } 21.108 + } 21.109 + while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp) 21.110 + ? toupper(*cp) : *cp)-'A'+10) < base) { 21.111 + result = result*base + value; 21.112 + cp++; 21.113 + } 21.114 + if (endp) 21.115 + *endp = (char *)cp; 21.116 + return result; 21.117 +} 21.118 + 21.119 +/** 21.120 + * simple_strtoll - convert a string to a signed long long 21.121 + * @cp: The start of the string 21.122 + * @endp: A pointer to the end of the parsed string will be placed here 21.123 + * @base: The number base to use 21.124 + */ 21.125 +long long simple_strtoll(const char *cp,char **endp,unsigned int base) 21.126 +{ 21.127 + if(*cp=='-') 21.128 + return -simple_strtoull(cp+1,endp,base); 21.129 + return simple_strtoull(cp,endp,base); 21.130 +} 21.131 + 21.132 +static int skip_atoi(const char **s) 21.133 +{ 21.134 + int i=0; 21.135 + 21.136 + while (isdigit(**s)) 21.137 + i = i*10 + *((*s)++) - '0'; 21.138 + return i; 21.139 +} 21.140 21.141 -int 21.142 -printf(const char *fmt, ...) 21.143 +#define ZEROPAD 1 /* pad with zero */ 21.144 +#define SIGN 2 /* unsigned/signed long */ 21.145 +#define PLUS 4 /* show plus */ 21.146 +#define SPACE 8 /* space if plus */ 21.147 +#define LEFT 16 /* left justified */ 21.148 +#define SPECIAL 32 /* 0x */ 21.149 +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ 21.150 + 21.151 +static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type) 21.152 { 21.153 - va_list ap; 21.154 - int retval; 21.155 - static char printk_buf[1024]; 21.156 + char c,sign,tmp[66]; 21.157 + const char *digits; 21.158 + const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; 21.159 + const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 21.160 + int i; 21.161 21.162 - va_start(ap, fmt); 21.163 - retval = kvprintf(fmt, printk_buf, 10, ap); 21.164 - printk_buf[retval] = '\0'; 21.165 - va_end(ap); 21.166 - (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(printk_buf), 21.167 - printk_buf); 21.168 - return retval; 21.169 + digits = (type & LARGE) ? large_digits : small_digits; 21.170 + if (type & LEFT) 21.171 + type &= ~ZEROPAD; 21.172 + if (base < 2 || base > 36) 21.173 + return buf; 21.174 + c = (type & ZEROPAD) ? '0' : ' '; 21.175 + sign = 0; 21.176 + if (type & SIGN) { 21.177 + if (num < 0) { 21.178 + sign = '-'; 21.179 + num = -num; 21.180 + size--; 21.181 + } else if (type & PLUS) { 21.182 + sign = '+'; 21.183 + size--; 21.184 + } else if (type & SPACE) { 21.185 + sign = ' '; 21.186 + size--; 21.187 + } 21.188 + } 21.189 + if (type & SPECIAL) { 21.190 + if (base == 16) 21.191 + size -= 2; 21.192 + else if (base == 8) 21.193 + size--; 21.194 + } 21.195 + i = 0; 21.196 + if (num == 0) 21.197 + tmp[i++]='0'; 21.198 + else 21.199 + { 21.200 + /* XXX KAF: force unsigned mod and div. */ 21.201 + unsigned long long num2=(unsigned long long)num; 21.202 + unsigned int base2=(unsigned int)base; 21.203 + while (num2 != 0) { tmp[i++] = digits[num2%base2]; num2 /= base2; } 21.204 + } 21.205 + if (i > precision) 21.206 + precision = i; 21.207 + size -= precision; 21.208 + if (!(type&(ZEROPAD+LEFT))) { 21.209 + while(size-->0) { 21.210 + if (buf <= end) 21.211 + *buf = ' '; 21.212 + ++buf; 21.213 + } 21.214 + } 21.215 + if (sign) { 21.216 + if (buf <= end) 21.217 + *buf = sign; 21.218 + ++buf; 21.219 + } 21.220 + if (type & SPECIAL) { 21.221 + if (base==8) { 21.222 + if (buf <= end) 21.223 + *buf = '0'; 21.224 + ++buf; 21.225 + } else if (base==16) { 21.226 + if (buf <= end) 21.227 + *buf = '0'; 21.228 + ++buf; 21.229 + if (buf <= end) 21.230 + *buf = digits[33]; 21.231 + ++buf; 21.232 + } 21.233 + } 21.234 + if (!(type & LEFT)) { 21.235 + while (size-- > 0) { 21.236 + if (buf <= end) 21.237 + *buf = c; 21.238 + ++buf; 21.239 + } 21.240 + } 21.241 + while (i < precision--) { 21.242 + if (buf <= end) 21.243 + *buf = '0'; 21.244 + ++buf; 21.245 + } 21.246 + while (i-- > 0) { 21.247 + if (buf <= end) 21.248 + *buf = tmp[i]; 21.249 + ++buf; 21.250 + } 21.251 + while (size-- > 0) { 21.252 + if (buf <= end) 21.253 + *buf = ' '; 21.254 + ++buf; 21.255 + } 21.256 + return buf; 21.257 } 21.258 21.259 -int 21.260 -vprintf(const char *fmt, va_list ap) 21.261 +/** 21.262 +* vsnprintf - Format a string and place it in a buffer 21.263 +* @buf: The buffer to place the result into 21.264 +* @size: The size of the buffer, including the trailing null space 21.265 +* @fmt: The format string to use 21.266 +* @args: Arguments for the format string 21.267 +* 21.268 +* Call this function if you are already dealing with a va_list. 21.269 +* You probably want snprintf instead. 21.270 + */ 21.271 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) 21.272 { 21.273 - int retval; 21.274 - static char printk_buf[1024]; 21.275 - retval = kvprintf(fmt, printk_buf, 10, ap); 21.276 - printk_buf[retval] = '\0'; 21.277 - (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(printk_buf), 21.278 - printk_buf); 21.279 - return retval; 21.280 + int len; 21.281 + unsigned long long num; 21.282 + int i, base; 21.283 + char *str, *end, c; 21.284 + const char *s; 21.285 + 21.286 + int flags; /* flags to number() */ 21.287 + 21.288 + int field_width; /* width of output field */ 21.289 + int precision; /* min. # of digits for integers; max 21.290 + number of chars for from string */ 21.291 + int qualifier; /* 'h', 'l', or 'L' for integer fields */ 21.292 + /* 'z' support added 23/7/1999 S.H. */ 21.293 + /* 'z' changed to 'Z' --davidm 1/25/99 */ 21.294 + 21.295 + str = buf; 21.296 + end = buf + size - 1; 21.297 + 21.298 + if (end < buf - 1) { 21.299 + end = ((void *) -1); 21.300 + size = end - buf + 1; 21.301 + } 21.302 + 21.303 + for (; *fmt ; ++fmt) { 21.304 + if (*fmt != '%') { 21.305 + if (str <= end) 21.306 + *str = *fmt; 21.307 + ++str; 21.308 + continue; 21.309 + } 21.310 + 21.311 + /* process flags */ 21.312 + flags = 0; 21.313 + repeat: 21.314 + ++fmt; /* this also skips first '%' */ 21.315 + switch (*fmt) { 21.316 + case '-': flags |= LEFT; goto repeat; 21.317 + case '+': flags |= PLUS; goto repeat; 21.318 + case ' ': flags |= SPACE; goto repeat; 21.319 + case '#': flags |= SPECIAL; goto repeat; 21.320 + case '0': flags |= ZEROPAD; goto repeat; 21.321 + } 21.322 + 21.323 + /* get field width */ 21.324 + field_width = -1; 21.325 + if (isdigit(*fmt)) 21.326 + field_width = skip_atoi(&fmt); 21.327 + else if (*fmt == '*') { 21.328 + ++fmt; 21.329 + /* it's the next argument */ 21.330 + field_width = va_arg(args, int); 21.331 + if (field_width < 0) { 21.332 + field_width = -field_width; 21.333 + flags |= LEFT; 21.334 + } 21.335 + } 21.336 + 21.337 + /* get the precision */ 21.338 + precision = -1; 21.339 + if (*fmt == '.') { 21.340 + ++fmt; 21.341 + if (isdigit(*fmt)) 21.342 + precision = skip_atoi(&fmt); 21.343 + else if (*fmt == '*') { 21.344 + ++fmt; 21.345 + /* it's the next argument */ 21.346 + precision = va_arg(args, int); 21.347 + } 21.348 + if (precision < 0) 21.349 + precision = 0; 21.350 + } 21.351 + 21.352 + /* get the conversion qualifier */ 21.353 + qualifier = -1; 21.354 + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { 21.355 + qualifier = *fmt; 21.356 + ++fmt; 21.357 + if (qualifier == 'l' && *fmt == 'l') { 21.358 + qualifier = 'L'; 21.359 + ++fmt; 21.360 + } 21.361 + } 21.362 + if (*fmt == 'q') { 21.363 + qualifier = 'L'; 21.364 + ++fmt; 21.365 + } 21.366 + 21.367 + /* default base */ 21.368 + base = 10; 21.369 + 21.370 + switch (*fmt) { 21.371 + case 'c': 21.372 + if (!(flags & LEFT)) { 21.373 + while (--field_width > 0) { 21.374 + if (str <= end) 21.375 + *str = ' '; 21.376 + ++str; 21.377 + } 21.378 + } 21.379 + c = (unsigned char) va_arg(args, int); 21.380 + if (str <= end) 21.381 + *str = c; 21.382 + ++str; 21.383 + while (--field_width > 0) { 21.384 + if (str <= end) 21.385 + *str = ' '; 21.386 + ++str; 21.387 + } 21.388 + continue; 21.389 + 21.390 + case 's': 21.391 + s = va_arg(args, char *); 21.392 + if (!s) 21.393 + s = "<NULL>"; 21.394 + 21.395 + len = strnlen(s, precision); 21.396 + 21.397 + if (!(flags & LEFT)) { 21.398 + while (len < field_width--) { 21.399 + if (str <= end) 21.400 + *str = ' '; 21.401 + ++str; 21.402 + } 21.403 + } 21.404 + for (i = 0; i < len; ++i) { 21.405 + if (str <= end) 21.406 + *str = *s; 21.407 + ++str; ++s; 21.408 + } 21.409 + while (len < field_width--) { 21.410 + if (str <= end) 21.411 + *str = ' '; 21.412 + ++str; 21.413 + } 21.414 + continue; 21.415 + 21.416 + case 'p': 21.417 + if (field_width == -1) { 21.418 + field_width = 2*sizeof(void *); 21.419 + flags |= ZEROPAD; 21.420 + } 21.421 + str = number(str, end, 21.422 + (unsigned long) va_arg(args, void *), 21.423 + 16, field_width, precision, flags); 21.424 + continue; 21.425 + 21.426 + 21.427 + case 'n': 21.428 + /* FIXME: 21.429 + * What does C99 say about the overflow case here? */ 21.430 + if (qualifier == 'l') { 21.431 + long * ip = va_arg(args, long *); 21.432 + *ip = (str - buf); 21.433 + } else if (qualifier == 'Z') { 21.434 + size_t * ip = va_arg(args, size_t *); 21.435 + *ip = (str - buf); 21.436 + } else { 21.437 + int * ip = va_arg(args, int *); 21.438 + *ip = (str - buf); 21.439 + } 21.440 + continue; 21.441 + 21.442 + case '%': 21.443 + if (str <= end) 21.444 + *str = '%'; 21.445 + ++str; 21.446 + continue; 21.447 + 21.448 + /* integer number formats - set up the flags and "break" */ 21.449 + case 'o': 21.450 + base = 8; 21.451 + break; 21.452 + 21.453 + case 'X': 21.454 + flags |= LARGE; 21.455 + case 'x': 21.456 + base = 16; 21.457 + break; 21.458 + 21.459 + case 'd': 21.460 + case 'i': 21.461 + flags |= SIGN; 21.462 + case 'u': 21.463 + break; 21.464 + 21.465 + default: 21.466 + if (str <= end) 21.467 + *str = '%'; 21.468 + ++str; 21.469 + if (*fmt) { 21.470 + if (str <= end) 21.471 + *str = *fmt; 21.472 + ++str; 21.473 + } else { 21.474 + --fmt; 21.475 + } 21.476 + continue; 21.477 + } 21.478 + if (qualifier == 'L') 21.479 + num = va_arg(args, long long); 21.480 + else if (qualifier == 'l') { 21.481 + num = va_arg(args, unsigned long); 21.482 + if (flags & SIGN) 21.483 + num = (signed long) num; 21.484 + } else if (qualifier == 'Z') { 21.485 + num = va_arg(args, size_t); 21.486 + } else if (qualifier == 'h') { 21.487 + num = (unsigned short) va_arg(args, int); 21.488 + if (flags & SIGN) 21.489 + num = (signed short) num; 21.490 + } else { 21.491 + num = va_arg(args, unsigned int); 21.492 + if (flags & SIGN) 21.493 + num = (signed int) num; 21.494 + } 21.495 + 21.496 + str = number(str, end, num, base, 21.497 + field_width, precision, flags); 21.498 + } 21.499 + if (str <= end) 21.500 + *str = '\0'; 21.501 + else if (size > 0) 21.502 + /* don't write out a null byte if the buf size is zero */ 21.503 + *end = '\0'; 21.504 + /* the trailing null byte doesn't count towards the total 21.505 + * ++str; 21.506 + */ 21.507 + return str-buf; 21.508 } 21.509 21.510 -int 21.511 -sprintf(char *buf, const char *cfmt, ...) 21.512 +/** 21.513 + * snprintf - Format a string and place it in a buffer 21.514 + * @buf: The buffer to place the result into 21.515 + * @size: The size of the buffer, including the trailing null space 21.516 + * @fmt: The format string to use 21.517 + * @...: Arguments for the format string 21.518 + */ 21.519 +int snprintf(char * buf, size_t size, const char *fmt, ...) 21.520 { 21.521 - int retval; 21.522 - va_list ap; 21.523 + va_list args; 21.524 + int i; 21.525 21.526 - va_start(ap, cfmt); 21.527 - retval = kvprintf(cfmt, (void *)buf, 10, ap); 21.528 - buf[retval] = '\0'; 21.529 - va_end(ap); 21.530 - return retval; 21.531 + va_start(args, fmt); 21.532 + i=vsnprintf(buf,size,fmt,args); 21.533 + va_end(args); 21.534 + return i; 21.535 } 21.536 21.537 -int 21.538 -vsprintf(char *buf, const char *cfmt, va_list ap) 21.539 +/** 21.540 + * vsprintf - Format a string and place it in a buffer 21.541 + * @buf: The buffer to place the result into 21.542 + * @fmt: The format string to use 21.543 + * @args: Arguments for the format string 21.544 + * 21.545 + * Call this function if you are already dealing with a va_list. 21.546 + * You probably want sprintf instead. 21.547 + */ 21.548 +int vsprintf(char *buf, const char *fmt, va_list args) 21.549 { 21.550 - int retval; 21.551 - 21.552 - retval = kvprintf(cfmt, (void *)buf, 10, ap); 21.553 - buf[retval] = '\0'; 21.554 - return retval; 21.555 + return vsnprintf(buf, 0xFFFFFFFFUL, fmt, args); 21.556 } 21.557 21.558 21.559 -/* 21.560 - * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse 21.561 - * order; return an optional length and a pointer to the last character 21.562 - * written in the buffer (i.e., the first character of the string). 21.563 - * The buffer pointed to by `nbuf' must have length >= MAXNBUF. 21.564 +/** 21.565 + * sprintf - Format a string and place it in a buffer 21.566 + * @buf: The buffer to place the result into 21.567 + * @fmt: The format string to use 21.568 + * @...: Arguments for the format string 21.569 */ 21.570 -static char * 21.571 -ksprintn(char *nbuf, u_long ul, int base, int *lenp) 21.572 +int sprintf(char * buf, const char *fmt, ...) 21.573 { 21.574 - char *p; 21.575 + va_list args; 21.576 + int i; 21.577 21.578 - p = nbuf; 21.579 - *p = '\0'; 21.580 - do { 21.581 - *++p = hex2ascii(ul % base); 21.582 - } while (ul /= base); 21.583 - if (lenp) 21.584 - *lenp = p - nbuf; 21.585 - return (p); 21.586 + va_start(args, fmt); 21.587 + i=vsprintf(buf,fmt,args); 21.588 + va_end(args); 21.589 + return i; 21.590 } 21.591 -/* ksprintn, but for a quad_t. */ 21.592 -static char * 21.593 -ksprintqn(char *nbuf, u_quad_t uq, int base, int *lenp) 21.594 -{ 21.595 - char *p; 21.596 + 21.597 21.598 - p = nbuf; 21.599 - *p = '\0'; 21.600 - do { 21.601 - *++p = hex2ascii(uq % base); 21.602 - } while (uq /= base); 21.603 - if (lenp) 21.604 - *lenp = p - nbuf; 21.605 - return (p); 21.606 +void printf(const char *fmt, ...) 21.607 +{ 21.608 + static char buf[1024]; 21.609 + va_list args; 21.610 + 21.611 + va_start(args, fmt); 21.612 + (void)vsnprintf(buf, sizeof(buf), fmt, args); 21.613 + va_end(args); 21.614 + 21.615 + (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); 21.616 } 21.617 21.618 -/* 21.619 - * Scaled down version of printf(3). 21.620 - * 21.621 - * Two additional formats: 21.622 - * 21.623 - * The format %b is supported to decode error registers. 21.624 - * Its usage is: 21.625 - * 21.626 - * printf("reg=%b\n", regval, "<base><arg>*"); 21.627 - * 21.628 - * where <base> is the output base expressed as a control character, e.g. 21.629 - * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, 21.630 - * the first of which gives the bit number to be inspected (origin 1), and 21.631 - * the next characters (up to a control character, i.e. a character <= 32), 21.632 - * give the name of the register. Thus: 21.633 - * 21.634 - * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 21.635 - * 21.636 - * would produce output: 21.637 - * 21.638 - * reg=3<BITTWO,BITONE> 21.639 - * 21.640 - * XXX: %D -- Hexdump, takes pointer and separator string: 21.641 - * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX 21.642 - * ("%*D", len, ptr, " " -> XX XX XX XX ... 21.643 +/** 21.644 + * vsscanf - Unformat a buffer into a list of arguments 21.645 + * @buf: input buffer 21.646 + * @fmt: format of buffer 21.647 + * @args: arguments 21.648 */ 21.649 +int vsscanf(const char * buf, const char * fmt, va_list args) 21.650 +{ 21.651 + const char *str = buf; 21.652 + char *next; 21.653 + char digit; 21.654 + int num = 0; 21.655 + int qualifier; 21.656 + int base; 21.657 + int field_width; 21.658 + int is_sign = 0; 21.659 + 21.660 + while(*fmt && *str) { 21.661 + /* skip any white space in format */ 21.662 + /* white space in format matchs any amount of 21.663 + * white space, including none, in the input. 21.664 + */ 21.665 + if (isspace(*fmt)) { 21.666 + while (isspace(*fmt)) 21.667 + ++fmt; 21.668 + while (isspace(*str)) 21.669 + ++str; 21.670 + } 21.671 + 21.672 + /* anything that is not a conversion must match exactly */ 21.673 + if (*fmt != '%' && *fmt) { 21.674 + if (*fmt++ != *str++) 21.675 + break; 21.676 + continue; 21.677 + } 21.678 21.679 -/* RN: This normally takes a function for output. 21.680 - * we always print to a string and the use HYPERCALL for write to console */ 21.681 -static int 21.682 -kvprintf(char const *fmt, void *arg, int radix, va_list ap) 21.683 -{ 21.684 - 21.685 -#define PCHAR(c) {int cc=(c); *d++ = cc; retval++; } 21.686 + if (!*fmt) 21.687 + break; 21.688 + ++fmt; 21.689 + 21.690 + /* skip this conversion. 21.691 + * advance both strings to next white space 21.692 + */ 21.693 + if (*fmt == '*') { 21.694 + while (!isspace(*fmt) && *fmt) 21.695 + fmt++; 21.696 + while (!isspace(*str) && *str) 21.697 + str++; 21.698 + continue; 21.699 + } 21.700 21.701 - char nbuf[MAXNBUF]; 21.702 - char *p, *q, *d; 21.703 - u_char *up; 21.704 - int ch, n; 21.705 - u_long ul; 21.706 - u_quad_t uq; 21.707 - int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; 21.708 - int dwidth; 21.709 - char padc; 21.710 - int retval = 0; 21.711 + /* get field width */ 21.712 + field_width = -1; 21.713 + if (isdigit(*fmt)) 21.714 + field_width = skip_atoi(&fmt); 21.715 21.716 - ul = 0; 21.717 - uq = 0; 21.718 - d = (char *) arg; 21.719 - 21.720 - if (fmt == NULL) 21.721 - fmt = "(fmt null)\n"; 21.722 - 21.723 - if (radix < 2 || radix > 36) 21.724 - radix = 10; 21.725 + /* get conversion qualifier */ 21.726 + qualifier = -1; 21.727 + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || 21.728 + *fmt == 'Z' || *fmt == 'z') { 21.729 + qualifier = *fmt++; 21.730 + if (unlikely(qualifier == *fmt)) { 21.731 + if (qualifier == 'h') { 21.732 + qualifier = 'H'; 21.733 + fmt++; 21.734 + } else if (qualifier == 'l') { 21.735 + qualifier = 'L'; 21.736 + fmt++; 21.737 + } 21.738 + } 21.739 + } 21.740 + base = 10; 21.741 + is_sign = 0; 21.742 21.743 - for (;;) { 21.744 - padc = ' '; 21.745 - width = 0; 21.746 - while ((ch = (u_char)*fmt++) != '%') { 21.747 - if (ch == '\0') 21.748 - return retval; 21.749 - PCHAR(ch); 21.750 - } 21.751 - qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; 21.752 - sign = 0; dot = 0; dwidth = 0; 21.753 -reswitch: switch (ch = (u_char)*fmt++) { 21.754 - case '.': 21.755 - dot = 1; 21.756 - goto reswitch; 21.757 - case '#': 21.758 - sharpflag = 1; 21.759 - goto reswitch; 21.760 - case '+': 21.761 - sign = 1; 21.762 - goto reswitch; 21.763 - case '-': 21.764 - ladjust = 1; 21.765 - goto reswitch; 21.766 - case '%': 21.767 - PCHAR(ch); 21.768 + if (!*fmt || !*str) 21.769 break; 21.770 - case '*': 21.771 - if (!dot) { 21.772 - width = va_arg(ap, int); 21.773 - if (width < 0) { 21.774 - ladjust = !ladjust; 21.775 - width = -width; 21.776 - } 21.777 - } else { 21.778 - dwidth = va_arg(ap, int); 21.779 - } 21.780 - goto reswitch; 21.781 - case '0': 21.782 - if (!dot) { 21.783 - padc = '0'; 21.784 - goto reswitch; 21.785 + 21.786 + switch(*fmt++) { 21.787 + case 'c': 21.788 + { 21.789 + char *s = (char *) va_arg(args,char*); 21.790 + if (field_width == -1) 21.791 + field_width = 1; 21.792 + do { 21.793 + *s++ = *str++; 21.794 + } while (--field_width > 0 && *str); 21.795 + num++; 21.796 + } 21.797 + continue; 21.798 + case 's': 21.799 + { 21.800 + char *s = (char *) va_arg(args, char *); 21.801 + if(field_width == -1) 21.802 + field_width = INT_MAX; 21.803 + /* first, skip leading white space in buffer */ 21.804 + while (isspace(*str)) 21.805 + str++; 21.806 + 21.807 + /* now copy until next white space */ 21.808 + while (*str && !isspace(*str) && field_width--) { 21.809 + *s++ = *str++; 21.810 } 21.811 - case '1': case '2': case '3': case '4': 21.812 - case '5': case '6': case '7': case '8': case '9': 21.813 - for (n = 0;; ++fmt) { 21.814 - n = n * 10 + ch - '0'; 21.815 - ch = *fmt; 21.816 - if (ch < '0' || ch > '9') 21.817 - break; 21.818 - } 21.819 - if (dot) 21.820 - dwidth = n; 21.821 - else 21.822 - width = n; 21.823 - goto reswitch; 21.824 - case 'b': 21.825 - ul = va_arg(ap, int); 21.826 - p = va_arg(ap, char *); 21.827 - for (q = ksprintn(nbuf, ul, *p++, NULL); *q;) 21.828 - PCHAR(*q--); 21.829 + *s = '\0'; 21.830 + num++; 21.831 + } 21.832 + continue; 21.833 + case 'n': 21.834 + /* return number of characters read so far */ 21.835 + { 21.836 + int *i = (int *)va_arg(args,int*); 21.837 + *i = str - buf; 21.838 + } 21.839 + continue; 21.840 + case 'o': 21.841 + base = 8; 21.842 + break; 21.843 + case 'x': 21.844 + case 'X': 21.845 + base = 16; 21.846 + break; 21.847 + case 'i': 21.848 + base = 0; 21.849 + case 'd': 21.850 + is_sign = 1; 21.851 + case 'u': 21.852 + break; 21.853 + case '%': 21.854 + /* looking for '%' in str */ 21.855 + if (*str++ != '%') 21.856 + return num; 21.857 + continue; 21.858 + default: 21.859 + /* invalid format; stop here */ 21.860 + return num; 21.861 + } 21.862 21.863 - if (!ul) 21.864 + /* have some sort of integer conversion. 21.865 + * first, skip white space in buffer. 21.866 + */ 21.867 + while (isspace(*str)) 21.868 + str++; 21.869 + 21.870 + digit = *str; 21.871 + if (is_sign && digit == '-') 21.872 + digit = *(str + 1); 21.873 + 21.874 + if (!digit 21.875 + || (base == 16 && !isxdigit(digit)) 21.876 + || (base == 10 && !isdigit(digit)) 21.877 + || (base == 8 && (!isdigit(digit) || digit > '7')) 21.878 + || (base == 0 && !isdigit(digit))) 21.879 break; 21.880 21.881 - for (tmp = 0; *p;) { 21.882 - n = *p++; 21.883 - if (ul & (1 << (n - 1))) { 21.884 - PCHAR(tmp ? ',' : '<'); 21.885 - for (; (n = *p) > ' '; ++p) 21.886 - PCHAR(n); 21.887 - tmp = 1; 21.888 - } else 21.889 - for (; *p > ' '; ++p) 21.890 - continue; 21.891 + switch(qualifier) { 21.892 + case 'H': /* that's 'hh' in format */ 21.893 + if (is_sign) { 21.894 + signed char *s = (signed char *) va_arg(args,signed char *); 21.895 + *s = (signed char) simple_strtol(str,&next,base); 21.896 + } else { 21.897 + unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); 21.898 + *s = (unsigned char) simple_strtoul(str, &next, base); 21.899 } 21.900 - if (tmp) 21.901 - PCHAR('>'); 21.902 break; 21.903 - case 'c': 21.904 - PCHAR(va_arg(ap, int)); 21.905 + case 'h': 21.906 + if (is_sign) { 21.907 + short *s = (short *) va_arg(args,short *); 21.908 + *s = (short) simple_strtol(str,&next,base); 21.909 + } else { 21.910 + unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); 21.911 + *s = (unsigned short) simple_strtoul(str, &next, base); 21.912 + } 21.913 break; 21.914 - case 'D': 21.915 - up = va_arg(ap, u_char *); 21.916 - p = va_arg(ap, char *); 21.917 - if (!width) 21.918 - width = 16; 21.919 - while(width--) { 21.920 - PCHAR(hex2ascii(*up >> 4)); 21.921 - PCHAR(hex2ascii(*up & 0x0f)); 21.922 - up++; 21.923 - if (width) 21.924 - for (q=p;*q;q++) 21.925 - PCHAR(*q); 21.926 + case 'l': 21.927 + if (is_sign) { 21.928 + long *l = (long *) va_arg(args,long *); 21.929 + *l = simple_strtol(str,&next,base); 21.930 + } else { 21.931 + unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); 21.932 + *l = simple_strtoul(str,&next,base); 21.933 + } 21.934 + break; 21.935 + case 'L': 21.936 + if (is_sign) { 21.937 + long long *l = (long long*) va_arg(args,long long *); 21.938 + *l = simple_strtoll(str,&next,base); 21.939 + } else { 21.940 + unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); 21.941 + *l = simple_strtoull(str,&next,base); 21.942 } 21.943 break; 21.944 - case 'd': 21.945 - if (qflag) 21.946 - uq = va_arg(ap, quad_t); 21.947 - else if (lflag) 21.948 - ul = va_arg(ap, long); 21.949 - else 21.950 - ul = va_arg(ap, int); 21.951 - sign = 1; 21.952 - base = 10; 21.953 - goto number; 21.954 - case 'l': 21.955 - if (lflag) { 21.956 - lflag = 0; 21.957 - qflag = 1; 21.958 - } else 21.959 - lflag = 1; 21.960 - goto reswitch; 21.961 - case 'o': 21.962 - if (qflag) 21.963 - uq = va_arg(ap, u_quad_t); 21.964 - else if (lflag) 21.965 - ul = va_arg(ap, u_long); 21.966 - else 21.967 - ul = va_arg(ap, u_int); 21.968 - base = 8; 21.969 - goto nosign; 21.970 - case 'p': 21.971 - ul = (uintptr_t)va_arg(ap, void *); 21.972 - base = 16; 21.973 - sharpflag = 0; 21.974 - padc = '0'; 21.975 - width = sizeof(uintptr_t)*2; 21.976 - goto nosign; 21.977 - case 'q': 21.978 - qflag = 1; 21.979 - goto reswitch; 21.980 - case 'n': 21.981 - case 'r': 21.982 - if (qflag) 21.983 - uq = va_arg(ap, u_quad_t); 21.984 - else if (lflag) 21.985 - ul = va_arg(ap, u_long); 21.986 - else 21.987 - ul = sign ? 21.988 - (u_long)va_arg(ap, int) : va_arg(ap, u_int); 21.989 - base = radix; 21.990 - goto number; 21.991 - case 's': 21.992 - p = va_arg(ap, char *); 21.993 - if (p == NULL) 21.994 - p = "(null)"; 21.995 - if (!dot) 21.996 - n = strlen (p); 21.997 - else 21.998 - for (n = 0; n < dwidth && p[n]; n++) 21.999 - continue; 21.1000 - 21.1001 - width -= n; 21.1002 - 21.1003 - if (!ladjust && width > 0) 21.1004 - while (width--) 21.1005 - PCHAR(padc); 21.1006 - while (n--) 21.1007 - PCHAR(*p++); 21.1008 - if (ladjust && width > 0) 21.1009 - while (width--) 21.1010 - PCHAR(padc); 21.1011 - break; 21.1012 - case 'u': 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 = 10; 21.1020 - goto nosign; 21.1021 - case 'x': 21.1022 - case 'X': 21.1023 - if (qflag) 21.1024 - uq = va_arg(ap, u_quad_t); 21.1025 - else if (lflag) 21.1026 - ul = va_arg(ap, u_long); 21.1027 - else 21.1028 - ul = va_arg(ap, u_int); 21.1029 - base = 16; 21.1030 - goto nosign; 21.1031 + case 'Z': 21.1032 case 'z': 21.1033 - if (qflag) 21.1034 - uq = va_arg(ap, u_quad_t); 21.1035 - else if (lflag) 21.1036 - ul = va_arg(ap, u_long); 21.1037 - else 21.1038 - ul = sign ? 21.1039 - (u_long)va_arg(ap, int) : va_arg(ap, u_int); 21.1040 - base = 16; 21.1041 - goto number; 21.1042 -nosign: sign = 0; 21.1043 -number: 21.1044 - if (qflag) { 21.1045 - if (sign && (quad_t)uq < 0) { 21.1046 - neg = 1; 21.1047 - uq = -(quad_t)uq; 21.1048 - } 21.1049 - p = ksprintqn(nbuf, uq, base, &tmp); 21.1050 + { 21.1051 + size_t *s = (size_t*) va_arg(args,size_t*); 21.1052 + *s = (size_t) simple_strtoul(str,&next,base); 21.1053 + } 21.1054 + break; 21.1055 + default: 21.1056 + if (is_sign) { 21.1057 + int *i = (int *) va_arg(args, int*); 21.1058 + *i = (int) simple_strtol(str,&next,base); 21.1059 } else { 21.1060 - if (sign && (long)ul < 0) { 21.1061 - neg = 1; 21.1062 - ul = -(long)ul; 21.1063 - } 21.1064 - p = ksprintn(nbuf, ul, base, &tmp); 21.1065 - } 21.1066 - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { 21.1067 - if (base == 8) 21.1068 - tmp++; 21.1069 - else if (base == 16) 21.1070 - tmp += 2; 21.1071 + unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); 21.1072 + *i = (unsigned int) simple_strtoul(str,&next,base); 21.1073 } 21.1074 - if (neg) 21.1075 - tmp++; 21.1076 - 21.1077 - if (!ladjust && width && (width -= tmp) > 0) 21.1078 - while (width--) 21.1079 - PCHAR(padc); 21.1080 - if (neg) 21.1081 - PCHAR('-'); 21.1082 - if (sharpflag && (qflag ? uq != 0 : ul != 0)) { 21.1083 - if (base == 8) { 21.1084 - PCHAR('0'); 21.1085 - } else if (base == 16) { 21.1086 - PCHAR('0'); 21.1087 - PCHAR('x'); 21.1088 - } 21.1089 - } 21.1090 - 21.1091 - while (*p) 21.1092 - PCHAR(*p--); 21.1093 - 21.1094 - if (ladjust && width && (width -= tmp) > 0) 21.1095 - while (width--) 21.1096 - PCHAR(padc); 21.1097 - 21.1098 - break; 21.1099 - default: 21.1100 - PCHAR('%'); 21.1101 - if (lflag) 21.1102 - PCHAR('l'); 21.1103 - PCHAR(ch); 21.1104 break; 21.1105 } 21.1106 + num++; 21.1107 + 21.1108 + if (!next) 21.1109 + break; 21.1110 + str = next; 21.1111 } 21.1112 -#undef PCHAR 21.1113 + return num; 21.1114 } 21.1115 21.1116 +/** 21.1117 + * sscanf - Unformat a buffer into a list of arguments 21.1118 + * @buf: input buffer 21.1119 + * @fmt: formatting of buffer 21.1120 + * @...: resulting arguments 21.1121 + */ 21.1122 +int sscanf(const char * buf, const char * fmt, ...) 21.1123 +{ 21.1124 + va_list args; 21.1125 + int i; 21.1126 + 21.1127 + va_start(args,fmt); 21.1128 + i = vsscanf(buf,fmt,args); 21.1129 + va_end(args); 21.1130 + return i; 21.1131 +} 21.1132 + 21.1133 +
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) (®s->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 +}
33.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 09 08:56:38 2005 +0000 33.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Fri Sep 09 10:20:25 2005 +0000 33.3 @@ -776,8 +776,8 @@ static void blkif_completion(struct blk_ 33.4 { 33.5 int i; 33.6 for (i = 0; i < s->req.nr_segments; i++) 33.7 - gnttab_free_grant_reference( 33.8 - blkif_gref_from_fas(s->req.frame_and_sects[i])); 33.9 + gnttab_end_foreign_access( 33.10 + blkif_gref_from_fas(s->req.frame_and_sects[i]), 0); 33.11 } 33.12 33.13 /*
35.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Fri Sep 09 08:56:38 2005 +0000 35.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Fri Sep 09 10:20:25 2005 +0000 35.3 @@ -29,136 +29,163 @@ 35.4 #include <linux/skbuff.h> 35.5 #include <net/dst.h> 35.6 35.7 +static int nloopbacks = 1; 35.8 +module_param(nloopbacks, int, 0); 35.9 +MODULE_PARM_DESC(nloopbacks, "Number of netback-loopback devices to create"); 35.10 + 35.11 struct net_private { 35.12 - struct net_device *loopback_dev; 35.13 - struct net_device_stats stats; 35.14 + struct net_device *loopback_dev; 35.15 + struct net_device_stats stats; 35.16 }; 35.17 35.18 static int loopback_open(struct net_device *dev) 35.19 { 35.20 - struct net_private *np = netdev_priv(dev); 35.21 - memset(&np->stats, 0, sizeof(np->stats)); 35.22 - netif_start_queue(dev); 35.23 - return 0; 35.24 + struct net_private *np = netdev_priv(dev); 35.25 + memset(&np->stats, 0, sizeof(np->stats)); 35.26 + netif_start_queue(dev); 35.27 + return 0; 35.28 } 35.29 35.30 static int loopback_close(struct net_device *dev) 35.31 { 35.32 - netif_stop_queue(dev); 35.33 - return 0; 35.34 + netif_stop_queue(dev); 35.35 + return 0; 35.36 } 35.37 35.38 static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev) 35.39 { 35.40 - struct net_private *np = netdev_priv(dev); 35.41 + struct net_private *np = netdev_priv(dev); 35.42 35.43 - dst_release(skb->dst); 35.44 - skb->dst = NULL; 35.45 + dst_release(skb->dst); 35.46 + skb->dst = NULL; 35.47 35.48 - skb_orphan(skb); 35.49 + skb_orphan(skb); 35.50 35.51 - np->stats.tx_bytes += skb->len; 35.52 - np->stats.tx_packets++; 35.53 + np->stats.tx_bytes += skb->len; 35.54 + np->stats.tx_packets++; 35.55 35.56 - /* Switch to loopback context. */ 35.57 - dev = np->loopback_dev; 35.58 - np = netdev_priv(dev); 35.59 + /* Switch to loopback context. */ 35.60 + dev = np->loopback_dev; 35.61 + np = netdev_priv(dev); 35.62 35.63 - np->stats.rx_bytes += skb->len; 35.64 - np->stats.rx_packets++; 35.65 + np->stats.rx_bytes += skb->len; 35.66 + np->stats.rx_packets++; 35.67 35.68 - if ( skb->ip_summed == CHECKSUM_HW ) 35.69 - { 35.70 - /* Defer checksum calculation. */ 35.71 - skb->proto_csum_blank = 1; 35.72 - /* Must be a local packet: assert its integrity. */ 35.73 - skb->proto_csum_valid = 1; 35.74 - } 35.75 + if (skb->ip_summed == CHECKSUM_HW) { 35.76 + /* Defer checksum calculation. */ 35.77 + skb->proto_csum_blank = 1; 35.78 + /* Must be a local packet: assert its integrity. */ 35.79 + skb->proto_csum_valid = 1; 35.80 + } 35.81 35.82 - skb->ip_summed = skb->proto_csum_valid ? 35.83 - CHECKSUM_UNNECESSARY : CHECKSUM_NONE; 35.84 + skb->ip_summed = skb->proto_csum_valid ? 35.85 + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; 35.86 35.87 - skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */ 35.88 - skb->protocol = eth_type_trans(skb, dev); 35.89 - skb->dev = dev; 35.90 - dev->last_rx = jiffies; 35.91 - netif_rx(skb); 35.92 + skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */ 35.93 + skb->protocol = eth_type_trans(skb, dev); 35.94 + skb->dev = dev; 35.95 + dev->last_rx = jiffies; 35.96 + netif_rx(skb); 35.97 35.98 - return 0; 35.99 + return 0; 35.100 } 35.101 35.102 static struct net_device_stats *loopback_get_stats(struct net_device *dev) 35.103 { 35.104 - struct net_private *np = netdev_priv(dev); 35.105 - return &np->stats; 35.106 + struct net_private *np = netdev_priv(dev); 35.107 + return &np->stats; 35.108 } 35.109 35.110 static void loopback_construct(struct net_device *dev, struct net_device *lo) 35.111 { 35.112 - struct net_private *np = netdev_priv(dev); 35.113 + struct net_private *np = netdev_priv(dev); 35.114 + 35.115 + np->loopback_dev = lo; 35.116 35.117 - np->loopback_dev = lo; 35.118 + dev->open = loopback_open; 35.119 + dev->stop = loopback_close; 35.120 + dev->hard_start_xmit = loopback_start_xmit; 35.121 + dev->get_stats = loopback_get_stats; 35.122 + 35.123 + dev->tx_queue_len = 0; 35.124 + 35.125 + dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX; 35.126 35.127 - dev->open = loopback_open; 35.128 - dev->stop = loopback_close; 35.129 - dev->hard_start_xmit = loopback_start_xmit; 35.130 - dev->get_stats = loopback_get_stats; 35.131 + /* 35.132 + * We do not set a jumbo MTU on the interface. Otherwise the network 35.133 + * stack will try to send large packets that will get dropped by the 35.134 + * Ethernet bridge (unless the physical Ethernet interface is 35.135 + * configured to transfer jumbo packets). If a larger MTU is desired 35.136 + * then the system administrator can specify it using the 'ifconfig' 35.137 + * command. 35.138 + */ 35.139 + /*dev->mtu = 16*1024;*/ 35.140 +} 35.141 35.142 - dev->tx_queue_len = 0; 35.143 +static int __init make_loopback(int i) 35.144 +{ 35.145 + struct net_device *dev1, *dev2; 35.146 + char dev_name[IFNAMSIZ]; 35.147 + int err = -ENOMEM; 35.148 35.149 - dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX; 35.150 + sprintf(dev_name, "vif0.%d", i); 35.151 + dev1 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup); 35.152 + sprintf(dev_name, "veth%d", i); 35.153 + dev2 = alloc_netdev(sizeof(struct net_private), dev_name, ether_setup); 35.154 + if ((dev1 == NULL) || (dev2 == NULL)) 35.155 + goto fail; 35.156 + 35.157 + loopback_construct(dev1, dev2); 35.158 + loopback_construct(dev2, dev1); 35.159 + 35.160 + dev1->features |= NETIF_F_NO_CSUM; 35.161 + dev2->features |= NETIF_F_IP_CSUM; 35.162 35.163 - /* 35.164 - * We do not set a jumbo MTU on the interface. Otherwise the network 35.165 - * stack will try to send large packets that will get dropped by the 35.166 - * Ethernet bridge (unless the physical Ethernet interface is configured 35.167 - * to transfer jumbo packets). If a larger MTU is desired then the system 35.168 - * administrator can specify it using the 'ifconfig' command. 35.169 - */ 35.170 - /*dev->mtu = 16*1024;*/ 35.171 + /* 35.172 + * Initialise a dummy MAC address for the 'dummy backend' interface. We 35.173 + * choose the numerically largest non-broadcast address to prevent the 35.174 + * address getting stolen by an Ethernet bridge for STP purposes. 35.175 + */ 35.176 + memset(dev1->dev_addr, 0xFF, ETH_ALEN); 35.177 + dev1->dev_addr[0] &= ~0x01; 35.178 + 35.179 + if ((err = register_netdev(dev1)) != 0) 35.180 + goto fail; 35.181 + 35.182 + if ((err = register_netdev(dev2)) != 0) { 35.183 + unregister_netdev(dev1); 35.184 + goto fail; 35.185 + } 35.186 + 35.187 + return 0; 35.188 + 35.189 + fail: 35.190 + if (dev1 != NULL) 35.191 + kfree(dev1); 35.192 + if (dev2 != NULL) 35.193 + kfree(dev2); 35.194 + return err; 35.195 } 35.196 35.197 static int __init loopback_init(void) 35.198 { 35.199 - struct net_device *dev1, *dev2; 35.200 - int err = -ENOMEM; 35.201 - 35.202 - dev1 = alloc_netdev(sizeof(struct net_private), "vif0.0", ether_setup); 35.203 - dev2 = alloc_netdev(sizeof(struct net_private), "veth0", ether_setup); 35.204 - if ( (dev1 == NULL) || (dev2 == NULL) ) 35.205 - goto fail; 35.206 - 35.207 - loopback_construct(dev1, dev2); 35.208 - loopback_construct(dev2, dev1); 35.209 - 35.210 - dev1->features |= NETIF_F_NO_CSUM; 35.211 - dev2->features |= NETIF_F_IP_CSUM; 35.212 + int i, err = 0; 35.213 35.214 - /* 35.215 - * Initialise a dummy MAC address for the 'dummy backend' interface. We 35.216 - * choose the numerically largest non-broadcast address to prevent the 35.217 - * address getting stolen by an Ethernet bridge for STP purposes. 35.218 - */ 35.219 - memset(dev1->dev_addr, 0xFF, ETH_ALEN); 35.220 - dev1->dev_addr[0] &= ~0x01; 35.221 - 35.222 - if ( (err = register_netdev(dev1)) != 0 ) 35.223 - goto fail; 35.224 + for (i = 0; i < nloopbacks; i++) 35.225 + if ((err = make_loopback(i)) != 0) 35.226 + break; 35.227 35.228 - if ( (err = register_netdev(dev2)) != 0 ) 35.229 - { 35.230 - unregister_netdev(dev1); 35.231 - goto fail; 35.232 - } 35.233 - 35.234 - return 0; 35.235 - 35.236 - fail: 35.237 - if ( dev1 != NULL ) 35.238 - kfree(dev1); 35.239 - if ( dev2 != NULL ) 35.240 - kfree(dev2); 35.241 - return err; 35.242 + return err; 35.243 } 35.244 35.245 module_init(loopback_init); 35.246 + 35.247 +/* 35.248 + * Local variables: 35.249 + * c-file-style: "linux" 35.250 + * indent-tabs-mode: t 35.251 + * c-indent-level: 8 35.252 + * c-basic-offset: 8 35.253 + * tab-width: 8 35.254 + * End: 35.255 + */
50.1 --- a/tools/python/xen/lowlevel/xs/xs.c Fri Sep 09 08:56:38 2005 +0000 50.2 +++ b/tools/python/xen/lowlevel/xs/xs.c Fri Sep 09 10:20:25 2005 +0000 50.3 @@ -93,7 +93,9 @@ static PyObject *xspy_read(PyObject *sel 50.4 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 50.5 &path)) 50.6 goto exit; 50.7 + Py_BEGIN_ALLOW_THREADS 50.8 xsval = xs_read(xh, path, &xsval_n); 50.9 + Py_END_ALLOW_THREADS 50.10 if (!xsval) { 50.11 val = pyvalue_int(0); 50.12 goto exit; 50.13 @@ -140,7 +142,9 @@ static PyObject *xspy_write(PyObject *se 50.14 flags |= O_CREAT; 50.15 if (excl) 50.16 flags |= O_EXCL; 50.17 + Py_BEGIN_ALLOW_THREADS 50.18 xsval = xs_write(xh, path, data, data_n, flags); 50.19 + Py_END_ALLOW_THREADS 50.20 val = pyvalue_int(xsval); 50.21 exit: 50.22 return val; 50.23 @@ -170,7 +174,9 @@ static PyObject *xspy_ls(PyObject *self, 50.24 goto exit; 50.25 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 50.26 goto exit; 50.27 + Py_BEGIN_ALLOW_THREADS 50.28 xsval = xs_directory(xh, path, &xsval_n); 50.29 + Py_END_ALLOW_THREADS 50.30 if (!xsval) { 50.31 val = pyvalue_int(0); 50.32 goto exit; 50.33 @@ -204,7 +210,9 @@ static PyObject *xspy_mkdir(PyObject *se 50.34 goto exit; 50.35 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 50.36 goto exit; 50.37 + Py_BEGIN_ALLOW_THREADS 50.38 xsval = xs_mkdir(xh, path); 50.39 + Py_END_ALLOW_THREADS 50.40 val = pyvalue_int(xsval); 50.41 exit: 50.42 return val; 50.43 @@ -232,7 +240,9 @@ static PyObject *xspy_rm(PyObject *self, 50.44 goto exit; 50.45 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 50.46 goto exit; 50.47 + Py_BEGIN_ALLOW_THREADS 50.48 xsval = xs_rm(xh, path); 50.49 + Py_END_ALLOW_THREADS 50.50 val = pyvalue_int(xsval); 50.51 exit: 50.52 return val; 50.53 @@ -263,7 +273,9 @@ static PyObject *xspy_get_permissions(Py 50.54 goto exit; 50.55 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 50.56 goto exit; 50.57 + Py_BEGIN_ALLOW_THREADS 50.58 perms = xs_get_permissions(xh, path, &perms_n); 50.59 + Py_END_ALLOW_THREADS 50.60 if (!perms) { 50.61 PyErr_SetFromErrno(PyExc_RuntimeError); 50.62 goto exit; 50.63 @@ -339,7 +351,9 @@ static PyObject *xspy_set_permissions(Py 50.64 if (p_write) 50.65 xsperms[i].perms |= XS_PERM_WRITE; 50.66 } 50.67 + Py_BEGIN_ALLOW_THREADS 50.68 xsval = xs_set_permissions(xh, path, xsperms, xsperms_n); 50.69 + Py_END_ALLOW_THREADS 50.70 val = pyvalue_int(xsval); 50.71 exit: 50.72 Py_XDECREF(tuple0); 50.73 @@ -381,7 +395,9 @@ static PyObject *xspy_watch(PyObject *se 50.74 goto exit; 50.75 Py_INCREF(token); 50.76 sprintf(token_str, "%li", (unsigned long)token); 50.77 + Py_BEGIN_ALLOW_THREADS 50.78 xsval = xs_watch(xh, path, token_str); 50.79 + Py_END_ALLOW_THREADS 50.80 if (!xsval) { 50.81 val = PyErr_SetFromErrno(PyExc_RuntimeError); 50.82 Py_DECREF(token); 50.83 @@ -429,7 +445,9 @@ static PyObject *xspy_read_watch(PyObjec 50.84 goto exit; 50.85 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec)) 50.86 goto exit; 50.87 + Py_BEGIN_ALLOW_THREADS 50.88 xsval = xs_read_watch(xh); 50.89 + Py_END_ALLOW_THREADS 50.90 if (!xsval) { 50.91 val = PyErr_SetFromErrno(PyExc_RuntimeError); 50.92 goto exit; 50.93 @@ -479,7 +497,9 @@ static PyObject *xspy_acknowledge_watch( 50.94 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &token)) 50.95 goto exit; 50.96 sprintf(token_str, "%li", (unsigned long)token); 50.97 + Py_BEGIN_ALLOW_THREADS 50.98 xsval = xs_acknowledge_watch(xh, token_str); 50.99 + Py_END_ALLOW_THREADS 50.100 if (!xsval) { 50.101 val = PyErr_SetFromErrno(PyExc_RuntimeError); 50.102 goto exit; 50.103 @@ -519,7 +539,9 @@ static PyObject *xspy_unwatch(PyObject * 50.104 &token)) 50.105 goto exit; 50.106 sprintf(token_str, "%li", (unsigned long)token); 50.107 + Py_BEGIN_ALLOW_THREADS 50.108 xsval = xs_unwatch(xh, path, token_str); 50.109 + Py_END_ALLOW_THREADS 50.110 if (!xsval) 50.111 val = PyErr_SetFromErrno(PyExc_RuntimeError); 50.112 else { 50.113 @@ -561,7 +583,9 @@ static PyObject *xspy_transaction_start( 50.114 goto exit; 50.115 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path)) 50.116 goto exit; 50.117 + Py_BEGIN_ALLOW_THREADS 50.118 xsval = xs_transaction_start(xh, path); 50.119 + Py_END_ALLOW_THREADS 50.120 val = pyvalue_int(xsval); 50.121 exit: 50.122 return val; 50.123 @@ -591,7 +615,9 @@ static PyObject *xspy_transaction_end(Py 50.124 goto exit; 50.125 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort)) 50.126 goto exit; 50.127 + Py_BEGIN_ALLOW_THREADS 50.128 xsval = xs_transaction_end(xh, abort); 50.129 + Py_END_ALLOW_THREADS 50.130 val = pyvalue_int(xsval); 50.131 exit: 50.132 return val; 50.133 @@ -627,7 +653,9 @@ static PyObject *xspy_introduce_domain(P 50.134 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 50.135 &dom, &page, &port, &path)) 50.136 goto exit; 50.137 + Py_BEGIN_ALLOW_THREADS 50.138 xsval = xs_introduce_domain(xh, dom, page, port, path); 50.139 + Py_END_ALLOW_THREADS 50.140 val = pyvalue_int(xsval); 50.141 exit: 50.142 return val; 50.143 @@ -658,7 +686,9 @@ static PyObject *xspy_release_domain(PyO 50.144 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, 50.145 &dom)) 50.146 goto exit; 50.147 + Py_BEGIN_ALLOW_THREADS 50.148 xsval = xs_release_domain(xh, dom); 50.149 + Py_END_ALLOW_THREADS 50.150 val = pyvalue_int(xsval); 50.151 exit: 50.152 return val; 50.153 @@ -718,7 +748,9 @@ static PyObject *xspy_shutdown(PyObject 50.154 goto exit; 50.155 if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec)) 50.156 goto exit; 50.157 + Py_BEGIN_ALLOW_THREADS 50.158 xsval = xs_shutdown(xh); 50.159 + Py_END_ALLOW_THREADS 50.160 val = pyvalue_int(xsval); 50.161 exit: 50.162 return val;