45 | /*
46 | * block current thread until comp is posted
47 | */
48 | void guk_wait_for_completion(struct completion *comp)
49 | {
50 | unsigned long flags;
51 | spin_lock_irqsave(&comp->wait.lock, flags);
52 | rmb();
53 | if(!comp->done) {
54 | DEFINE_WAIT(wait);
55 | add_wait_queue(&comp->wait, &wait);
56 | do {
57 | block(current);
58 | spin_unlock_irqrestore(&comp->wait.lock, flags);
59 | schedule();
60 | spin_lock_irqsave(&comp->wait.lock, flags);
61 | rmb();
62 | } while(!comp->done);
63 | remove_wait_queue(&wait);
64 | }
65 | comp->done--;
66 | spin_unlock_irqrestore(&comp->wait.lock, flags);
67 | }
68 |
69 | /*
70 | * post completion comp; release all threads waiting on comp
71 | */
72 | void guk_complete_all(struct completion *comp)
73 | {
74 | unsigned long flags;
75 | spin_lock_irqsave(&comp->wait.lock, flags);
76 | comp->done = UINT_MAX/2;
77 | wmb();
78 | __wake_up(&comp->wait);
79 | spin_unlock_irqrestore(&comp->wait.lock, flags);
80 | }
81 |
82 | /*
83 | * post completion comp; release only the first thread waiting on comp
84 | */
85 | void guk_complete(struct completion *comp)
86 | {
87 | unsigned long flags;
88 | spin_lock_irqsave(&comp->wait.lock, flags);
89 |
90 | /*
91 | * instead of incrementing we set it to one here. i.e. the waiter only sees
92 | * the last notify. this is different to the linux version of complete
93 | */
94 | comp->done = 1;
95 | wmb();
96 | __wake_up(&comp->wait);
97 | spin_unlock_irqrestore(&comp->wait.lock, flags);
98 |
99 | }
100 |
101 | struct completion *guk_create_completion(void) {
102 | struct completion *comp = (struct completion *)xmalloc(struct completion);
103 | init_completion(comp);
104 | return comp;
105 | }
106 |
107 | void guk_delete_completion(struct completion *completion) {
108 | free(completion);
109 | }
110 |
111 |
--------------------------------------------------------------------------------
/docs/bootstrap.html:
--------------------------------------------------------------------------------
1 |
25 |
26 |
27 | GUK: Bootstrap
28 |
29 | GUK: Bootstrap
30 | Introduction
31 | GUK is normally part of a larger subsystem but can be run stand-alone, e.g.:
32 |
33 | # xm create -c domain_config
34 | Using config file "./domain_config".
35 | Started domain GUK-root
36 | time: 70673721792504 periodic_thread
37 | ...
38 |
39 | The microkernel gets the startup information from the Xen hypervisor
40 | and provides a set of callbacks to it. Bootstrapping continues by
41 | setting up the event channels (interrupt handlers) and initializing
42 | pagetables, timers, console and the scheduler. If SMP is enabled,
43 | i.e. vcpus > 1 in the domain config file, the remaining cpus are
44 | activated after the scheduler is initialized. If the BRIDGE
45 | environment variable is set to the name of the network bridge, the domain
46 | will be configured with a network interface.
47 |
48 | To support null pointer checks, the page at virtual address 0 is then
49 | mapped out.
50 |
51 | The microkernel services are then started, these are:
52 |
53 | - Network (netfront)
54 |
- Block device (blk_front)
55 |
- Sibling guest file system (fs-front)
56 |
- Shutdown (suspend/resume)
57 |
58 |
59 | If debugging is enabled, the db-backend thread is created, which will
60 | wait for a connection from the debugging front-end before continuing
61 | the microkernel. Otherwise, the function guk_app_main is invoked. The
62 | microkernel provides a weak definition of this function which creates
63 | a thread that prints the time (in nanoseconds) to both the console and
64 | the Xen console every 500 ms. The network is handled in a similar
65 | way, the function guk_net_app_main being called
66 | with the MAC address, or NULL if no network is configured. Incoming packets
67 | invoke the guk_netif_rx method. Both of these methods are given
68 | weak definitions in GUK, the default guk_netif_rx just prints a
69 | message to the console. The
70 |
71 | When the microkernel is used as part of
72 | a larger system, that system must provide a strong definition of
73 | guk_app_main that will override the weak definition. Note that any
74 | definition of guk_app_main must create a thread to contain its
75 | activity and return, at which point the microkernel switches to the
76 | idle thread for VCPU 0. A similar override should be used for the network methods.
77 |
78 | The startup can be traced by placing -XX:GUKTrace:startup in the
79 | extra command line argument.
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/include/guk/fs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | * Sibling guest file system support.
25 |
26 | * Author: Grzegorz Milos
27 | * Changes: Mick Jordan
28 | */
29 | #ifndef __FS_H__
30 | #define __FS_H__
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | #define FSTEST_CMDLINE "fstest"
38 |
39 | struct fs_import {
40 | domid_t dom_id; /* dom id of the exporting domain */
41 | uint16_t export_id; /* export id (exporting dom specific) */
42 | char *path; /* path of exported fs */
43 | uint16_t import_id; /* import id (specific to this domain) */
44 | struct list_head list; /* list of all imports */
45 | unsigned int nr_entries; /* Number of entries in rings & request
46 | array */
47 | struct fsif_front_ring ring; /* frontend ring (contains shared ring) */
48 | int gnt_ref; /* grant reference to the shared ring */
49 | unsigned int local_port; /* local event channel port */
50 | char *backend; /* XenBus location of the backend */
51 | struct fs_request *requests; /* Table of requests */
52 | unsigned short *freelist; /* List of free request ids */
53 | };
54 |
55 |
56 | int guk_fs_open(struct fs_import *, const char *file, int flags);
57 | int guk_fs_close(struct fs_import *, int fd);
58 | ssize_t guk_fs_read(struct fs_import *, int fd, void *buf, ssize_t len, ssize_t offset);
59 | ssize_t guk_fs_write(struct fs_import *, int fd, const void *buf, ssize_t len, ssize_t offset);
60 | int guk_fs_fstat(struct fs_import *, int fd, struct fsif_stat *buf);
61 | int guk_fs_stat(struct fs_import *, const char *file, struct fsif_stat *buf);
62 | int guk_fs_truncate(struct fs_import *, int fd, int64_t length);
63 | int guk_fs_remove(struct fs_import *, char *file);
64 | int guk_fs_rename(struct fs_import *, char *old_file_name, char *new_file_name);
65 | int guk_fs_create(struct fs_import *, char *name, int8_t directory, int32_t mode);
66 | int guk_fs_fchmod(struct fs_import *, int fd, int32_t mode);
67 | int64_t guk_fs_space(struct fs_import *, char *location);
68 | int guk_fs_sync(struct fs_import *, int fd);
69 | char** guk_fs_list(struct fs_import *, char *name, int32_t offset, int32_t *nr_files, int *has_more);
70 | char* guk_fs_import_path(struct fs_import *);
71 |
72 | struct list_head *guk_fs_get_imports(void);
73 | struct fs_import *guk_fs_get_next(struct fs_import *);
74 |
75 | #endif
76 |
--------------------------------------------------------------------------------
/tools/db-front/32bit/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | #
5 | # This code is free software; you can redistribute it and/or modify it
6 | # under the terms of the GNU General Public License version 2 only, as
7 | # published by the Free Software Foundation.
8 | #
9 | # This code is distributed in the hope that it will be useful, but WITHOUT
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | # version 2 for more details (a copy is included in the LICENSE file that
13 | # accompanied this code).
14 | #
15 | # You should have received a copy of the GNU General Public License version
16 | # 2 along with this work; if not, write to the Free Software Foundation,
17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | #
19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | # or visit www.oracle.com if you need additional information or have any
21 | # questions.
22 | #
23 | # The standard target of this build is a 64-bit library that will be
24 | # linked with the Maxine Inspector.
25 | #
26 | # The build also produces a 32-bit library that can run in a 32-bit dom0
27 | # and an executable 32-bit program, db-frontend, that accepts a TCP connection
28 | # from a 64-bit remote system (running the Maxine Inspector).
29 | # The 32-bit versions of libxenctrl.so, libxenstore.so, libxenguest.so must
30 | # be available in the XEN_LIBS32
31 | #
32 | ifndef XEN_ROOT
33 | $(error "Must set XEN_ROOT environment variable to the root of Xen tree")
34 | endif
35 |
36 | OSNAME ?= $(shell uname -s)
37 | ifneq ($(OSNAME),Linux)
38 | $(error "db-front can only be built and installed in a Linux guest")
39 | endif
40 |
41 | OSARCH ?= $(shell arch)
42 | ifneq ($(OSARCH),x86_64)
43 | $(error "db-front must be compiled on a 64-bit system")
44 | endif
45 |
46 | ifndef XEN_LIBS32
47 | $(error "Must set XEN_LIBS32 to directory containing 32 bit versions of libxenstore...")
48 | endif
49 |
50 | include $(XEN_ROOT)/tools/Rules.mk
51 |
52 | INCLUDES += -I.
53 |
54 | IBIN = db-frontend
55 | LIB = libguk_db.so
56 |
57 | MAJOR = 1.0
58 | MINOR = 0
59 |
60 | CFLAGS = -m32
61 | CFLAGS += -Werror
62 | CFLAGS += -Wno-unused
63 | CFLAGS += -fno-strict-aliasing
64 | CFLAGS += -I $(XEN_ROOT)/tools/include -I $(XEN_LIBXC) -I $(XEN_XENSTORE)
65 | CFLAGS += -I.. $(INCLUDES)
66 | CFLAGS += -D_GNU_SOURCE
67 |
68 | # Get gcc to generate the dependencies for us.
69 | CFLAGS += -Wp,-MD,.$(@F).d
70 | DEPS = .*.d
71 |
72 | LIBS := -L. -L$(XEN_LIBS32) -lxenctrl -lxenstore
73 |
74 | SRCS := db-frontend.c db-xenbus.c
75 | OBJS := db-xenbus.o
76 | PIC_OBJS := db-xenbus.opic db-frontend.opic
77 |
78 | all: links $(LIB) $(LIB).$(MAJOR) $(LIB).$(MAJOR).$(MINOR)
79 |
80 | .PHONY: links
81 | links: $(ARCH_LINKS)
82 | [ -e xen ] || ln -sf $(XEN_ROOT)/xen/include/public xen
83 | [ -e db-xenbus.c ] || ln -sf ../db-xenbus.c
84 | [ -e db-frontend.c ] || ln -sf ../db-frontend.c
85 |
86 | $(LIB): $(LIB).$(MAJOR)
87 | ln -sf $< $@
88 |
89 | $(LIB).$(MAJOR): $(LIB).$(MAJOR).$(MINOR)
90 | ln -sf $< $@
91 |
92 | $(LIB).$(MAJOR).$(MINOR): $(PIC_OBJS)
93 | $(CC) $(CFLAGS) $(LIBS) -Wl,$(SONAME_LDFLAG) -Wl,$(LIB).$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^
94 |
95 |
96 | install: all
97 | $(INSTALL_PROG) $(LIB).$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
98 | ln -sf $(LIB).$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/$(LIB).$(MAJOR)
99 | ln -sf $(LIB).$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/$(LIB)
100 |
101 | clean:
102 | rm -rf *.o *.opic *~ $(DEPS) xen $(LIB)*
103 |
104 | .PHONY: clean install
105 |
106 | -include $(DEPS)
107 |
--------------------------------------------------------------------------------
/include/guk/blk_front.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | * Author: Harald Roeck
25 | */
26 | #ifndef _BLK_FRONT_H_
27 | #define _BLK_FRONT_H_
28 |
29 | #include
30 |
31 | /* these are default values: a sector is 512 bytes */
32 | #define SECTOR_BITS 9
33 | #define SECTOR_SIZE (1<
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include "db-frontend.h"
34 |
35 |
36 | /* Small utility function to figure out our domain id */
37 | static int get_self_id(void)
38 | {
39 | char *dom_id;
40 | int ret;
41 |
42 | assert(xsh != NULL);
43 | dom_id = xs_read(xsh, XBT_NULL, "domid", NULL);
44 | sscanf(dom_id, "%d", &ret);
45 |
46 | return ret;
47 | }
48 |
49 |
50 | int xenbus_request_connection(int dom_id,
51 | grant_ref_t *gref,
52 | evtchn_port_t *evtchn,
53 | grant_ref_t *dgref)
54 | {
55 | char request_node[256], *dom_path, **watch_rsp, *db_back_rsp, *str;
56 | bool ret;
57 | unsigned int length;
58 | int i;
59 | grant_ref_t lgref, ldgref;
60 | evtchn_port_t levtchn;
61 | sprintf(request_node,
62 | "/local/domain/%d/device/db/requests",
63 | dom_id);
64 | dom_path = xs_read(xsh, XBT_NULL, request_node, &length);
65 | free(dom_path);
66 | if(length <= 0)
67 | return -1;
68 | sprintf(request_node,
69 | "/local/domain/%d/device/db/requests/%d",
70 | dom_id, get_self_id());
71 | assert(xs_watch(xsh, request_node, "db-token") == true);
72 | ret = xs_write(xsh, XBT_NULL, request_node, "connection request",
73 | strlen("connection requset"));
74 |
75 | if(!ret)
76 | return -2;
77 |
78 | watch_again:
79 | watch_rsp = xs_read_watch(xsh, &length);
80 | assert(length == 2);
81 | assert(strcmp(watch_rsp[XS_WATCH_TOKEN], "db-token") == 0);
82 | db_back_rsp = watch_rsp[XS_WATCH_PATH] + strlen(request_node);
83 | if(strcmp(db_back_rsp, "/connected") == 0)
84 | {
85 | str = xs_read(xsh, XBT_NULL, watch_rsp[XS_WATCH_PATH], &length);
86 | assert(length > 0);
87 | lgref = -1;
88 | levtchn = -1;
89 | sscanf(str, "gref=%d evtchn=%d dgref=%d", &lgref, &levtchn, &ldgref);
90 | //printf("Gref is = %d, evtchn = %d, DGref = %d\n", lgref, levtchn, ldgref);
91 | *gref = lgref;
92 | *evtchn = levtchn;
93 | *dgref = ldgref;
94 | ret = 0;
95 | goto exit;
96 | }
97 | if(strcmp(db_back_rsp, "/already-in-use") == 0)
98 | {
99 | ret = -3;
100 | goto exit;
101 | }
102 |
103 | free(watch_rsp);
104 | goto watch_again;
105 |
106 | exit:
107 | xs_unwatch(xsh, request_node, "db-token");
108 | free(watch_rsp);
109 |
110 | return ret;
111 | }
112 |
--------------------------------------------------------------------------------
/include/fcntl.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | #ifndef _I386_FCNTL_H
24 | #define _I386_FCNTL_H
25 |
26 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
27 | located on an ext2 file system */
28 | #define O_ACCMODE 0003
29 | #define O_RDONLY 00
30 | #define O_WRONLY 01
31 | #define O_RDWR 02
32 | #define O_CREAT 0100 /* not fcntl */
33 | #define O_EXCL 0200 /* not fcntl */
34 | #define O_NOCTTY 0400 /* not fcntl */
35 | #define O_TRUNC 01000 /* not fcntl */
36 | #define O_APPEND 02000
37 | #define O_NONBLOCK 04000
38 | #define O_NDELAY O_NONBLOCK
39 | #define O_SYNC 010000
40 | #define FASYNC 020000 /* fcntl, for BSD compatibility */
41 | #define O_DIRECT 040000 /* direct disk access hint */
42 | #define O_LARGEFILE 0100000
43 | #define O_DIRECTORY 0200000 /* must be a directory */
44 | #define O_NOFOLLOW 0400000 /* don't follow links */
45 | #define O_NOATIME 01000000
46 |
47 | #define F_DUPFD 0 /* dup */
48 | #define F_GETFD 1 /* get close_on_exec */
49 | #define F_SETFD 2 /* set/clear close_on_exec */
50 | #define F_GETFL 3 /* get file->f_flags */
51 | #define F_SETFL 4 /* set file->f_flags */
52 | #define F_GETLK 5
53 | #define F_SETLK 6
54 | #define F_SETLKW 7
55 |
56 | #define F_SETOWN 8 /* for sockets. */
57 | #define F_GETOWN 9 /* for sockets. */
58 | #define F_SETSIG 10 /* for sockets. */
59 | #define F_GETSIG 11 /* for sockets. */
60 |
61 | #define F_GETLK64 12 /* using 'struct flock64' */
62 | #define F_SETLK64 13
63 | #define F_SETLKW64 14
64 |
65 | /* for F_[GET|SET]FL */
66 | #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
67 |
68 | /* for posix fcntl() and lockf() */
69 | #define F_RDLCK 0
70 | #define F_WRLCK 1
71 | #define F_UNLCK 2
72 |
73 | /* for old implementation of bsd flock () */
74 | #define F_EXLCK 4 /* or 3 */
75 | #define F_SHLCK 8 /* or 4 */
76 |
77 | /* for leases */
78 | #define F_INPROGRESS 16
79 |
80 | /* operations for bsd flock(), also used by the kernel implementation */
81 | #define LOCK_SH 1 /* shared lock */
82 | #define LOCK_EX 2 /* exclusive lock */
83 | #define LOCK_NB 4 /* or'd with one of the above to prevent
84 | blocking */
85 | #define LOCK_UN 8 /* remove lock */
86 |
87 | #define LOCK_MAND 32 /* This is a mandatory flock */
88 | #define LOCK_READ 64 /* ... Which allows concurrent read operations */
89 | #define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
90 | #define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
91 |
92 | /*
93 | struct flock {
94 | short l_type;
95 | short l_whence;
96 | off_t l_start;
97 | off_t l_len;
98 | pid_t l_pid;
99 | };
100 |
101 | struct flock64 {
102 | short l_type;
103 | short l_whence;
104 | loff_t l_start;
105 | loff_t l_len;
106 | pid_t l_pid;
107 | };
108 |
109 | #define F_LINUX_SPECIFIC_BASE 1024
110 | */
111 | #endif
112 |
--------------------------------------------------------------------------------
/service.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | * service/driver framework
25 | *
26 | * Author: Harald Roeck
27 | * Changes: Mick Jordan
28 | */
29 |
30 |
31 | #include
32 | #include
33 | #include
34 | #include
35 |
36 | #include
37 | static LIST_HEAD(services);
38 |
39 | #define SERV_STOP 0
40 | #define SERV_STARTED 1
41 | #define SERV_SUSPEND 2
42 | #define SERV_RESUME 3
43 | static int services_state = SERV_STOP;
44 |
45 |
46 | void register_service(struct service *s)
47 | {
48 | BUG_ON(services_state != SERV_STOP);
49 | list_add(&s->list, &services);
50 | }
51 |
52 | void start_services(void)
53 | {
54 | struct list_head *next;
55 | struct service *s;
56 | services_state = SERV_STARTED;
57 |
58 | if(trace_service())
59 | tprintk("start services ...\n");
60 | list_for_each(next, &services) {
61 | s = list_entry(next, struct service, list);
62 |
63 | if(trace_service())
64 | tprintk("start %s\n", s->name);
65 | s->init(s->arg);
66 | }
67 | }
68 |
69 | int suspend_services(void)
70 | {
71 | struct list_head *next;
72 | struct service *s;
73 | int retval;
74 |
75 | services_state = SERV_SUSPEND;
76 | if(trace_service())
77 | tprintk("suspend services ...\n");
78 | retval = 0;
79 | list_for_each(next, &services) {
80 | s = list_entry(next, struct service, list);
81 |
82 | if (trace_service())
83 | tprintk("suspend %s\n", s->name);
84 | retval += s->suspend();
85 | if (trace_service())
86 | tprintk("suspended %s\n", s->name);
87 | }
88 |
89 | if (retval)
90 | tprintk("%s %d WARNING: services are not suspended correctly\n", __FILE__, __LINE__);
91 | return retval;
92 | }
93 |
94 | int resume_services(void)
95 | {
96 | struct list_head *next;
97 | struct service *s;
98 | services_state = SERV_RESUME;
99 | int retval;
100 |
101 | if (trace_service())
102 | tprintk("resume services ...\n");
103 | retval = 0;
104 | list_for_each(next, &services) {
105 | s = list_entry(next, struct service, list);
106 |
107 | if (trace_service())
108 | tprintk("resume %s\n", s->name);
109 | retval += s->resume();
110 | if (trace_service())
111 | tprintk("resumed %s\n", s->name);
112 | }
113 | services_state = SERV_STARTED;
114 | return retval;
115 | }
116 |
117 |
118 | int shutdown_services(void)
119 | {
120 | struct list_head *next;
121 | struct service *s;
122 | int retval;
123 |
124 | if (trace_service())
125 | tprintk("shutdown services ...\n");
126 | retval = 0;
127 | list_for_each(next, &services) {
128 | s = list_entry(next, struct service, list);
129 |
130 | if (trace_service())
131 | tprintk("shutdown %s\n", s->name);
132 | retval += s->shutdown();
133 | }
134 | services_state = SERV_STOP;
135 | return retval;
136 | }
137 |
--------------------------------------------------------------------------------
/tests/run-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | #
4 | # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
5 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 | #
7 | # This code is free software; you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License version 2 only, as
9 | # published by the Free Software Foundation.
10 | #
11 | # This code is distributed in the hope that it will be useful, but WITHOUT
12 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 | # version 2 for more details (a copy is included in the LICENSE file that
15 | # accompanied this code).
16 | #
17 | # You should have received a copy of the GNU General Public License version
18 | # 2 along with this work; if not, write to the Free Software Foundation,
19 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 | #
21 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 | # or visit www.oracle.com if you need additional information or have any
23 | # questions.
24 | #
25 |
26 | # Config variables
27 | DOMAIN_CONFIG=domain_config
28 | DOMAIN_NAME=GUK-Test
29 | EXTRA=-XX:GUKMS=100 # allocate all initial memory to small pages
30 | CONSOLE_OUT=/tmp/console.out
31 | SUCCESSFUL=results_`date +%m.%d.%y`/successful
32 | UNSUCCESSFUL=results_`date +%m.%d.%y`/unsuccessful
33 | MAX_TEST_TIME=600
34 | MAKE=gmake
35 |
36 |
37 | # Execution variables
38 | cd `dirname $0`
39 | TEST_DIR=`pwd`
40 | GUK_ROOT=$TEST_DIR/../
41 |
42 | cd_guk() {
43 | cd $GUK_ROOT
44 | }
45 |
46 | cd_test_dir() {
47 | cd $TEST_DIR
48 | }
49 |
50 | destroy_domain() {
51 | # Destroy domain if it still exists
52 | if [ "`xm list | grep $DOMAIN_NAME`" ]; then
53 | xm destroy $DOMAIN_NAME
54 | fi
55 | }
56 |
57 | domain_exists() {
58 | if [ "`xm list | grep $DOMAIN_NAME`" ]; then
59 | echo yes
60 | else
61 | echo no
62 | fi
63 | }
64 |
65 | wait_on_domain() {
66 | # Let's sleep for couple of seconds to let xm create call finish it's
67 | # processing (otherwise we'll exit on failed domain_exists check immediately
68 | sleep 2
69 | COUNTER=2
70 | echo
71 | while [ $COUNTER -lt $MAX_TEST_TIME ] && [ "`domain_exists`" == "yes" ]; do
72 | let COUNTER=COUNTER+1
73 | sleep 1
74 | done
75 | }
76 |
77 | run_domain() {
78 | destroy_domain
79 | # Create the domain
80 | echo Creating the domain
81 | # Dump the console output for at most $MAX_TEST_TIME
82 | echo `wait_on_domain` | xm create -f $DOMAIN_CONFIG name=$DOMAIN_NAME -c extra=$EXTRA > $CONSOLE_OUT
83 | echo Destroying the domain
84 | # Destroy the domain
85 | destroy_domain
86 | }
87 |
88 | prepare_sources() {
89 | cd_guk
90 | rm -f test.o test_rand.o guestvm-ukernel.o
91 | ln -s "${TEST_DIR}/test_rand.c" "test_rand.c"
92 | ln -s "${TEST_DIR}/${TEST_FILE}" "test.c"
93 | }
94 |
95 | compile_domain() {
96 | cd_guk
97 | $MAKE
98 | RET=$?
99 | rm -f test.c
100 | rm -f test_rand.c
101 | }
102 |
103 | TEST_FILES=`ls *_test.c 2> /dev/null`
104 | if [ $# == 1 ]; then
105 | TEST_FILES=$1
106 | fi
107 |
108 |
109 | rm -rf ${TEST_DIR}/$SUCCESSFUL
110 | rm -rf ${TEST_DIR}/$UNSUCCESSFUL
111 | mkdir -p ${TEST_DIR}/$SUCCESSFUL
112 | mkdir -p ${TEST_DIR}/$UNSUCCESSFUL
113 | cd_test_dir
114 | for TEST_FILE in $TEST_FILES; do
115 | echo TESTING using $TEST_FILE
116 | cd_guk
117 | prepare_sources
118 | compile_domain
119 | if [ $RET != 0 ]; then
120 | continue
121 | fi
122 | run_domain
123 | # Check if the test was successful or not
124 | if [ "`cat $CONSOLE_OUT | grep SUCCESSFUL`" ]; then
125 | mv $CONSOLE_OUT ${TEST_DIR}/${SUCCESSFUL}/${TEST_FILE}.console
126 | else
127 | mv $CONSOLE_OUT ${TEST_DIR}/${UNSUCCESSFUL}/${TEST_FILE}.console
128 | fi
129 | done
130 |
131 |
--------------------------------------------------------------------------------
/tools/fs-back/fs-backend.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | * xenbus interface for Guest VM microkernel fs support
25 | *
26 | * Author: Grzegorz Milos
27 | * Mick Jordan
28 | *
29 | */
30 |
31 | #ifndef __LIB_FS_BACKEND__
32 | #define __LIB_FS_BACKEND__
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include "fsif.h"
40 |
41 | #define ROOT_NODE "backend/vfs"
42 | #define EXPORTS_SUBNODE "exports"
43 | #define EXPORTS_NODE ROOT_NODE"/"EXPORTS_SUBNODE
44 | #define WATCH_NODE EXPORTS_NODE"/requests"
45 |
46 | #define TRACE_OPS 1
47 | #define TRACE_OPS_NOISY 2
48 | #define TRACE_RING 3
49 |
50 | struct fs_export
51 | {
52 | int export_id;
53 | char *export_path;
54 | char *name;
55 | struct fs_export *next;
56 | };
57 |
58 | struct fs_request
59 | {
60 | int active;
61 | void *page; /* Pointer to mapped grant */
62 | struct fsif_request req_shadow;
63 | struct aiocb aiocb;
64 | };
65 |
66 |
67 | struct mount
68 | {
69 | struct fs_export *export;
70 | int dom_id;
71 | char *frontend;
72 | int mount_id; /* = backend id */
73 | grant_ref_t gref;
74 | evtchn_port_t remote_evtchn;
75 | int evth; /* Handle to the event channel */
76 | evtchn_port_t local_evtchn;
77 | int gnth;
78 | struct fsif_back_ring ring;
79 | int nr_entries;
80 | struct fs_request *requests;
81 | unsigned short *freelist;
82 | };
83 |
84 |
85 | /* Handle to XenStore driver */
86 | extern struct xs_handle *xsh;
87 |
88 | bool xenbus_create_request_node(void);
89 | int xenbus_register_export(struct fs_export *export);
90 | int xenbus_get_watch_fd(void);
91 | void xenbus_read_mount_request(struct mount *mount);
92 | void xenbus_write_backend_node(struct mount *mount);
93 | void xenbus_write_backend_ready(struct mount *mount);
94 |
95 | /* File operations, implemented in fs-ops.c */
96 | struct fs_op
97 | {
98 | int type; /* Type of request (from fsif.h) this handlers
99 | are responsible for */
100 | void (*dispatch_handler)(struct mount *mount, struct fsif_request *req);
101 | void (*response_handler)(struct mount *mount, struct fs_request *req);
102 | };
103 |
104 | /* This NULL terminated array of all file requests handlers */
105 | extern struct fs_op *fsops[];
106 |
107 | static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
108 | {
109 | freelist[id] = freelist[0];
110 | freelist[0] = id;
111 | }
112 |
113 | static inline unsigned short get_id_from_freelist(unsigned short* freelist)
114 | {
115 | unsigned int id = freelist[0];
116 | freelist[0] = freelist[id];
117 | return id;
118 | }
119 |
120 | #endif /* __LIB_FS_BACKEND__ */
121 |
--------------------------------------------------------------------------------
/include/guk/xenbus.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | #ifndef XENBUS_H__
24 | #define XENBUS_H__
25 |
26 | #include
27 |
28 | typedef unsigned long xenbus_transaction_t;
29 | #define XBT_NIL ((xenbus_transaction_t)0)
30 |
31 | /* Initialize the XenBus system. */
32 | void init_xenbus(void);
33 |
34 | void xenbus_suspend(void);
35 | void xenbus_resume(void);
36 |
37 | /* Read the value associated with a path. Returns a malloc'd error
38 | string on failure and sets *value to NULL. On success, *value is
39 | set to a malloc'd copy of the value. */
40 | char *guk_xenbus_read(xenbus_transaction_t xbt, const char *path, char **value);
41 | #define xenbus_read guk_xenbus_read
42 |
43 | char *xenbus_watch_path(xenbus_transaction_t xbt, char *path, char *token);
44 | char* xenbus_wait_for_value(char* token, char *path, char* value);
45 | char * xenbus_read_watch(char *token);
46 |
47 | int xenbus_rm_watch(char *token);
48 |
49 | /* Associates a value with a path. Returns a malloc'd error string on
50 | failure. */
51 | char *xenbus_write(xenbus_transaction_t xbt, const char *path, const char *value);
52 |
53 | /* Removes the value associated with a path. Returns a malloc'd error
54 | string on failure. */
55 | char *xenbus_rm(xenbus_transaction_t xbt, const char *path);
56 |
57 | /* List the contents of a directory. Returns a malloc'd error string
58 | on failure and sets *contents to NULL. On success, *contents is
59 | set to a malloc'd array of pointers to malloc'd strings. The array
60 | is NULL terminated. May block. */
61 | char *xenbus_ls(xenbus_transaction_t xbt, const char *prefix, char ***contents);
62 |
63 | /* Reads permissions associated with a path. Returns a malloc'd error
64 | string on failure and sets *value to NULL. On success, *value is
65 | set to a malloc'd copy of the value. */
66 | char *xenbus_get_perms(xenbus_transaction_t xbt, const char *path, char **value);
67 |
68 | /* Sets the permissions associated with a path. Returns a malloc'd
69 | error string on failure. */
70 | char *xenbus_set_perms(xenbus_transaction_t xbt, const char *path, domid_t dom, char perm);
71 |
72 | /* Start a xenbus transaction. Returns the transaction in xbt on
73 | success or a malloc'd error string otherwise. */
74 | char *xenbus_transaction_start(xenbus_transaction_t *xbt);
75 |
76 | /* End a xenbus transaction. Returns a malloc'd error string if it
77 | fails. abort says whether the transaction should be aborted.
78 | Returns 1 in *retry iff the transaction should be retried. */
79 | char *xenbus_transaction_end(xenbus_transaction_t, int abort,
80 | int *retry);
81 |
82 | /* Read path and parse it as an integer. Returns -1 on error. */
83 | int xenbus_read_integer(char *path);
84 |
85 | char* xenbus_printf(xenbus_transaction_t xbt,
86 | char* node, char* path,
87 | char* fmt, ...);
88 | /* get this domain's id */
89 | domid_t xenbus_get_self_id(void);
90 |
91 | #endif /* XENBUS_H__ */
92 |
--------------------------------------------------------------------------------
/tests/thread_bomb_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | Author: Grzegorz Milos
25 | */
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | extern u32 rand_int(void);
33 | extern void seed(u32 s);
34 |
35 | /* Objects = threads in this test */
36 | #define NUM_OBJECTS 1000
37 | struct object
38 | {
39 | struct thread *thread;
40 | };
41 | struct object objects[NUM_OBJECTS];
42 | static int remaining_threads_count;
43 | static DEFINE_SPINLOCK(thread_count_lock);
44 |
45 | void thread_fn(void *pickled_id)
46 | {
47 | struct timeval timeval_start, timeval_end;
48 | u32 ms = rand_int() & 0xFFF;
49 | int id = (int)(u64)pickled_id;
50 |
51 | gettimeofday(&timeval_start);
52 | gettimeofday(&timeval_end);
53 | while(SECONDS(timeval_end.tv_sec - timeval_start.tv_sec) +
54 | MICROSECS(timeval_end.tv_usec - timeval_start.tv_usec) <=
55 | MILLISECS(ms)){
56 | gettimeofday(&timeval_end);
57 | }
58 |
59 | spin_lock(&thread_count_lock);
60 | remaining_threads_count--;
61 | if(remaining_threads_count == 0)
62 | {
63 | spin_unlock(&thread_count_lock);
64 | printk("ALL SUCCESSFUL\n");
65 | ok_exit();
66 | }
67 |
68 | spin_unlock(&thread_count_lock);
69 | if(id % (NUM_OBJECTS / 100) == 0)
70 | printk("Success, exiting thread: %s, remaining %d.\n",
71 | current->name,
72 | remaining_threads_count);
73 |
74 | }
75 |
76 | static void allocate_object(u32 id)
77 | {
78 | char buffer[256];
79 |
80 | sprintf(buffer, "thread_bomb_%d", id);
81 | objects[id].thread = create_thread(strdup(buffer), thread_fn, UKERNEL_FLAG,
82 | (void *)(u64)id);
83 | if(id % (NUM_OBJECTS / 20) == 0)
84 | printk("Allocated thread id=%d\n", id);
85 | }
86 |
87 | static void USED thread_spawner(void *p)
88 | {
89 | u32 count = 1;
90 |
91 |
92 | seed((u32)NOW());
93 | memset(objects, 0, sizeof(struct object) * NUM_OBJECTS);
94 | printk("Thread bomb tester started.\n");
95 | for(count=0; count < NUM_OBJECTS; count++)
96 | {
97 | spin_lock(&thread_count_lock);
98 | /* The first object has been accounted for twice (in app_main, and here)
99 | * we therefore don't account for the last one */
100 | if(count != NUM_OBJECTS - 1)
101 | remaining_threads_count++;
102 | spin_unlock(&thread_count_lock);
103 | allocate_object(count);
104 | if(!(rand_int() & 0xFF))
105 | schedule();
106 | }
107 | }
108 |
109 | int guk_app_main(start_info_t *si)
110 | {
111 | printk("Private appmain.\n");
112 | /* assign 1 to prevent an exiting thread thinking it's the last one */
113 | remaining_threads_count = 1;
114 | create_thread("thread_spawner", thread_spawner, UKERNEL_FLAG, NULL);
115 |
116 | return 0;
117 | }
118 |
--------------------------------------------------------------------------------
/include/ctype.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | #ifndef _CTYPE_H
24 | #define _CTYPE_H
25 |
26 | /*
27 | * NOTE! This ctype does not handle EOF like the standard C
28 | * library is required to.
29 | */
30 |
31 | #define _U 0x01 /* upper */
32 | #define _L 0x02 /* lower */
33 | #define _D 0x04 /* digit */
34 | #define _C 0x08 /* cntrl */
35 | #define _P 0x10 /* punct */
36 | #define _S 0x20 /* white space (space/lf/tab) */
37 | #define _X 0x40 /* hex digit */
38 | #define _SP 0x80 /* hard space (0x20) */
39 |
40 |
41 | unsigned char _ctype[] = {
42 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
43 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
44 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
45 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
46 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
47 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
48 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
49 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
50 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
51 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
52 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
53 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
54 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
55 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
56 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
57 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
58 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
59 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
60 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
61 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
62 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
63 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
64 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
65 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
66 |
67 | #define __ismask(x) (_ctype[(int)(unsigned char)(x)])
68 |
69 | #define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
70 | #define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
71 | #define iscntrl(c) ((__ismask(c)&(_C)) != 0)
72 | #define isdigit(c) ((__ismask(c)&(_D)) != 0)
73 | #define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
74 | #define islower(c) ((__ismask(c)&(_L)) != 0)
75 | #define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
76 | #define ispunct(c) ((__ismask(c)&(_P)) != 0)
77 | #define isspace(c) ((__ismask(c)&(_S)) != 0)
78 | #define isupper(c) ((__ismask(c)&(_U)) != 0)
79 | #define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
80 |
81 | #define isascii(c) (((unsigned char)(c))<=0x7f)
82 | #define toascii(c) (((unsigned char)(c))&0x7f)
83 |
84 | static inline unsigned char __tolower(unsigned char c)
85 | {
86 | if (isupper(c))
87 | c -= 'A'-'a';
88 | return c;
89 | }
90 |
91 | static inline unsigned char __toupper(unsigned char c)
92 | {
93 | if (islower(c))
94 | c -= 'a'-'A';
95 | return c;
96 | }
97 |
98 | #define tolower(c) __tolower(c)
99 | #define toupper(c) __toupper(c)
100 |
101 | #endif
102 |
--------------------------------------------------------------------------------
/guk.mk:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | #
5 | # This code is free software; you can redistribute it and/or modify it
6 | # under the terms of the GNU General Public License version 2 only, as
7 | # published by the Free Software Foundation.
8 | #
9 | # This code is distributed in the hope that it will be useful, but WITHOUT
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | # version 2 for more details (a copy is included in the LICENSE file that
13 | # accompanied this code).
14 | #
15 | # You should have received a copy of the GNU General Public License version
16 | # 2 along with this work; if not, write to the Free Software Foundation,
17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | #
19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | # or visit www.oracle.com if you need additional information or have any
21 | # questions.
22 | #
23 | # The file contains the common make rules for building GUK.
24 | #
25 |
26 | debug = y
27 |
28 | # find gcc headers
29 | GCC_BASE=$(shell $(CC) -print-search-dirs | grep ^install | cut -f 2 -d ' ')
30 |
31 | ifeq ($(XEN_OS),SunOS)
32 | GCC_INCLUDE:=${GCC_BASE}install-tools/include
33 | endif
34 |
35 | ifeq ($(XEN_OS),Linux)
36 | GCC_INCLUDE:=-I${GCC_BASE}include
37 | GCC_INCLUDE+=-I${GCC_BASE}include-fixed
38 | endif
39 |
40 | # Define some default flags.
41 | # NB. '-Wcast-qual' is nasty, so I omitted it.
42 | # use -nostdinc to avoid name clashes, but include gcc standard headers
43 | DEF_CFLAGS := -fno-builtin -nostdinc $(GCC_INCLUDE)
44 | DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
45 | DEF_CFLAGS += -Wall -Werror -Wredundant-decls -Wno-format
46 | DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
47 | DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
48 | DEF_CFLAGS += -DCONFIG_PREEMPT -DCONFIG_SMP
49 |
50 | DEF_ASFLAGS = -D__ASSEMBLY__
51 | DEF_LDFLAGS =
52 |
53 | ifeq ($(debug),y)
54 | DEF_CFLAGS += -g
55 | else
56 | DEF_CFLAGS += -O3
57 | endif
58 |
59 | # Build the CFLAGS and ASFLAGS for compiling and assembling.
60 | # DEF_... flags are the common flags,
61 | # ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
62 | CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
63 | ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
64 | LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
65 |
66 | # The path pointing to the architecture specific header files.
67 | ARCH_INC := $(GUK_ROOT)/include/$(TARGET_ARCH_FAM)
68 |
69 | # Special build dependencies.
70 | # Rebuild all after touching this/these file(s)
71 | EXTRA_DEPS = $(GUK_ROOT)/guk.mk \
72 | $(GUK_ROOT)/$(TARGET_ARCH_DIR)/arch.mk \
73 | $(XEN_ROOT)/Config.mk
74 |
75 | # Find all header files for checking dependencies.
76 | HDRS := $(wildcard $(GUK_ROOT)/include/*.h)
77 | HDRS += $(wildcard $(GUK_ROOT)/include/xen/*.h)
78 | HDRS += $(wildcard $(GUK_ROOT)/include/guk/*.h)
79 | HDRS += $(wildcard $(ARCH_INC)/*.h)
80 | # For special wanted header directories.
81 | extra_heads := $(foreach dir,$(EXTRA_INC),$(wildcard $(dir)/*.h))
82 | HDRS += $(extra_heads)
83 |
84 | # Add the special header directories to the include paths.
85 | #extra_incl := $(foreach dir,$(EXTRA_INC),-I$(GUK_ROOT)/include/$(dir))
86 | override CPPFLAGS := -I$(GUK_ROOT)/tools/fs-back -I$(GUK_ROOT)/tools/db-front -I$(GUK_ROOT)/include $(CPPFLAGS)
87 | #$(extra_incl)
88 |
89 | # The name of the architecture specific library.
90 | # This is on x86_32: libx86_32.a
91 | # $(ARCH_LIB) has to built in the architecture specific directory.
92 | ARCH_LIB_NAME = $(TARGET_ARCH)
93 | ARCH_LIB := lib$(ARCH_LIB_NAME).a
94 |
95 | # This object contains the entrypoint for startup from Xen.
96 | # $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
97 | HEAD_ARCH_OBJ := $(TARGET_ARCH).o
98 | HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
99 |
100 |
101 | %.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
102 | $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
103 |
104 | %.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
105 | $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
106 |
107 | %.E: %.c $(HDRS) Makefile $(EXTRA_DEPS)
108 | $(CC) $(CFLAGS) $(CPPFLAGS) -E $< -o $@
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/include/guk/time.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | ****************************************************************************
25 | * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
26 | * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
27 | ****************************************************************************
28 | *
29 | * File: time.h
30 | * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
31 | * Changes: Grzegorz Milos (gm281@cam.ac.uk)
32 | * Robert Kaiser (kaiser@informatik.fh-wiesbaden.de)
33 | *
34 | * Date: Jul 2003, changes: Jun 2005, Sep 2006
35 | *
36 | * Environment: Guest VM microkernel evolved from Xen Minimal OS
37 | * Description: Time and timer functions
38 | *
39 | ****************************************************************************
40 | */
41 |
42 | #ifndef _TIME_H_
43 | #define _TIME_H_
44 |
45 |
46 |
47 | struct shadow_time_info {
48 | u64 tsc_timestamp; /* TSC at last update of time vals. */
49 | u64 system_timestamp; /* Time, in nanosecs, since boot. */
50 | u32 tsc_to_nsec_mul;
51 | u32 tsc_to_usec_mul;
52 | int tsc_shift;
53 | u32 version;
54 | };
55 |
56 | /*
57 | * System Time
58 | * 64 bit value containing the nanoseconds elapsed since boot time.
59 | * This value is adjusted by frequency drift.
60 | * NOW() returns the current time.
61 | * The other macros are for convenience to approximate short intervals
62 | * of real time into system time
63 | */
64 | typedef s64 s_time_t;
65 | extern s64 guk_time_addend;
66 |
67 | #define NOW() ((s_time_t)monotonic_clock() + time_addend)
68 | #define SECONDS(_s) (((s_time_t)(_s)) * 1000000000UL )
69 | #define TENTHS(_ts) (((s_time_t)(_ts)) * 100000000UL )
70 | #define HUNDREDTHS(_hs) (((s_time_t)(_hs)) * 10000000UL )
71 | #define MILLISECS(_ms) (((s_time_t)(_ms)) * 1000000UL )
72 | #define MICROSECS(_us) (((s_time_t)(_us)) * 1000UL )
73 | #define Time_Max ((s_time_t) 0x7fffffffffffffffLL)
74 | #define FOREVER Time_Max
75 | #define NSEC_TO_USEC(_nsec) ((_nsec) / 1000UL)
76 | #define NSEC_TO_SEC(_nsec) ((_nsec) / 1000000000ULL)
77 |
78 | /* wall clock time */
79 | #ifndef _STRUCT_TIMEVAL
80 | #define _STRUCT_TIMEVAL
81 | typedef long time_t;
82 | typedef long suseconds_t;
83 | struct timeval {
84 | time_t tv_sec; /* seconds */
85 | suseconds_t tv_usec; /* microseconds */
86 | };
87 | #endif
88 |
89 |
90 | struct timespec {
91 | time_t ts_sec;
92 | long ts_nsec;
93 | };
94 |
95 | typedef int clockid_t;
96 |
97 | /* prototypes */
98 | void init_time(void);
99 | u64 guk_monotonic_clock(void);
100 | void guk_gettimeofday(struct timeval *tv);
101 | void block_domain(s_time_t until);
102 | void check_need_resched(void);
103 | u64 guk_get_cpu_running_time(int cpu);
104 | void set_timer_interrupt(u64 delta);
105 |
106 | void time_suspend(void);
107 | void time_resume(void);
108 |
109 | #define monotonic_clock guk_monotonic_clock
110 | #define time_addend guk_time_addend
111 | #define gettimeofday guk_gettimeofday
112 | #define get_running_time() guk_get_cpu_running_time(smp_processor_id())
113 |
114 | #endif /* _TIME_H_ */
115 |
--------------------------------------------------------------------------------
/console/xencons_ring.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | #include
33 |
34 | #include
35 | #include
36 |
37 | DECLARE_WAIT_QUEUE_HEAD(console_queue);
38 |
39 | static inline struct xencons_interface *xencons_interface(void)
40 | {
41 | return mfn_to_virt(start_info.console.domU.mfn);
42 | }
43 |
44 | void xencons_notify_daemon(void)
45 | {
46 | /* Use evtchn: this is called early, before irq is set up. */
47 | notify_remote_via_evtchn(start_info.console.domU.evtchn);
48 | }
49 |
50 | int xencons_ring_avail(void)
51 | {
52 | struct xencons_interface *intf = xencons_interface();
53 | XENCONS_RING_IDX cons, prod;
54 |
55 | cons = intf->in_cons;
56 | prod = intf->in_prod;
57 | mb();
58 | BUG_ON((prod - cons) > sizeof(intf->in));
59 |
60 | return prod - cons;
61 | }
62 |
63 | int xencons_ring_send_no_notify(const char *data, unsigned len)
64 | {
65 | int sent = 0;
66 | struct xencons_interface *intf = xencons_interface();
67 | XENCONS_RING_IDX cons, prod;
68 | cons = intf->out_cons;
69 | prod = intf->out_prod;
70 | mb();
71 | BUG_ON((prod - cons) > sizeof(intf->out));
72 |
73 | while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
74 | intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
75 |
76 | wmb();
77 | intf->out_prod = prod;
78 |
79 | return sent;
80 | }
81 |
82 | int xencons_ring_send(const char *data, unsigned len)
83 | {
84 | int sent;
85 | sent = xencons_ring_send_no_notify(data, len);
86 | xencons_notify_daemon();
87 |
88 | return sent;
89 | }
90 |
91 |
92 |
93 | static void handle_input(evtchn_port_t port, void *ign)
94 | {
95 | //xprintk("wake_up\n");
96 | wake_up(&console_queue);
97 | }
98 |
99 | int xencons_ring_recv(char *data, unsigned len)
100 | {
101 | struct xencons_interface *intf = xencons_interface();
102 | XENCONS_RING_IDX cons, prod;
103 | unsigned filled = 0;
104 |
105 | cons = intf->in_cons;
106 | prod = intf->in_prod;
107 | mb();
108 | BUG_ON((prod - cons) > sizeof(intf->in));
109 |
110 | while (filled < len && cons + filled != prod) {
111 | data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in));
112 | filled++;
113 | }
114 |
115 | mb();
116 | intf->in_cons = cons + filled;
117 |
118 | xencons_notify_daemon();
119 |
120 | return filled;
121 | }
122 |
123 | int xencons_ring_init(void)
124 | {
125 | int err;
126 |
127 | if (!start_info.console.domU.evtchn)
128 | return 0;
129 |
130 | err = bind_evtchn(start_info.console.domU.evtchn,
131 | ANY_CPU,
132 | handle_input,
133 | NULL);
134 | if (err <= 0) {
135 | xprintk("XEN console request chn bind failed %i\n", err);
136 | return err;
137 | }
138 |
139 | /* In case we have in-flight data after save/restore... */
140 | xencons_notify_daemon();
141 |
142 | return 0;
143 | }
144 |
145 | void xencons_resume(void)
146 | {
147 | //xprintk("xencons_resume\n");
148 | xencons_ring_init();
149 | }
150 |
151 | void xencons_suspend(void)
152 | {
153 | //xprintk("xencons_suspend %d\n", start_info.console.domU.evtchn);
154 | unbind_evtchn(start_info.console.domU.evtchn);
155 | }
156 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | #
5 | # This code is free software; you can redistribute it and/or modify it
6 | # under the terms of the GNU General Public License version 2 only, as
7 | # published by the Free Software Foundation.
8 | #
9 | # This code is distributed in the hope that it will be useful, but WITHOUT
10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | # version 2 for more details (a copy is included in the LICENSE file that
13 | # accompanied this code).
14 | #
15 | # You should have received a copy of the GNU General Public License version
16 | # 2 along with this work; if not, write to the Free Software Foundation,
17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | #
19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | # or visit www.oracle.com if you need additional information or have any
21 | # questions.
22 | #
23 | # Common Makefile for guk.
24 | #
25 | # Every architecture directory below guk/arch has to have a
26 | # Makefile and an arch.mk.
27 | #
28 |
29 | ifndef XEN_ROOT
30 | $(error "Must set XEN_ROOT environment variable to the root of Xen tree")
31 | endif
32 |
33 |
34 | include $(XEN_ROOT)/Config.mk
35 | export XEN_ROOT
36 |
37 | # force 64 bit
38 | XEN_COMPILE_ARCH=x86_64
39 | XEN_TARGET_ARCH=x86_64
40 |
41 | XEN_INTERFACE_VERSION := 0x00030205
42 | export XEN_INTERFACE_VERSION
43 |
44 | # Set TARGET_ARCH
45 | override TARGET_ARCH := $(XEN_TARGET_ARCH)
46 |
47 | # Set guk root path, used in guk.mk.
48 | GUK_ROOT=$(PWD)
49 | export GUK_ROOT
50 |
51 | TARGET_ARCH_FAM = x86
52 |
53 | # The architecture family directory below guk.
54 | TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM)
55 |
56 | # Export these variables for possible use in architecture dependent makefiles.
57 | export TARGET_ARCH
58 | export TARGET_ARCH_DIR
59 | export TARGET_ARCH_FAM
60 |
61 | # This is used for architecture specific links.
62 | # This can be overwritten from arch specific rules.
63 | ARCH_LINKS =
64 |
65 | # For possible special header directories.
66 | # This can be overwritten from arch specific rules.
67 | EXTRA_INC =
68 |
69 | # Include the architecture family's special makerules.
70 | # This must be before include guk.mk!
71 | include $(TARGET_ARCH_DIR)/arch.mk
72 |
73 | # Include common guk makerules.
74 | include guk.mk
75 |
76 | # Define some default flags for linking.
77 | LDLIBS :=
78 | LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
79 | LDFLAGS_FINAL := -N -T $(TARGET_ARCH_DIR)/guk-$(TARGET_ARCH).lds
80 |
81 | # Prefix for global API names. All other local symbols are localised before
82 | # linking with EXTRA_OBJS.
83 | GLOBAL_PREFIX := guk_
84 | EXTRA_OBJS =
85 |
86 | TARGET := guk
87 |
88 | # Subdirectories common to guk
89 | SUBDIRS := lib xenbus console
90 |
91 | # The common guk objects to build.
92 | OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
93 | OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
94 | OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
95 | OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
96 |
97 |
98 | .PHONY: default
99 | default: links arch_lib $(TARGET)
100 |
101 | # Create special architecture specific links. The function arch_links
102 | # has to be defined in arch.mk (see include above).
103 | ifneq ($(ARCH_LINKS),)
104 | $(ARCH_LINKS):
105 | $(arch_links)
106 | endif
107 |
108 | .PHONY: links
109 | links: $(ARCH_LINKS)
110 | [ -e include/xen ] || ln -sf $(XEN_ROOT)/xen/include/public include/xen
111 |
112 | .PHONY: arch_lib
113 | arch_lib:
114 | $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
115 |
116 | $(TARGET): $(OBJS) $(TARGET_ARCH_DIR)/lib$(ARCH_LIB_NAME).a
117 | $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o
118 | $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start -G str* -G mem* -G hypercall_page $@.o $@.o
119 | $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
120 | gzip -f -9 -c $@ >$@.gz
121 |
122 | .PHONY: clean arch_clean
123 |
124 | arch_clean:
125 | $(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1;
126 |
127 | clean: arch_clean
128 | for dir in $(SUBDIRS); do \
129 | rm -f $$dir/*.o; \
130 | done
131 | rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
132 | find . -type l | xargs rm -f
133 |
134 |
135 | define all_sources
136 | ( find . -follow -name SCCS -prune -o -name '*.[chS]' -print )
137 | endef
138 |
139 | .PHONY: cscope
140 | cscope:
141 | $(all_sources) > cscope.files
142 | cscope -k -b -q
143 |
144 | .PHONY: tags
145 | tags:
146 | $(all_sources) | xargs ctags
147 |
148 | %.S: %.c
149 | $(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@
150 |
151 |
--------------------------------------------------------------------------------
/tests/sleeping_threads_bomb_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | Author: Grzegorz Milos
25 | */
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | extern u32 rand_int(void);
33 | extern void seed(u32 s);
34 |
35 | /* Objects = threads in this test */
36 | #define NUM_OBJECTS 10000
37 | struct object
38 | {
39 | struct thread *thread;
40 | };
41 | struct object objects[NUM_OBJECTS];
42 | static int remaining_threads_count;
43 | static DEFINE_SPINLOCK(thread_count_lock);
44 |
45 | void thread_fn(void *pickled_id)
46 | {
47 | struct timeval timeval_start, timeval_end, timeval_sleep;
48 | u32 ms = rand_int() & 0xFFF;
49 | int id = (int)(u64)pickled_id;
50 |
51 | gettimeofday(&timeval_start);
52 | gettimeofday(&timeval_end);
53 | while(SECONDS(timeval_end.tv_sec - timeval_start.tv_sec) +
54 | MICROSECS(timeval_end.tv_usec - timeval_start.tv_usec) <=
55 | MILLISECS(ms)){
56 | #define SLEEP_PERIOD 500
57 | if(!(rand_int() & 0xFF))
58 | {
59 | gettimeofday(&timeval_sleep);
60 | sleep(SLEEP_PERIOD);
61 | gettimeofday(&timeval_end);
62 | if(SECONDS(timeval_end.tv_sec - timeval_sleep.tv_sec) +
63 | MICROSECS(timeval_end.tv_usec - timeval_sleep.tv_usec) <=
64 | MILLISECS(SLEEP_PERIOD)){
65 | printk("Thread: %s didn't sleep for long enough.\n",
66 | current->name);
67 | printk("FAILED.\n");
68 | ok_exit();
69 | }
70 |
71 | }
72 | if(!(rand_int() & 0x1))
73 | schedule();
74 | gettimeofday(&timeval_end);
75 | }
76 |
77 | spin_lock(&thread_count_lock);
78 | remaining_threads_count--;
79 | if(remaining_threads_count == 0)
80 | {
81 | spin_unlock(&thread_count_lock);
82 | printk("ALL SUCCESSFUL\n");
83 | ok_exit();
84 | }
85 |
86 | spin_unlock(&thread_count_lock);
87 | if(id % (NUM_OBJECTS / 100) == 0)
88 | printk("Success, exiting thread: %s, remaining %d.\n",
89 | current->name,
90 | remaining_threads_count);
91 |
92 | }
93 |
94 | static void allocate_object(u32 id)
95 | {
96 | char buffer[256];
97 |
98 | sprintf(buffer, "thread_bomb_%d", id);
99 | objects[id].thread = create_thread(strdup(buffer), thread_fn, UKERNEL_FLAG,
100 | (void *)(u64)id);
101 | if(id % (NUM_OBJECTS / 20) == 0)
102 | printk("Allocated thread id=%d\n", id);
103 | }
104 |
105 | static void USED thread_spawner(void *p)
106 | {
107 | u32 count = 1;
108 |
109 |
110 | seed((u32)NOW());
111 | memset(objects, 0, sizeof(struct object) * NUM_OBJECTS);
112 | printk("Sleeping threads bomb tester started.\n");
113 | for(count=0; count < NUM_OBJECTS; count++)
114 | {
115 | spin_lock(&thread_count_lock);
116 | /* The first object has been accounted for twice (in app_main, and here)
117 | * we therefore don't account for the last one */
118 | if(count != NUM_OBJECTS - 1)
119 | remaining_threads_count++;
120 | spin_unlock(&thread_count_lock);
121 | allocate_object(count);
122 | if(!(rand_int() & 0xFF))
123 | schedule();
124 | }
125 | }
126 |
127 | int guk_app_main(start_info_t *si)
128 | {
129 | printk("Private appmain.\n");
130 | /* assign 1 to prevent an exiting thread thinking it's the last one */
131 | remaining_threads_count = 1;
132 | create_thread("thread_spawner", thread_spawner, UKERNEL_FLAG, NULL);
133 |
134 | return 0;
135 | }
136 |
--------------------------------------------------------------------------------
/tests/timing_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | Author: Grzegorz Milos
25 | */
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | extern u32 rand_int(void);
33 | extern void seed(u32 s);
34 |
35 | /* Objects = threads in this test */
36 | #define NUM_OBJECTS 1000
37 | struct object
38 | {
39 | struct thread *thread;
40 | };
41 | struct object objects[NUM_OBJECTS];
42 | static int remaining_threads_count;
43 | static DEFINE_SPINLOCK(thread_count_lock);
44 | static DEFINE_SPINLOCK(time_lock);
45 | u64 last_time_val = 0;
46 | int last_cpu = 0;
47 | u64 total_time_tests = 0;
48 |
49 |
50 | void thread_fn(void *pickled_id)
51 | {
52 | struct timeval timeval_start, timeval_end;
53 | u32 ms = rand_int() & 0xFFF;
54 | int id = (int)(u64)pickled_id;
55 | u64 current_time;
56 |
57 | gettimeofday(&timeval_start);
58 | gettimeofday(&timeval_end);
59 | while(SECONDS(timeval_end.tv_sec - timeval_start.tv_sec) +
60 | MICROSECS(timeval_end.tv_usec - timeval_start.tv_usec) <=
61 | MILLISECS(ms)){
62 | spin_lock(&time_lock);
63 | gettimeofday(&timeval_end);
64 | current_time = SECONDS(timeval_end.tv_sec) +
65 | MICROSECS(timeval_end.tv_usec);
66 | if(current_time < last_time_val)
67 | {
68 | printk("Time went backwards: last_time_val=%lx (CPU=%d), "
69 | "current_time=%lx (CPU=%d), difference: %lldns\n",
70 | last_time_val, last_cpu,
71 | current_time, smp_processor_id(),
72 | (last_time_val - current_time));
73 | ok_exit();
74 | }
75 | last_time_val = current_time;
76 | last_cpu = smp_processor_id();
77 | total_time_tests++;
78 | spin_unlock(&time_lock);
79 | }
80 |
81 | spin_lock(&thread_count_lock);
82 | remaining_threads_count--;
83 | if(remaining_threads_count == 0)
84 | {
85 | spin_unlock(&thread_count_lock);
86 | printk("ALL SUCCESSFUL\n");
87 | printk("Total time tests done: %lld\n", total_time_tests);
88 | ok_exit();
89 | }
90 |
91 | spin_unlock(&thread_count_lock);
92 | if(id % (NUM_OBJECTS / 100) == 0)
93 | printk("Success, exiting thread: %s, remaining %d.\n",
94 | current->name,
95 | remaining_threads_count);
96 |
97 | }
98 |
99 | static void allocate_object(u32 id)
100 | {
101 | char buffer[256];
102 |
103 | sprintf(buffer, "thread_bomb_%d", id);
104 | objects[id].thread = create_thread(strdup(buffer), thread_fn, UKERNEL_FLAG,
105 | (void *)(u64)id);
106 | if(id % (NUM_OBJECTS / 20) == 0)
107 | printk("Allocated thread id=%d\n", id);
108 | }
109 |
110 | static void USED thread_spawner(void *p)
111 | {
112 | u32 count = 1;
113 |
114 |
115 | seed((u32)NOW());
116 | memset(objects, 0, sizeof(struct object) * NUM_OBJECTS);
117 | printk("Timing tester started.\n");
118 | for(count=0; count < NUM_OBJECTS; count++)
119 | {
120 | spin_lock(&thread_count_lock);
121 | /* The first object has been accounted for twice (in app_main, and here)
122 | * we therefore don't account for the last one */
123 | if(count != NUM_OBJECTS - 1)
124 | remaining_threads_count++;
125 | spin_unlock(&thread_count_lock);
126 | allocate_object(count);
127 | if(!(rand_int() & 0xFF))
128 | schedule();
129 | }
130 | }
131 |
132 | int guk_app_main(void *args)
133 | {
134 | printk("Private appmain.\n");
135 | /* assign 1 to prevent an exiting thread thinking it's the last one */
136 | remaining_threads_count = 1;
137 | create_thread("thread_spawner", thread_spawner, UKERNEL_FLAG, NULL);
138 |
139 | return 0;
140 | }
141 |
--------------------------------------------------------------------------------
/lib/string.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | ****************************************************************************
25 | * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
26 | ****************************************************************************
27 | *
28 | * File: string.c
29 | * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
30 | * Changes:
31 | *
32 | * Date: Aug 2003
33 | *
34 | * Environment: Guest VM microkernel evolved from Xen Minimal OS
35 | * Description: Library function for string and memory manipulation
36 | * Origin unknown
37 | *
38 | */
39 |
40 | #if !defined HAVE_LIBC
41 |
42 | #include
43 | #include
44 |
45 | #include
46 | #include
47 |
48 | int memcmp(const void * cs,const void * ct,size_t count)
49 | {
50 | const unsigned char *su1, *su2;
51 | signed char res = 0;
52 |
53 | for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
54 | if ((res = *su1 - *su2) != 0)
55 | break;
56 | return res;
57 | }
58 |
59 | void * memcpy(void * dest,const void *src,size_t count)
60 | {
61 | char *tmp = (char *) dest;
62 | const char *s = src;
63 |
64 | while (count--)
65 | *tmp++ = *s++;
66 |
67 | return dest;
68 | }
69 |
70 | int strncmp(const char * cs,const char * ct,size_t count)
71 | {
72 | register signed char __res = 0;
73 |
74 | while (count) {
75 | if ((__res = *cs - *ct++) != 0 || !*cs++)
76 | break;
77 | count--;
78 | }
79 |
80 | return __res;
81 | }
82 |
83 | int strcmp(const char * cs,const char * ct)
84 | {
85 | register signed char __res;
86 |
87 | while (1) {
88 | if ((__res = *cs - *ct++) != 0 || !*cs++)
89 | break;
90 | }
91 |
92 | return __res;
93 | }
94 |
95 | char * strcpy(char * dest,const char *src)
96 | {
97 | char *tmp = dest;
98 |
99 | while ((*dest++ = *src++) != '\0')
100 | /* nothing */;
101 | return tmp;
102 | }
103 |
104 | char * strncpy(char * dest,const char *src,size_t count)
105 | {
106 | char *tmp = dest;
107 |
108 | while (count-- && (*dest++ = *src++) != '\0')
109 | /* nothing */;
110 |
111 | return tmp;
112 | }
113 |
114 | void * memset(void * s,int c,size_t count)
115 | {
116 | char *xs = (char *) s;
117 |
118 | while (count--)
119 | *xs++ = c;
120 |
121 | return s;
122 | }
123 |
124 | size_t strnlen(const char * s, size_t count)
125 | {
126 | const char *sc;
127 |
128 | for (sc = s; count-- && *sc != '\0'; ++sc)
129 | /* nothing */;
130 | return sc - s;
131 | }
132 |
133 |
134 | char * strcat(char * dest, const char * src)
135 | {
136 | char *tmp = dest;
137 |
138 | while (*dest)
139 | dest++;
140 |
141 | while ((*dest++ = *src++) != '\0');
142 |
143 | return tmp;
144 | }
145 |
146 | size_t strlen(const char * s)
147 | {
148 | const char *sc;
149 |
150 | for (sc = s; *sc != '\0'; ++sc)
151 | /* nothing */;
152 | return sc - s;
153 | }
154 |
155 | char * strchr(const char * s, int c)
156 | {
157 | for(; *s != (char) c; ++s)
158 | if (*s == '\0')
159 | return NULL;
160 | return (char *)s;
161 | }
162 |
163 | char * strstr(const char * s1,const char * s2)
164 | {
165 | int l1, l2;
166 |
167 | l2 = strlen(s2);
168 | if (!l2)
169 | return (char *) s1;
170 | l1 = strlen(s1);
171 | while (l1 >= l2) {
172 | l1--;
173 | if (!memcmp(s1,s2,l2))
174 | return (char *) s1;
175 | s1++;
176 | }
177 | return NULL;
178 | }
179 |
180 | char *strdup(const char *x)
181 | {
182 | int l = strlen(x);
183 | char *res = malloc(l + 1);
184 | if (!res) return NULL;
185 | memcpy(res, x, l + 1);
186 | return res;
187 | }
188 |
189 | #endif
190 |
--------------------------------------------------------------------------------
/tests/repetitive_memory_test.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /*
24 | Author: Grzegorz Milos
25 | */
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | extern u32 rand_int(void);
33 | extern void seed(u32 s);
34 |
35 | #define NUM_OBJECTS 1000
36 | #define MAX_OBJ_SIZE 0x1FFF
37 | struct object
38 | {
39 | int size;
40 | void *pointer;
41 | int allocated;
42 | int read;
43 | };
44 | struct object objects[NUM_OBJECTS];
45 |
46 | static void verify_object(struct object *object)
47 | {
48 | u32 id = ((unsigned long)object - (unsigned long)objects) / sizeof(struct object);
49 | uint8_t *test_value = (uint8_t *)object->pointer, *pointer;
50 | int i;
51 |
52 | if(!object->allocated)
53 | return;
54 | object->read = 1;
55 | for(i=0; isize; i++)
56 | if(test_value[i] != (id & 0xFF))
57 | goto fail;
58 | return;
59 |
60 | fail:
61 | printk("Failed verification for object id=%d, size=%d, i=%d,"
62 | " got=%x, expected=%x\n",
63 | id, object->size, i, test_value[i], id & 0xFF);
64 |
65 | pointer = (uint8_t *)objects[id].pointer;
66 |
67 | printk("Object %d, size: %d, pointer=%lx\n",
68 | id, objects[id].size, objects[id].pointer);
69 | for(i=0; iallocated)
98 | return;
99 | free(object->pointer);
100 | object->size = 0;
101 | object->read = 0;
102 | object->allocated = 0;
103 | object->pointer = 0;
104 | }
105 |
106 | static void USED mem_allocator(void *p)
107 | {
108 | u32 count, loop_count;
109 |
110 |
111 | loop_count = 0;
112 | seed((u32)NOW());
113 | again:
114 | memset(objects, 0, sizeof(struct object) * NUM_OBJECTS);
115 | printk("Repetitive memory allocator tester started.\n");
116 | for(count=0; count < NUM_OBJECTS; count++)
117 | {
118 | allocate_object(count);
119 | /* Randomly read an object off */
120 | if(rand_int() & 1)
121 | {
122 | u32 to_read = count & rand_int();
123 |
124 | verify_object(&objects[to_read]);
125 | }
126 | /* Randomly free an object */
127 | if(rand_int() & 1)
128 | {
129 | u32 to_free = count & rand_int();
130 |
131 | free_object(&objects[to_free]);
132 | }
133 | }
134 |
135 | printk("Destroying remaining objects.\n");
136 | for(count = 0; count < NUM_OBJECTS; count++)
137 | {
138 | if(objects[count].allocated)
139 | {
140 | verify_object(&objects[count]);
141 | free_object(&objects[count]);
142 | }
143 | }
144 |
145 | loop_count++;
146 | if(loop_count < 50)
147 | {
148 | printk("Finished loop %d. Repeating the test.\n", loop_count);
149 | goto again;
150 | }
151 |
152 | printk("SUCCESSFUL\n");
153 | do_exit();
154 | }
155 |
156 | int guk_app_main(start_info_t *si)
157 | {
158 | printk("Private appmain.\n");
159 | create_thread("mem_allocator", mem_allocator, UKERNEL_FLAG, NULL);
160 |
161 | return 0;
162 | }
163 |
--------------------------------------------------------------------------------
/tools/db-front/gx_utils.c:
--------------------------------------------------------------------------------
1 | /* Remote utility routines for the remote server for GDB.
2 | Copyright (C) 2008
3 | Free Software Foundation, Inc.
4 |
5 | This file is part of GDB.
6 |
7 | This program is free software; you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation; either version 2 of the License, or
10 | (at your option) any later version.
11 |
12 | This program is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with this program; if not, write to the Free Software
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 | Boston, MA 02110-1301, USA. */
21 | /*
22 | * Copyright (C) 2008 Oracle. All rights reserved.
23 | *
24 | * This program is free software; you can redistribute it and/or
25 | * modify it under the terms of the GNU General Public
26 | * License v2 as published by the Free Software Foundation.
27 | *
28 | * This program is distributed in the hope that it will be useful,
29 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31 | * General Public License for more details.
32 | *
33 | * You should have received a copy of the GNU General Public
34 | * License along with this program; if not, write to the
35 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
36 | * Boston, MA 021110-1307, USA.
37 | */
38 |
39 | #include
40 | #include
41 | #include
42 |
43 | #include "gx.h"
44 |
45 |
46 | void
47 | gxprt(const char *fmt, ...)
48 | {
49 | char buf[2048];
50 | va_list args;
51 |
52 | va_start(args, fmt);
53 | (void)vsnprintf(buf, sizeof(buf), fmt, args);
54 | va_end(args);
55 | fprintf(stderr, "%s", buf);
56 | fflush(stderr);
57 | }
58 |
59 | int
60 | gx_fromhex(int a)
61 | {
62 | if (a >= '0' && a <= '9')
63 | return a - '0';
64 | else if (a >= 'a' && a <= 'f')
65 | return a - 'a' + 10;
66 | else
67 | gxprt("Reply contains invalid hex digit");
68 | return 0;
69 | }
70 |
71 | int
72 | gx_tohex(int nib)
73 | {
74 | if (nib < 10)
75 | return '0' + nib;
76 | else
77 | return 'a' + nib - 10;
78 | }
79 |
80 |
81 | void
82 | gx_convert_int_to_ascii(char *from, char *to, int n)
83 | {
84 | int nib;
85 | int ch;
86 | while (n--) {
87 | ch = *from++;
88 | nib = ((ch & 0xf0) >> 4) & 0x0f;
89 | *to++ = gx_tohex(nib);
90 | nib = ch & 0x0f;
91 | *to++ = gx_tohex(nib);
92 | }
93 | *to = 0;
94 | }
95 |
96 | /* input: "70676433206431" output: "pgd3 d1" n == 7 */
97 | void
98 | gx_convert_ascii_to_int(char *from, char *to, int n)
99 | {
100 | int nib1, nib2;
101 | while (n--) {
102 | nib1 = gx_fromhex(*from++);
103 | nib2 = gx_fromhex(*from++);
104 | *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
105 | }
106 | *to = 0;
107 | }
108 |
109 | void
110 | gx_decode_zZ_packet(char *from, uint64_t *mem_addr_ptr)
111 | {
112 | int i = 0;
113 | char ch;
114 | *mem_addr_ptr = 0;
115 |
116 | while ((ch=from[i++]) != ',') {
117 | *mem_addr_ptr = *mem_addr_ptr << 4;
118 | *mem_addr_ptr |= gx_fromhex(ch) & 0x0f;
119 | }
120 | }
121 |
122 | /* Eg: mc0267d3a,1\0 : from points to char after 'm' */
123 | void
124 | gx_decode_m_packet(char *from, uint64_t *mem_addr_ptr, int *len_ptr)
125 | {
126 | int i = 0, j = 0;
127 | char ch;
128 | *mem_addr_ptr = *len_ptr = 0;
129 |
130 | while ((ch=from[i++]) != ',') {
131 | *mem_addr_ptr = *mem_addr_ptr << 4;
132 | *mem_addr_ptr |= gx_fromhex(ch) & 0x0f;
133 | }
134 | for (j = 0; j < 4; j++) {
135 | if ((ch=from[i++]) == 0)
136 | break;
137 | *len_ptr = *len_ptr << 4;
138 | *len_ptr |= gx_fromhex(ch) & 0x0f;
139 | }
140 | }
141 |
142 | /*
143 | * Decode M pkt as in: Mc0267d3a,1:cc\0 where c0267d3a is the guest addr
144 | * from points to char after 'M'
145 | * Returns: address of byte after ":", ie, addr of cc in buf
146 | */
147 | char *
148 | gx_decode_M_packet(char *from, uint64_t *mem_addr_ptr, int *len_ptr)
149 | {
150 | int i = 0;
151 | char ch;
152 |
153 | *mem_addr_ptr = *len_ptr = 0;
154 |
155 | while ((ch=from[i++]) != ',') {
156 | *mem_addr_ptr = *mem_addr_ptr << 4;
157 | *mem_addr_ptr |= gx_fromhex(ch) & 0x0f;
158 | }
159 | while ((ch = from[i++]) != ':') {
160 | *len_ptr = *len_ptr << 4;
161 | *len_ptr |= gx_fromhex(ch) & 0x0f;
162 | }
163 | return(&from[i]);
164 | }
165 |
166 |
--------------------------------------------------------------------------------
/hypervisor.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software; you can redistribute it and/or modify it
6 | * under the terms of the GNU General Public License version 2 only, as
7 | * published by the Free Software Foundation.
8 | *
9 | * This code is distributed in the hope that it will be useful, but WITHOUT
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 | * version 2 for more details (a copy is included in the LICENSE file that
13 | * accompanied this code).
14 | *
15 | * You should have received a copy of the GNU General Public License version
16 | * 2 along with this work; if not, write to the Free Software Foundation,
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 | *
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 | * or visit www.oracle.com if you need additional information or have any
21 | * questions.
22 | */
23 | /******************************************************************************
24 | * hypervisor.c
25 | *
26 | * Communication to/from hypervisor.
27 | *
28 | * Copyright (c) 2002-2003, K A Fraser
29 | * Copyright (c) 2005, Grzegorz Milos, gm281@cam.ac.uk,Intel Research Cambridge
30 | *
31 | * Permission is hereby granted, free of charge, to any person obtaining a copy
32 | * of this software and associated documentation files (the "Software"), to
33 | * deal in the Software without restriction, including without limitation the
34 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
35 | * sell copies of the Software, and to permit persons to whom the Software is
36 | * furnished to do so, subject to the following conditions:
37 | *
38 | * The above copyright notice and this permission notice shall be included in
39 | * all copies or substantial portions of the Software.
40 | *
41 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
47 | * DEALINGS IN THE SOFTWARE.
48 | */
49 |
50 | #include
51 | #include
52 | #include
53 | #include
54 | #include
55 |
56 | #define active_evtchns(idx) \
57 | (HYPERVISOR_shared_info->evtchn_pending[idx] & \
58 | ~HYPERVISOR_shared_info->evtchn_mask[idx])
59 |
60 | void do_hypervisor_callback(void)
61 | {
62 | u32 l1, l2;
63 | unsigned int l1i, l2i, port;
64 | int cpu, count;
65 | vcpu_info_t *vcpu_info;
66 |
67 | cpu = smp_processor_id();
68 | vcpu_info = &HYPERVISOR_shared_info->vcpu_info[cpu];
69 | // BUG_ON(vcpu_info->evtchn_upcall_mask == 0);
70 | // BUG_ON(current->tmp == 1);
71 | do {
72 | vcpu_info->evtchn_upcall_pending = 0;
73 | /* Nested invocations bail immediately. */
74 | if (unlikely(this_cpu(upcall_count)++))
75 | return;
76 | /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
77 | l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
78 | while ( l1 != 0 )
79 | {
80 | l1i = __ffs(l1);
81 | l1 &= ~(1 << l1i);
82 |
83 | while ( (l2 = active_evtchns(l1i)) != 0 )
84 | {
85 | l2i = __ffs(l2);
86 | l2 &= ~(1 << l2i);
87 |
88 | port = (l1i << 5) + l2i;
89 | do_event(port);
90 | }
91 | }
92 | count = this_cpu(upcall_count);
93 | this_cpu(upcall_count) = 0;
94 | if(count != 1)
95 | printk("=========> WARN: untested: event set during IRQ.\n");
96 | } while (count != 1);
97 | }
98 |
99 |
100 | inline void mask_evtchn(u32 port)
101 | {
102 | shared_info_t *s = HYPERVISOR_shared_info;
103 | synch_set_bit(port, &s->evtchn_mask[0]);
104 | }
105 |
106 | inline void unmask_evtchn(u32 port)
107 | {
108 | shared_info_t *s = HYPERVISOR_shared_info;
109 | vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
110 |
111 | synch_clear_bit(port, &s->evtchn_mask[0]);
112 |
113 | /*
114 | * The following is basically the equivalent of 'hw_resend_irq'. Just like
115 | * a real IO-APIC we 'lose the interrupt edge' if the channel is masked.
116 | */
117 | if ( synch_test_bit (port, &s->evtchn_pending[0]) &&
118 | !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel) )
119 | {
120 | vcpu_info->evtchn_upcall_pending = 1;
121 | if ( !vcpu_info->evtchn_upcall_mask )
122 | force_evtchn_callback();
123 | }
124 | }
125 |
126 | inline void clear_evtchn(u32 port)
127 | {
128 | shared_info_t *s = HYPERVISOR_shared_info;
129 | synch_clear_bit(port, &s->evtchn_pending[0]);
130 | }
131 |
--------------------------------------------------------------------------------