aboutsummaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2008-06-19 12:46:26 +0900
committerIsaku Yamahata <yamahata@valinux.co.jp>2008-06-19 12:46:26 +0900
commitd20f38afdaf61331547a3436e9d7311b75628d21 (patch)
tree0eab6105ee58ad8397365ce5d4d598ad049f70e7 /extras
parent006dff9e0417b59020b675f1b0ee49713a9a5739 (diff)
parentd9a2559fc45a21e727e44a5261695dbbba8a517b (diff)
downloadxen-d20f38afdaf61331547a3436e9d7311b75628d21.tar.gz
xen-d20f38afdaf61331547a3436e9d7311b75628d21.tar.bz2
xen-d20f38afdaf61331547a3436e9d7311b75628d21.zip
merge with xen-unstable.hg
Diffstat (limited to 'extras')
-rw-r--r--extras/mini-os/Makefile41
-rw-r--r--extras/mini-os/arch/ia64/Makefile7
-rw-r--r--extras/mini-os/arch/ia64/common.c6
-rw-r--r--extras/mini-os/arch/ia64/time.c6
-rw-r--r--extras/mini-os/arch/x86/Makefile10
-rw-r--r--extras/mini-os/arch/x86/mm.c10
-rw-r--r--extras/mini-os/arch/x86/setup.c10
-rw-r--r--extras/mini-os/arch/x86/time.c9
-rw-r--r--extras/mini-os/arch/x86/traps.c4
-rw-r--r--extras/mini-os/arch/x86/x86_32.S2
-rw-r--r--extras/mini-os/blkfront.c47
-rw-r--r--extras/mini-os/console/console.c12
-rw-r--r--extras/mini-os/console/xencons_ring.c44
-rw-r--r--extras/mini-os/events.c33
-rw-r--r--extras/mini-os/fbfront.c52
-rw-r--r--extras/mini-os/fs-front.c2
-rw-r--r--extras/mini-os/gnttab.c14
-rw-r--r--extras/mini-os/include/blkfront.h7
-rw-r--r--extras/mini-os/include/byteswap.h39
-rw-r--r--extras/mini-os/include/console.h10
-rw-r--r--extras/mini-os/include/events.h1
-rw-r--r--extras/mini-os/include/gnttab.h1
-rw-r--r--extras/mini-os/include/ia64/os.h3
-rw-r--r--extras/mini-os/include/ia64/traps.h4
-rw-r--r--extras/mini-os/include/kernel.h7
-rw-r--r--extras/mini-os/include/mm.h1
-rw-r--r--extras/mini-os/include/netfront.h1
-rw-r--r--extras/mini-os/include/time.h1
-rw-r--r--extras/mini-os/include/wait.h2
-rw-r--r--extras/mini-os/include/x86/arch_mm.h24
-rw-r--r--extras/mini-os/include/x86/os.h4
-rw-r--r--extras/mini-os/include/xenbus.h3
-rw-r--r--extras/mini-os/kernel.c48
-rw-r--r--extras/mini-os/lib/sys.c48
-rw-r--r--extras/mini-os/lwip-net.c6
-rw-r--r--extras/mini-os/main.c39
-rw-r--r--extras/mini-os/minios.mk6
-rw-r--r--extras/mini-os/mm.c4
-rw-r--r--extras/mini-os/netfront.c21
-rw-r--r--extras/mini-os/xenbus/xenbus.c17
40 files changed, 479 insertions, 127 deletions
diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile
index 18497e1843..bc55145f3a 100644
--- a/extras/mini-os/Makefile
+++ b/extras/mini-os/Makefile
@@ -6,6 +6,7 @@
export XEN_ROOT = ../..
include $(XEN_ROOT)/Config.mk
+OBJ_DIR ?= $(CURDIR)
ifneq ($(stubdom),y)
include Config.mk
@@ -20,7 +21,7 @@ include minios.mk
# Define some default flags for linking.
LDLIBS :=
APP_LDLIBS :=
-LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
+LDARCHLIB := -L$(OBJ_DIR)/$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(XEN_TARGET_ARCH).lds
# Prefix for global API names. All other symbols are localised before
@@ -35,14 +36,14 @@ SUBDIRS := lib xenbus console
# The common mini-os objects to build.
APP_OBJS :=
-OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
-OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
-OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
-OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
+OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard *.c))
+OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard lib/*.c))
+OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard xenbus/*.c))
+OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard console/*.c))
.PHONY: default
-default: $(TARGET)
+default: $(OBJ_DIR)/$(TARGET)
# Create special architecture specific links. The function arch_links
# has to be defined in arch.mk (see include above).
@@ -57,7 +58,7 @@ links: $(ARCH_LINKS)
.PHONY: arch_lib
arch_lib:
- $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
+ $(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) || exit 1;
ifeq ($(lwip),y)
# lwIP library
@@ -66,14 +67,14 @@ LWC := $(filter-out %6.c %ip6_addr.c %ethernetif.c, $(LWC))
LWC += lwip-arch.c lwip-net.c
LWO := $(patsubst %.c,%.o,$(LWC))
-lwip.a: $(LWO)
+$(OBJ_DIR)/lwip.a: $(LWO)
$(RM) $@
$(AR) cqs $@ $^
-OBJS += lwip.a
+OBJS += $(OBJ_DIR)/lwip.a
endif
-OBJS := $(filter-out main.o lwip%.o $(LWO), $(OBJS))
+OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS))
ifeq ($(libc),y)
APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -whole-archive -lxenguest -lxenctrl -no-whole-archive
@@ -84,14 +85,14 @@ LDLIBS += -lc
endif
ifneq ($(APP_OBJS)-$(lwip),-y)
-OBJS := $(filter-out daytime.o, $(OBJS))
+OBJS := $(filter-out $(OBJ_DIR)/daytime.o, $(OBJS))
endif
-$(TARGET)_app.o: $(APP_OBJS) app.lds
- $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined app_main -o $@
+$(OBJ_DIR)/$(TARGET)_app.o: $(APP_OBJS) app.lds
+ $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined main -o $@
-$(TARGET): links $(OBJS) $(TARGET)_app.o arch_lib
- $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(TARGET)_app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
+$(OBJ_DIR)/$(TARGET): links $(OBJS) $(OBJ_DIR)/$(TARGET)_app.o arch_lib
+ $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJ_DIR)/$(TARGET)_app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
gzip -f -9 -c $@ >$@.gz
@@ -99,15 +100,15 @@ $(TARGET): links $(OBJS) $(TARGET)_app.o arch_lib
.PHONY: clean arch_clean
arch_clean:
- $(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1;
+ $(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) clean || exit 1;
clean: arch_clean
- for dir in $(SUBDIRS); do \
+ for dir in $(addprefix $(OBJ_DIR)/,$(SUBDIRS)); do \
rm -f $$dir/*.o; \
done
- rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
- find . -type l | xargs rm -f
- $(RM) lwip.a $(LWO)
+ rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf $(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz
+ find . $(OBJ_DIR) -type l | xargs rm -f
+ $(RM) $(OBJ_DIR)/lwip.a $(LWO)
rm -f tags TAGS
diff --git a/extras/mini-os/arch/ia64/Makefile b/extras/mini-os/arch/ia64/Makefile
index 6e46aa67ef..405066215d 100644
--- a/extras/mini-os/arch/ia64/Makefile
+++ b/extras/mini-os/arch/ia64/Makefile
@@ -40,12 +40,13 @@ ARCH_OBJS += __umoddi3.o
ARCH_OBJS += __udivdi3.o
ARCH_OBJS += __udivsi3.o
ARCH_OBJS += __divdi3.o
+ARCH_OBJS := $(addprefix $(OBJ_DIR)/,$(ARCH_OBJS))
GEN_OFF_SRC := gen_off.c
GEN_OFF_ASM := gen_off.s
GEN_OFF_H := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h
-all: $(ARCH_LIB)
+all: $(OBJ_DIR)/$(ARCH_LIB)
$(GEN_OFF_ASM): $(GEN_OFF_SRC)
$(CC) -S -o $@ $(CPPFLAGS) $<
@@ -53,10 +54,10 @@ $(GEN_OFF_ASM): $(GEN_OFF_SRC)
$(GEN_OFF_H): $(GEN_OFF_ASM)
sed -ne "/^->/ {s/->/#define /; p}" < $< > $@
-$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+$(OBJ_DIR)/$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
clean:
- rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+ rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
rm -f $(GEN_OFF_ASM)
rm -f $(GEN_OFF_H)
diff --git a/extras/mini-os/arch/ia64/common.c b/extras/mini-os/arch/ia64/common.c
index cd4cec1e20..c65f0a0d07 100644
--- a/extras/mini-os/arch/ia64/common.c
+++ b/extras/mini-os/arch/ia64/common.c
@@ -236,6 +236,12 @@ arch_init(start_info_t *si)
}
void
+arch_fini(void)
+{
+ /* TODO */
+}
+
+void
arch_print_info(void)
{
int major, minor;
diff --git a/extras/mini-os/arch/ia64/time.c b/extras/mini-os/arch/ia64/time.c
index bbaa6b1864..baf9096330 100644
--- a/extras/mini-os/arch/ia64/time.c
+++ b/extras/mini-os/arch/ia64/time.c
@@ -280,3 +280,9 @@ init_time(void)
ia64_set_itm(new);
ia64_srlz_d();
}
+
+void
+fini_time(void)
+{
+ /* TODO */
+}
diff --git a/extras/mini-os/arch/x86/Makefile b/extras/mini-os/arch/x86/Makefile
index 21f0958f6a..3c5fb6ae78 100644
--- a/extras/mini-os/arch/x86/Makefile
+++ b/extras/mini-os/arch/x86/Makefile
@@ -17,15 +17,15 @@ include ../../minios.mk
ARCH_SRCS := $(wildcard *.c)
# The objects built from the sources.
-ARCH_OBJS := $(patsubst %.c,%.o,$(ARCH_SRCS))
+ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS))
-all: $(ARCH_LIB)
+all: $(OBJ_DIR)/$(ARCH_LIB)
# $(HEAD_ARCH_OBJ) is only build here, needed on linking
# in ../../Makefile.
-$(ARCH_LIB): $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
- $(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
+$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
+ $(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS)
clean:
- rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+ rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
diff --git a/extras/mini-os/arch/x86/mm.c b/extras/mini-os/arch/x86/mm.c
index 50fcc11688..ea8158045b 100644
--- a/extras/mini-os/arch/x86/mm.c
+++ b/extras/mini-os/arch/x86/mm.c
@@ -59,7 +59,7 @@ void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
{
pgentry_t *tab = (pgentry_t *)start_info.pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
- unsigned long prot_e, prot_t;
+ pgentry_t prot_e, prot_t;
mmu_update_t mmu_updates[1];
prot_e = prot_t = 0;
@@ -69,7 +69,7 @@ void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
/* We need to clear the page, otherwise we might fail to map it
as a page table page */
- memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);
+ memset((void*) pt_page, 0, PAGE_SIZE);
switch ( level )
{
@@ -99,7 +99,7 @@ void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
#endif
tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
- mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) +
+ mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) +
sizeof(pgentry_t) * l1_table_offset(pt_page);
mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT |
(prot_e & ~_PAGE_RW);
@@ -372,7 +372,7 @@ static pgentry_t *get_pgt(unsigned long addr)
return &tab[offset];
}
-static pgentry_t *need_pgt(unsigned long addr)
+pgentry_t *need_pgt(unsigned long addr)
{
unsigned long mfn;
pgentry_t *tab;
@@ -474,7 +474,7 @@ void do_map_frames(unsigned long addr,
if (!pgt || !(addr & L1_MASK))
pgt = need_pgt(addr);
mmu_updates[i].ptr = virt_to_mach(pgt);
- mmu_updates[i].val = ((f[(done + i) * stride] + (done + i) * increment) << PAGE_SHIFT) | prot;
+ mmu_updates[i].val = ((pgentry_t)(f[(done + i) * stride] + (done + i) * increment) << PAGE_SHIFT) | prot;
}
rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id);
diff --git a/extras/mini-os/arch/x86/setup.c b/extras/mini-os/arch/x86/setup.c
index ca97131315..3671fee332 100644
--- a/extras/mini-os/arch/x86/setup.c
+++ b/extras/mini-os/arch/x86/setup.c
@@ -100,6 +100,16 @@ arch_init(start_info_t *si)
}
void
+arch_fini(void)
+{
+#ifdef __i386__
+ HYPERVISOR_set_callbacks(0, 0, 0, 0);
+#else
+ HYPERVISOR_set_callbacks(0, 0, 0);
+#endif
+}
+
+void
arch_print_info(void)
{
printk(" stack: %p-%p\n", stack, stack + sizeof(stack));
diff --git a/extras/mini-os/arch/x86/time.c b/extras/mini-os/arch/x86/time.c
index d7b387f95f..4af0b89b94 100644
--- a/extras/mini-os/arch/x86/time.c
+++ b/extras/mini-os/arch/x86/time.c
@@ -222,10 +222,17 @@ static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
+static evtchn_port_t port;
void init_time(void)
{
- evtchn_port_t port;
printk("Initialising timer interface\n");
port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
unmask_evtchn(port);
}
+
+void fini_time(void)
+{
+ /* Clear any pending timer */
+ HYPERVISOR_set_timer_op(0);
+ unbind_evtchn(port);
+}
diff --git a/extras/mini-os/arch/x86/traps.c b/extras/mini-os/arch/x86/traps.c
index 5719f741e1..003ffb52b3 100644
--- a/extras/mini-os/arch/x86/traps.c
+++ b/extras/mini-os/arch/x86/traps.c
@@ -268,3 +268,7 @@ void trap_init(void)
HYPERVISOR_set_trap_table(trap_table);
}
+void trap_fini(void)
+{
+ HYPERVISOR_set_trap_table(NULL);
+}
diff --git a/extras/mini-os/arch/x86/x86_32.S b/extras/mini-os/arch/x86/x86_32.S
index 1dfaf12524..e1426acac0 100644
--- a/extras/mini-os/arch/x86/x86_32.S
+++ b/extras/mini-os/arch/x86/x86_32.S
@@ -8,7 +8,7 @@
.ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
.ascii ",ELF_PADDR_OFFSET=0x0"
.ascii ",HYPERCALL_PAGE=0x2"
- .ascii ",PAE=yes"
+ .ascii ",PAE=yes[extended-cr3]"
.ascii ",LOADER=generic"
.byte 0
.text
diff --git a/extras/mini-os/blkfront.c b/extras/mini-os/blkfront.c
index cb82228523..48704bd1c4 100644
--- a/extras/mini-os/blkfront.c
+++ b/extras/mini-os/blkfront.c
@@ -63,7 +63,8 @@ void blkfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
struct blkfront_dev *dev = data;
int fd = dev->fd;
- files[fd].read = 1;
+ if (fd != -1)
+ files[fd].read = 1;
#endif
wake_up(&blkfront_queue);
}
@@ -105,6 +106,9 @@ struct blkfront_dev *init_blkfront(char *nodename, struct blkfront_info *info)
dev = malloc(sizeof(*dev));
memset(dev, 0, sizeof(*dev));
dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+ dev->fd = -1;
+#endif
snprintf(path, sizeof(path), "%s/backend-id", nodename);
dev->dom = xenbus_read_integer(path);
@@ -238,8 +242,16 @@ void shutdown_blkfront(struct blkfront_dev *dev)
err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
xenbus_wait_for_value(path, "6", &dev->events);
+ err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+ xenbus_wait_for_value(path, "2", &dev->events);
+
xenbus_unwatch_path(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/ring-ref", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/event-channel", nodename);
+ xenbus_rm(XBT_NIL, path);
+
free_blkfront(dev);
}
@@ -323,14 +335,33 @@ void blkfront_aio(struct blkfront_aiocb *aiocbp, int write)
if(notify) notify_remote_via_evtchn(dev->evtchn);
}
-void blkfront_aio_write(struct blkfront_aiocb *aiocbp)
+static void blkfront_aio_cb(struct blkfront_aiocb *aiocbp, int ret)
{
- blkfront_aio(aiocbp, 1);
+ aiocbp->data = (void*) 1;
}
-void blkfront_aio_read(struct blkfront_aiocb *aiocbp)
+void blkfront_io(struct blkfront_aiocb *aiocbp, int write)
{
- blkfront_aio(aiocbp, 0);
+ unsigned long flags;
+ ASSERT(!aiocbp->aio_cb);
+ aiocbp->aio_cb = blkfront_aio_cb;
+ blkfront_aio(aiocbp, write);
+ aiocbp->data = NULL;
+
+ local_irq_save(flags);
+ DEFINE_WAIT(w);
+ while (1) {
+ blkfront_aio_poll(aiocbp->aio_dev);
+ if (aiocbp->data)
+ break;
+
+ add_waiter(w, blkfront_queue);
+ local_irq_restore(flags);
+ schedule();
+ local_irq_save(flags);
+ }
+ remove_waiter(w);
+ local_irq_restore(flags);
}
static void blkfront_push_operation(struct blkfront_dev *dev, uint8_t op, uint64_t id)
@@ -397,8 +428,10 @@ int blkfront_aio_poll(struct blkfront_dev *dev)
moretodo:
#ifdef HAVE_LIBC
- files[dev->fd].read = 0;
- mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
+ if (dev->fd != -1) {
+ files[dev->fd].read = 0;
+ mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
+ }
#endif
rp = dev->ring.sring->rsp_prod;
diff --git a/extras/mini-os/console/console.c b/extras/mini-os/console/console.c
index 29fdd99f3b..3805943465 100644
--- a/extras/mini-os/console/console.c
+++ b/extras/mini-os/console/console.c
@@ -49,17 +49,13 @@
of standard dom0 handled console */
#define USE_XEN_CONSOLE
-/* Low level functions defined in xencons_ring.c */
-extern int xencons_ring_init(void);
-extern int xencons_ring_send(const char *data, unsigned len);
-extern int xencons_ring_send_no_notify(const char *data, unsigned len);
-
/* If console not initialised the printk will be sent to xen serial line
NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
static int console_initialised = 0;
+#ifndef HAVE_LIBC
void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
{
if(len > 0)
@@ -77,6 +73,7 @@ void xencons_tx(void)
{
/* Do nothing, handled by _rx */
}
+#endif
void console_print(char *data, int length)
@@ -153,3 +150,8 @@ void init_console(void)
/* This is also required to notify the daemon */
printk("done.\n");
}
+
+void fini_console(void)
+{
+ /* Destruct the console and get the parameters of the restarted one */
+}
diff --git a/extras/mini-os/console/xencons_ring.c b/extras/mini-os/console/xencons_ring.c
index 583e4bcb92..251a4f95f1 100644
--- a/extras/mini-os/console/xencons_ring.c
+++ b/extras/mini-os/console/xencons_ring.c
@@ -8,6 +8,7 @@
#include <xenbus.h>
#include <xen/io/console.h>
+DECLARE_WAIT_QUEUE_HEAD(console_queue);
static inline struct xencons_interface *xencons_interface(void)
{
@@ -52,6 +53,9 @@ int xencons_ring_send(const char *data, unsigned len)
static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
{
+#ifdef HAVE_LIBC
+ wake_up(&console_queue);
+#else
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
@@ -71,8 +75,48 @@ static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
notify_daemon();
xencons_tx();
+#endif
}
+#ifdef HAVE_LIBC
+int xencons_ring_avail(void)
+{
+ struct xencons_interface *intf = xencons_interface();
+ XENCONS_RING_IDX cons, prod;
+
+ cons = intf->in_cons;
+ prod = intf->in_prod;
+ mb();
+ BUG_ON((prod - cons) > sizeof(intf->in));
+
+ return prod - cons;
+}
+
+int xencons_ring_recv(char *data, unsigned len)
+{
+ struct xencons_interface *intf = xencons_interface();
+ XENCONS_RING_IDX cons, prod;
+ unsigned filled = 0;
+
+ cons = intf->in_cons;
+ prod = intf->in_prod;
+ mb();
+ BUG_ON((prod - cons) > sizeof(intf->in));
+
+ while (filled < len && cons + filled != prod) {
+ data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in));
+ filled++;
+ }
+
+ mb();
+ intf->in_cons = cons + filled;
+
+ notify_daemon();
+
+ return filled;
+}
+#endif
+
int xencons_ring_init(void)
{
int err;
diff --git a/extras/mini-os/events.c b/extras/mini-os/events.c
index f47fc38822..87f54ef5eb 100644
--- a/extras/mini-os/events.c
+++ b/extras/mini-os/events.c
@@ -39,19 +39,29 @@ static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
void unbind_all_ports(void)
{
int i;
+ int cpu = 0;
+ shared_info_t *s = HYPERVISOR_shared_info;
+ vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
for (i = 0; i < NR_EVS; i++)
{
+ if (i == start_info.console.domU.evtchn ||
+ i == start_info.store_evtchn)
+ continue;
if (test_and_clear_bit(i, bound_ports))
{
struct evtchn_close close;
+ printk("port %d still bound!\n", i);
mask_evtchn(i);
close.port = i;
HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ clear_evtchn(i);
}
}
+ vcpu_info->evtchn_upcall_pending = 0;
+ vcpu_info->evtchn_pending_sel = 0;
}
-
+
/*
* Demux events to different handlers.
*/
@@ -86,17 +96,27 @@ evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
ev_actions[port].data = data;
wmb();
ev_actions[port].handler = handler;
+ set_bit(port, bound_ports);
return port;
}
void unbind_evtchn(evtchn_port_t port )
{
+ struct evtchn_close close;
+
if (ev_actions[port].handler == default_handler)
printk("WARN: No handler for port %d when unbinding\n", port);
+ mask_evtchn(port);
+ clear_evtchn(port);
+
ev_actions[port].handler = default_handler;
wmb();
ev_actions[port].data = NULL;
+ clear_bit(port, bound_ports);
+
+ close.port = port;
+ HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
}
evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
@@ -112,7 +132,6 @@ evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
printk("Failed to bind virtual IRQ %d\n", virq);
return -1;
}
- set_bit(op.port,bound_ports);
bind_evtchn(op.port, handler, data);
return op.port;
}
@@ -147,6 +166,15 @@ void init_events(void)
}
}
+void fini_events(void)
+{
+ /* Dealloc all events */
+ unbind_all_ports();
+#if defined(__x86_64__)
+ wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+#endif
+}
+
void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
{
printk("[Port %d] - event received\n", port);
@@ -185,7 +213,6 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
if (err)
return err;
- set_bit(op.local_port,bound_ports);
evtchn_port_t port = op.local_port;
*local_port = bind_evtchn(port, handler, data);
return err;
diff --git a/extras/mini-os/fbfront.c b/extras/mini-os/fbfront.c
index 60c7552d00..245ef468ed 100644
--- a/extras/mini-os/fbfront.c
+++ b/extras/mini-os/fbfront.c
@@ -44,7 +44,8 @@ void kbdfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
struct kbdfront_dev *dev = data;
int fd = dev->fd;
- files[fd].read = 1;
+ if (fd != -1)
+ files[fd].read = 1;
#endif
wake_up(&kbdfront_queue);
}
@@ -83,6 +84,9 @@ struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer)
dev = malloc(sizeof(*dev));
dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+ dev->fd = -1;
+#endif
snprintf(path, sizeof(path), "%s/backend-id", nodename);
dev->dom = xenbus_read_integer(path);
@@ -179,8 +183,10 @@ int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n
int i;
#ifdef HAVE_LIBC
- files[dev->fd].read = 0;
- mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
+ if (dev->fd != -1) {
+ files[dev->fd].read = 0;
+ mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
+ }
#endif
prod = page->in_prod;
@@ -198,7 +204,7 @@ int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n
notify_remote_via_evtchn(dev->evtchn);
#ifdef HAVE_LIBC
- if (cons != prod)
+ if (cons != prod && dev->fd != -1)
/* still some events to read */
files[dev->fd].read = 1;
#endif
@@ -223,8 +229,19 @@ void shutdown_kbdfront(struct kbdfront_dev *dev)
err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
xenbus_wait_for_value(path, "6", &dev->events);
+ err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+ // does not work yet.
+ //xenbus_wait_for_value(path, "2", &dev->events);
+
xenbus_unwatch_path(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/page-ref", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/event-channel", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename);
+ xenbus_rm(XBT_NIL, path);
+
free_kbdfront(dev);
}
@@ -279,7 +296,8 @@ void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
struct fbfront_dev *dev = data;
int fd = dev->fd;
- files[fd].read = 1;
+ if (fd != -1)
+ files[fd].read = 1;
#endif
wake_up(&fbfront_queue);
}
@@ -305,8 +323,10 @@ int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n)
int i;
#ifdef HAVE_LIBC
- files[dev->fd].read = 0;
- mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
+ if (dev->fd != -1) {
+ files[dev->fd].read = 0;
+ mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
+ }
#endif
prod = page->in_prod;
@@ -324,7 +344,7 @@ int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n)
notify_remote_via_evtchn(dev->evtchn);
#ifdef HAVE_LIBC
- if (cons != prod)
+ if (cons != prod && dev->fd != -1)
/* still some events to read */
files[dev->fd].read = 1;
#endif
@@ -352,6 +372,9 @@ struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int width,
dev = malloc(sizeof(*dev));
dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+ dev->fd = -1;
+#endif
snprintf(path, sizeof(path), "%s/backend-id", nodename);
dev->dom = xenbus_read_integer(path);
@@ -547,8 +570,21 @@ void shutdown_fbfront(struct fbfront_dev *dev)
err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
xenbus_wait_for_value(path, "6", &dev->events);
+ err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+ // does not work yet
+ //xenbus_wait_for_value(path, "2", &dev->events);
+
xenbus_unwatch_path(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/page-ref", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/event-channel", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/protocol", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/feature-update", nodename);
+ xenbus_rm(XBT_NIL, path);
+
unbind_evtchn(dev->evtchn);
free_fbfront(dev);
diff --git a/extras/mini-os/fs-front.c b/extras/mini-os/fs-front.c
index 5b7bc6a4a2..0b27df361b 100644
--- a/extras/mini-os/fs-front.c
+++ b/extras/mini-os/fs-front.c
@@ -1127,3 +1127,5 @@ void init_fs_frontend(void)
if (!fs_import)
printk("No FS import\n");
}
+
+/* TODO: shutdown */
diff --git a/extras/mini-os/gnttab.c b/extras/mini-os/gnttab.c
index dd66b043bf..18fd87e29c 100644
--- a/extras/mini-os/gnttab.c
+++ b/extras/mini-os/gnttab.c
@@ -35,7 +35,7 @@ static grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
#ifdef GNT_DEBUG
static char inuse[NR_GRANT_ENTRIES];
#endif
-static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, NR_GRANT_ENTRIES);
+static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, 0);
static void
put_free_entry(grant_ref_t ref)
@@ -60,6 +60,7 @@ get_free_entry(void)
down(&gnttab_sem);
local_irq_save(flags);
ref = gnttab_list[0];
+ BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES);
gnttab_list[0] = gnttab_list[ref];
#ifdef GNT_DEBUG
BUG_ON(inuse[ref]);
@@ -193,3 +194,14 @@ init_gnttab(void)
gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
printk("gnttab_table mapped at %p.\n", gnttab_table);
}
+
+void
+fini_gnttab(void)
+{
+ struct gnttab_setup_table setup;
+
+ setup.dom = DOMID_SELF;
+ setup.nr_frames = 0;
+
+ HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+}
diff --git a/extras/mini-os/include/blkfront.h b/extras/mini-os/include/blkfront.h
index c8de59d335..a4e691140f 100644
--- a/extras/mini-os/include/blkfront.h
+++ b/extras/mini-os/include/blkfront.h
@@ -29,8 +29,11 @@ struct blkfront_dev *init_blkfront(char *nodename, struct blkfront_info *info);
int blkfront_open(struct blkfront_dev *dev);
#endif
void blkfront_aio(struct blkfront_aiocb *aiocbp, int write);
-void blkfront_aio_read(struct blkfront_aiocb *aiocbp);
-void blkfront_aio_write(struct blkfront_aiocb *aiocbp);
+#define blkfront_aio_read(aiocbp) blkfront_aio(aiocbp, 0)
+#define blkfront_aio_write(aiocbp) blkfront_aio(aiocbp, 1)
+void blkfront_io(struct blkfront_aiocb *aiocbp, int write);
+#define blkfront_read(aiocbp) blkfront_io(aiocbp, 0)
+#define blkfront_write(aiocbp) blkfront_io(aiocbp, 1)
void blkfront_aio_push_operation(struct blkfront_aiocb *aiocbp, uint8_t op);
int blkfront_aio_poll(struct blkfront_dev *dev);
void blkfront_sync(struct blkfront_dev *dev);
diff --git a/extras/mini-os/include/byteswap.h b/extras/mini-os/include/byteswap.h
index 7c4ffe393c..6d97f78f74 100644
--- a/extras/mini-os/include/byteswap.h
+++ b/extras/mini-os/include/byteswap.h
@@ -2,21 +2,32 @@
#define _BYTESWAP_H_
/* Unfortunately not provided by newlib. */
-#define bswap_16(x) \
- ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8))
-#define bswap_32(x) \
- ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
- (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+#include <types.h>
+static inline uint16_t bswap_16(uint16_t x)
+{
+ return
+ ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8));
+}
-#define bswap_64(x) \
- ((((x) & 0xff00000000000000ULL) >> 56) | \
- (((x) & 0x00ff000000000000ULL) >> 40) | \
- (((x) & 0x0000ff0000000000ULL) >> 24) | \
- (((x) & 0x000000ff00000000ULL) >> 8) | \
- (((x) & 0x00000000ff000000ULL) << 8) | \
- (((x) & 0x0000000000ff0000ULL) << 24) | \
- (((x) & 0x000000000000ff00ULL) << 40) | \
- (((x) & 0x00000000000000ffULL) << 56))
+static inline uint32_t bswap_32(uint32_t x)
+{
+ return
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) |
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
+}
+
+static inline uint64_t bswap_64(uint64_t x)
+{
+ return
+ ((((x) & 0xff00000000000000ULL) >> 56) |
+ (((x) & 0x00ff000000000000ULL) >> 40) |
+ (((x) & 0x0000ff0000000000ULL) >> 24) |
+ (((x) & 0x000000ff00000000ULL) >> 8) |
+ (((x) & 0x00000000ff000000ULL) << 8) |
+ (((x) & 0x0000000000ff0000ULL) << 24) |
+ (((x) & 0x000000000000ff00ULL) << 40) |
+ (((x) & 0x00000000000000ffULL) << 56));
+}
#endif /* _BYTESWAP_H */
diff --git a/extras/mini-os/include/console.h b/extras/mini-os/include/console.h
index 9ace8dfcb1..4a61f1aaa0 100644
--- a/extras/mini-os/include/console.h
+++ b/extras/mini-os/include/console.h
@@ -51,5 +51,15 @@ void xencons_tx(void);
void init_console(void);
void console_print(char *data, int length);
+void fini_console(void);
+
+/* Low level functions defined in xencons_ring.c */
+extern struct wait_queue_head console_queue;
+int xencons_ring_init(void);
+int xencons_ring_send(const char *data, unsigned len);
+int xencons_ring_send_no_notify(const char *data, unsigned len);
+int xencons_ring_avail(void);
+int xencons_ring_recv(char *data, unsigned len);
+
#endif /* _LIB_CONSOLE_H_ */
diff --git a/extras/mini-os/include/events.h b/extras/mini-os/include/events.h
index ff202e38fe..9ffb35d320 100644
--- a/extras/mini-os/include/events.h
+++ b/extras/mini-os/include/events.h
@@ -45,5 +45,6 @@ static inline int notify_remote_via_evtchn(evtchn_port_t port)
return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
}
+void fini_events(void);
#endif /* _EVENTS_H_ */
diff --git a/extras/mini-os/include/gnttab.h b/extras/mini-os/include/gnttab.h
index f952442955..acd6c39f8c 100644
--- a/extras/mini-os/include/gnttab.h
+++ b/extras/mini-os/include/gnttab.h
@@ -11,5 +11,6 @@ grant_ref_t gnttab_grant_transfer(domid_t domid, unsigned long pfn);
unsigned long gnttab_end_transfer(grant_ref_t gref);
int gnttab_end_access(grant_ref_t ref);
const char *gnttabop_error(int16_t status);
+void fini_gnttab(void);
#endif /* !__GNTTAB_H__ */
diff --git a/extras/mini-os/include/ia64/os.h b/extras/mini-os/include/ia64/os.h
index 2ae5331393..bf3785fc82 100644
--- a/extras/mini-os/include/ia64/os.h
+++ b/extras/mini-os/include/ia64/os.h
@@ -35,6 +35,7 @@
#include "sal.h"
#include "pal.h"
#include "hypervisor.h"
+#include <kernel.h>
typedef uint64_t paddr_t; /* Physical address. */
@@ -46,9 +47,9 @@ typedef uint64_t caddr_t; /* rr7/kernel memory address. */
#include "mm.h"
-void do_exit(void) __attribute__((noreturn));
void arch_init(start_info_t *si); /* in common.c */
void arch_print_info(void); /* in common.c */
+void arch_fini(void);
/* Size of xen_ia64_boot_param.command_line */
diff --git a/extras/mini-os/include/ia64/traps.h b/extras/mini-os/include/ia64/traps.h
index 4c5e7be527..e79a952aec 100644
--- a/extras/mini-os/include/ia64/traps.h
+++ b/extras/mini-os/include/ia64/traps.h
@@ -38,6 +38,10 @@ inline static void trap_init(void)
{
//printk("trap_init() until now not needed!\n");
}
+inline static void trap_fini(void)
+{
+ //printk("trap_fini() until now not needed!\n");
+}
#endif /* !defined(__ASSEMBLY__) */
diff --git a/extras/mini-os/include/kernel.h b/extras/mini-os/include/kernel.h
new file mode 100644
index 0000000000..b36f172ed8
--- /dev/null
+++ b/extras/mini-os/include/kernel.h
@@ -0,0 +1,7 @@
+#ifndef _KERNEL_H_
+#define _KERNEL_H_
+
+extern void do_exit(void) __attribute__((noreturn));
+extern void stop_kernel(void);
+
+#endif /* _KERNEL_H_ */
diff --git a/extras/mini-os/include/mm.h b/extras/mini-os/include/mm.h
index 28fb727f9f..7c8588ccf8 100644
--- a/extras/mini-os/include/mm.h
+++ b/extras/mini-os/include/mm.h
@@ -75,5 +75,6 @@ extern unsigned long heap, brk, heap_mapped, heap_end;
#endif
int free_physical_pages(xen_pfn_t *mfns, int n);
+void fini_mm(void);
#endif /* _MM_H_ */
diff --git a/extras/mini-os/include/netfront.h b/extras/mini-os/include/netfront.h
index 526dc94b5c..681ebf2c0f 100644
--- a/extras/mini-os/include/netfront.h
+++ b/extras/mini-os/include/netfront.h
@@ -18,6 +18,7 @@ extern struct wait_queue_head netfront_queue;
* N.B. _must_ be called from a thread; it's not safe to call this from
* app_main(). */
void start_networking(void);
+void stop_networking(void);
void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw);
#endif
diff --git a/extras/mini-os/include/time.h b/extras/mini-os/include/time.h
index e28bf171d7..250af5c5cf 100644
--- a/extras/mini-os/include/time.h
+++ b/extras/mini-os/include/time.h
@@ -54,6 +54,7 @@ typedef long suseconds_t;
/* prototypes */
void init_time(void);
+void fini_time(void);
s_time_t get_s_time(void);
s_time_t get_v_time(void);
u64 monotonic_clock(void);
diff --git a/extras/mini-os/include/wait.h b/extras/mini-os/include/wait.h
index cbcaab3519..2947d33150 100644
--- a/extras/mini-os/include/wait.h
+++ b/extras/mini-os/include/wait.h
@@ -87,9 +87,9 @@ static inline void wake_up(struct wait_queue_head *head)
#define wait_event_deadline(wq, condition, deadline) do { \
unsigned long flags; \
+ DEFINE_WAIT(__wait); \
if(condition) \
break; \
- DEFINE_WAIT(__wait); \
for(;;) \
{ \
/* protect the list */ \
diff --git a/extras/mini-os/include/x86/arch_mm.h b/extras/mini-os/include/x86/arch_mm.h
index 580955d223..4a04812891 100644
--- a/extras/mini-os/include/x86/arch_mm.h
+++ b/extras/mini-os/include/x86/arch_mm.h
@@ -109,16 +109,16 @@ typedef unsigned long pgentry_t;
(((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
#endif
-#define _PAGE_PRESENT 0x001UL
-#define _PAGE_RW 0x002UL
-#define _PAGE_USER 0x004UL
-#define _PAGE_PWT 0x008UL
-#define _PAGE_PCD 0x010UL
-#define _PAGE_ACCESSED 0x020UL
-#define _PAGE_DIRTY 0x040UL
-#define _PAGE_PAT 0x080UL
-#define _PAGE_PSE 0x080UL
-#define _PAGE_GLOBAL 0x100UL
+#define _PAGE_PRESENT 0x001ULL
+#define _PAGE_RW 0x002ULL
+#define _PAGE_USER 0x004ULL
+#define _PAGE_PWT 0x008ULL
+#define _PAGE_PCD 0x010ULL
+#define _PAGE_ACCESSED 0x020ULL
+#define _PAGE_DIRTY 0x040ULL
+#define _PAGE_PAT 0x080ULL
+#define _PAGE_PSE 0x080ULL
+#define _PAGE_GLOBAL 0x100ULL
#if defined(__i386__)
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
@@ -140,7 +140,7 @@ typedef unsigned long pgentry_t;
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
#define PFN_DOWN(x) ((x) >> L1_PAGETABLE_SHIFT)
-#define PFN_PHYS(x) ((x) << L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x) ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
#define PHYS_PFN(x) ((x) >> L1_PAGETABLE_SHIFT)
/* to align the pointer to the (next) page boundary */
@@ -221,4 +221,6 @@ static __inline__ paddr_t machine_to_phys(maddr_t machine)
#define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, L1_PROT_RO)
#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO)
+pgentry_t *need_pgt(unsigned long addr);
+
#endif /* _ARCH_MM_H_ */
diff --git a/extras/mini-os/include/x86/os.h b/extras/mini-os/include/x86/os.h
index 1cab0a73db..39faa0395d 100644
--- a/extras/mini-os/include/x86/os.h
+++ b/extras/mini-os/include/x86/os.h
@@ -18,10 +18,10 @@
#ifndef __ASSEMBLY__
#include <types.h>
#include <hypervisor.h>
+#include <kernel.h>
#define USED __attribute__ ((used))
-extern void do_exit(void) __attribute__((noreturn));
#define BUG do_exit
#endif
@@ -61,9 +61,11 @@ extern void do_exit(void) __attribute__((noreturn));
extern shared_info_t *HYPERVISOR_shared_info;
void trap_init(void);
+void trap_fini(void);
void arch_init(start_info_t *si);
void arch_print_info(void);
+void arch_fini(void);
diff --git a/extras/mini-os/include/xenbus.h b/extras/mini-os/include/xenbus.h
index 2ed370f252..f1585c9f70 100644
--- a/extras/mini-os/include/xenbus.h
+++ b/extras/mini-os/include/xenbus.h
@@ -90,4 +90,7 @@ char* xenbus_printf(xenbus_transaction_t xbt,
char* node, char* path,
char* fmt, ...);
+/* Reset the XenBus system. */
+void fini_xenbus(void);
+
#endif /* XENBUS_H__ */
diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c
index ea92adca6a..e02b85880f 100644
--- a/extras/mini-os/kernel.c
+++ b/extras/mini-os/kernel.c
@@ -46,6 +46,7 @@
#include <xen/features.h>
#include <xen/version.h>
+static struct netfront_dev *net_dev;
u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
@@ -87,7 +88,7 @@ static void periodic_thread(void *p)
static void netfront_thread(void *p)
{
- init_netfront(NULL, NULL, NULL, NULL);
+ net_dev = init_netfront(NULL, NULL, NULL, NULL);
}
static struct blkfront_dev *blk_dev;
@@ -347,9 +348,9 @@ static void refresh_cursor(int new_x, int new_y)
fbfront_update(fb_dev, new_x, new_y, 9, 9);
}
+static struct kbdfront_dev *kbd_dev;
static void kbdfront_thread(void *p)
{
- struct kbdfront_dev *kbd_dev;
DEFINE_WAIT(w);
int x = WIDTH / 2, y = HEIGHT / 2, z = 0;
@@ -509,6 +510,49 @@ void start_kernel(start_info_t *si)
run_idle_thread();
}
+void stop_kernel(void)
+{
+ if (net_dev)
+ shutdown_netfront(net_dev);
+
+ if (blk_dev)
+ shutdown_blkfront(blk_dev);
+
+ if (fb_dev)
+ shutdown_fbfront(fb_dev);
+
+ if (kbd_dev)
+ shutdown_kbdfront(kbd_dev);
+
+ /* TODO: fs import */
+
+ local_irq_disable();
+
+ /* Reset grant tables */
+ fini_gnttab();
+
+ /* Reset the console driver. */
+ fini_console();
+ /* TODO: record new ring mfn & event in start_info */
+
+ /* Reset XenBus */
+ fini_xenbus();
+
+ /* Reset timers */
+ fini_time();
+
+ /* Reset memory management. */
+ fini_mm();
+
+ /* Reset events. */
+ fini_events();
+
+ /* Reset traps */
+ trap_fini();
+
+ /* Reset arch details */
+ arch_fini();
+}
/*
* do_exit: This is called whenever an IRET fails in entry.S.
diff --git a/extras/mini-os/lib/sys.c b/extras/mini-os/lib/sys.c
index 004e300728..06f2822cfe 100644
--- a/extras/mini-os/lib/sys.c
+++ b/extras/mini-os/lib/sys.c
@@ -43,7 +43,9 @@
#include <stdlib.h>
#include <math.h>
+#ifdef HAVE_LWIP
#include <lwip/sockets.h>
+#endif
#include <fs.h>
#define debug(fmt, ...) \
@@ -213,8 +215,19 @@ int isatty(int fd)
int read(int fd, void *buf, size_t nbytes)
{
switch (files[fd].type) {
- case FTYPE_CONSOLE:
- return 0;
+ case FTYPE_CONSOLE: {
+ int ret;
+ DEFINE_WAIT(w);
+ while(1) {
+ add_waiter(w, console_queue);
+ ret = xencons_ring_recv(buf, nbytes);
+ if (ret)
+ break;
+ schedule();
+ }
+ remove_waiter(w);
+ return ret;
+ }
case FTYPE_FILE: {
ssize_t ret;
if (nbytes > PAGE_SIZE)
@@ -229,8 +242,10 @@ int read(int fd, void *buf, size_t nbytes)
}
return 0;
}
+#ifdef HAVE_LWIP
case FTYPE_SOCKET:
return lwip_read(files[fd].socket.fd, buf, nbytes);
+#endif
case FTYPE_TAP: {
ssize_t ret;
ret = netfront_receive(files[fd].tap.dev, buf, nbytes);
@@ -288,8 +303,10 @@ int write(int fd, const void *buf, size_t nbytes)
}
return 0;
}
+#ifdef HAVE_LWIP
case FTYPE_SOCKET:
return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
+#endif
case FTYPE_TAP:
netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes);
return nbytes;
@@ -356,7 +373,7 @@ int close(int fd)
{
printk("close(%d)\n", fd);
switch (files[fd].type) {
- case FTYPE_CONSOLE:
+ default:
files[fd].type = FTYPE_NONE;
return 0;
case FTYPE_FILE: {
@@ -371,11 +388,13 @@ int close(int fd)
case FTYPE_XENBUS:
xs_daemon_close((void*)(intptr_t) fd);
return 0;
+#ifdef HAVE_LWIP
case FTYPE_SOCKET: {
int res = lwip_close(files[fd].socket.fd);
files[fd].type = FTYPE_NONE;
return res;
}
+#endif
case FTYPE_XC:
xc_interface_close(fd);
return 0;
@@ -544,6 +563,7 @@ int fcntl(int fd, int cmd, ...)
va_end(ap);
switch (cmd) {
+#ifdef HAVE_LWIP
case F_SETFL:
if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) {
/* Only flag supported: non-blocking mode */
@@ -551,6 +571,7 @@ int fcntl(int fd, int cmd, ...)
return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock);
}
/* Fallthrough */
+#endif
default:
printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg);
errno = ENOSYS;
@@ -655,9 +676,12 @@ static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *except
/* Just poll without blocking */
static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
{
- int i, n = 0, sock_n, sock_nfds = 0;
+ int i, n = 0;
+#ifdef HAVE_LWIP
+ int sock_n, sock_nfds = 0;
fd_set sock_readfds, sock_writefds, sock_exceptfds;
struct timeval timeout = { .tv_sec = 0, .tv_usec = 0};
+#endif
#ifdef LIBC_VERBOSE
static int nb;
@@ -667,6 +691,7 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce
nb++;
#endif
+#ifdef HAVE_LWIP
/* first poll network */
FD_ZERO(&sock_readfds);
FD_ZERO(&sock_writefds);
@@ -693,6 +718,7 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce
sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
DEBUG("\n");
+#endif
/* Then see others as well. */
for (i = 0; i < nfds; i++) {
@@ -707,7 +733,12 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce
FD_CLR(i, exceptfds);
break;
case FTYPE_CONSOLE:
- FD_CLR(i, readfds);
+ if (FD_ISSET(i, writefds)) {
+ if (xencons_ring_avail())
+ n++;
+ else
+ FD_CLR(i, readfds);
+ }
if (FD_ISSET(i, writefds))
n++;
FD_CLR(i, exceptfds);
@@ -736,6 +767,7 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce
FD_CLR(i, writefds);
FD_CLR(i, exceptfds);
break;
+#ifdef HAVE_LWIP
case FTYPE_SOCKET:
if (FD_ISSET(i, readfds)) {
/* Optimize no-network-packet case. */
@@ -757,6 +789,7 @@ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exce
FD_CLR(i, exceptfds);
}
break;
+#endif
}
#ifdef LIBC_VERBOSE
if (FD_ISSET(i, readfds))
@@ -809,6 +842,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
DEFINE_WAIT(w3);
DEFINE_WAIT(w4);
DEFINE_WAIT(w5);
+ DEFINE_WAIT(w6);
assert(thread == main_thread);
@@ -830,6 +864,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
add_waiter(w3, blkfront_queue);
add_waiter(w4, xenbus_watch_queue);
add_waiter(w5, kbdfront_queue);
+ add_waiter(w6, console_queue);
if (readfds)
myread = *readfds;
@@ -916,9 +951,11 @@ out:
remove_waiter(w3);
remove_waiter(w4);
remove_waiter(w5);
+ remove_waiter(w6);
return ret;
}
+#ifdef HAVE_LWIP
int socket(int domain, int type, int protocol)
{
int fd, res;
@@ -970,6 +1007,7 @@ LWIP_STUB(ssize_t, recvfrom, (int s, void *buf, size_t len, int flags, struct so
LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, len, flags))
LWIP_STUB(ssize_t, sendto, (int s, void *buf, size_t len, int flags, struct sockaddr *to, socklen_t tolen), (s, buf, len, flags, to, tolen))
LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen))
+#endif
int nanosleep(const struct timespec *req, struct timespec *rem)
{
diff --git a/extras/mini-os/lwip-net.c b/extras/mini-os/lwip-net.c
index 2e68279c6f..4e7ffbdabf 100644
--- a/extras/mini-os/lwip-net.c
+++ b/extras/mini-os/lwip-net.c
@@ -376,3 +376,9 @@ void start_networking(void)
tprintk("Network is ready.\n");
}
+
+/* Shut down the network */
+void stop_networking(void)
+{
+ shutdown_netfront(dev);
+}
diff --git a/extras/mini-os/main.c b/extras/mini-os/main.c
index 22c7be1704..dac185a528 100644
--- a/extras/mini-os/main.c
+++ b/extras/mini-os/main.c
@@ -4,6 +4,7 @@
* Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
*/
+#ifdef HAVE_LIBC
#include <os.h>
#include <sched.h>
#include <console.h>
@@ -41,24 +42,30 @@ void _fini(void)
extern char __app_bss_start, __app_bss_end;
static void call_main(void *p)
{
- char *args, /**path,*/ *msg, *c;
+ char *c;
#ifdef CONFIG_QEMU
- char *domargs;
+ char *domargs, *msg;
#endif
int argc;
char **argv;
char *envp[] = { NULL };
+#ifdef CONFIG_QEMU
char *vm;
- int i;
char path[128];
+#endif
+ int i;
/* Let other parts initialize (including console output) before maybe
* crashing. */
//sleep(1);
+#ifndef CONFIG_GRUB
sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start);
+#ifdef HAVE_LWIP
start_networking();
+#endif
init_fs_frontend();
+#endif
#ifdef CONFIG_QEMU
if (!fs_import) {
@@ -92,22 +99,6 @@ static void call_main(void *p)
}
#endif
- msg = xenbus_read(XBT_NIL, "vm", &vm);
- if (msg) {
- printk("Couldn't read vm path\n");
- do_exit();
- }
-
- printk("my vm is at %s\n", vm);
- snprintf(path, sizeof(path), "%s/image/cmdline", vm);
- free(vm);
- msg = xenbus_read(XBT_NIL, path, &args);
-
- if (msg) {
- printk("Couldn't get my args: %s\n", msg);
- args = strdup("");
- }
-
argc = 1;
#define PARSE_ARGS(ARGS,START,END) \
@@ -124,7 +115,7 @@ static void call_main(void *p)
} \
}
- PARSE_ARGS(args, argc++, );
+ PARSE_ARGS((char*)start_info.cmd_line, argc++, );
#ifdef CONFIG_QEMU
PARSE_ARGS(domargs, argc++, );
#endif
@@ -133,7 +124,7 @@ static void call_main(void *p)
argv[0] = "main";
argc = 1;
- PARSE_ARGS(args, argv[argc++] = c, *c++ = 0)
+ PARSE_ARGS((char*)start_info.cmd_line, argv[argc++] = c, *c++ = 0)
#ifdef CONFIG_QEMU
PARSE_ARGS(domargs, argv[argc++] = c, *c++ = 0)
#endif
@@ -162,7 +153,10 @@ void _exit(int ret)
close_all_files();
__libc_fini_array();
printk("main returned %d\n", ret);
- unbind_all_ports();
+#ifdef HAVE_LWIP
+ stop_networking();
+#endif
+ stop_kernel();
if (!ret) {
/* No problem, just shutdown. */
struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
@@ -177,3 +171,4 @@ int app_main(start_info_t *si)
main_thread = create_thread("main", call_main, si);
return 0;
}
+#endif
diff --git a/extras/mini-os/minios.mk b/extras/mini-os/minios.mk
index 2282a187e2..cc45c2d4f5 100644
--- a/extras/mini-os/minios.mk
+++ b/extras/mini-os/minios.mk
@@ -57,13 +57,13 @@ ARCH_LIB := lib$(ARCH_LIB_NAME).a
# This object contains the entrypoint for startup from Xen.
# $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
HEAD_ARCH_OBJ := $(XEN_TARGET_ARCH).o
-HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
+HEAD_OBJ := $(OBJ_DIR)/$(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
-%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
+$(OBJ_DIR)/%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
-%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
+$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
$(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
diff --git a/extras/mini-os/mm.c b/extras/mini-os/mm.c
index bc56030a25..fbb155881a 100644
--- a/extras/mini-os/mm.c
+++ b/extras/mini-os/mm.c
@@ -419,6 +419,10 @@ void init_mm(void)
arch_init_demand_mapping_area(max_pfn);
}
+void fini_mm(void)
+{
+}
+
void sanity_check(void)
{
int x;
diff --git a/extras/mini-os/netfront.c b/extras/mini-os/netfront.c
index 5918853372..d01ce6927b 100644
--- a/extras/mini-os/netfront.c
+++ b/extras/mini-os/netfront.c
@@ -259,7 +259,8 @@ void netfront_select_handler(evtchn_port_t port, struct pt_regs *regs, void *dat
network_tx_buf_gc(dev);
local_irq_restore(flags);
- files[fd].read = 1;
+ if (fd != -1)
+ files[fd].read = 1;
wake_up(&netfront_queue);
}
#endif
@@ -323,6 +324,9 @@ struct netfront_dev *init_netfront(char *nodename, void (*thenetif_rx)(unsigned
dev = malloc(sizeof(*dev));
memset(dev, 0, sizeof(*dev));
dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+ dev->fd = -1;
+#endif
printk("net TX ring size %d\n", NET_TX_RING_SIZE);
printk("net RX ring size %d\n", NET_RX_RING_SIZE);
@@ -493,14 +497,27 @@ void shutdown_netfront(struct netfront_dev *dev)
printk("close network: backend at %s\n",dev->backend);
snprintf(path, sizeof(path), "%s/state", dev->backend);
+
err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
xenbus_wait_for_value(path, "5", &dev->events);
err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
xenbus_wait_for_value(path, "6", &dev->events);
+ err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+ xenbus_wait_for_value(path, "2", &dev->events);
+
xenbus_unwatch_path(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/tx-ring-ref", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/rx-ring-ref", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/event-channel", nodename);
+ xenbus_rm(XBT_NIL, path);
+ snprintf(path, sizeof(path), "%s/request-rx-copy", nodename);
+ xenbus_rm(XBT_NIL, path);
+
free_netfront(dev);
}
@@ -597,7 +614,7 @@ ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t l
local_irq_save(flags);
network_rx(dev);
- if (!dev->rlen)
+ if (!dev->rlen && fd != -1)
/* No data for us, make select stop returning */
files[fd].read = 0;
/* Before re-enabling the interrupts, in case a packet just arrived in the
diff --git a/extras/mini-os/xenbus/xenbus.c b/extras/mini-os/xenbus/xenbus.c
index 9065510e70..8e721caec0 100644
--- a/extras/mini-os/xenbus/xenbus.c
+++ b/extras/mini-os/xenbus/xenbus.c
@@ -124,7 +124,7 @@ char* xenbus_wait_for_value(const char* path, const char* value, xenbus_event_qu
static void xenbus_thread_func(void *ign)
{
struct xsd_sockmsg msg;
- unsigned prod = 0;
+ unsigned prod = xenstore_buf->rsp_prod;
for (;;)
{
@@ -174,9 +174,14 @@ static void xenbus_thread_func(void *ign)
break;
}
- event->next = *events;
- *events = event;
- wake_up(&xenbus_watch_queue);
+ if (events) {
+ event->next = *events;
+ *events = event;
+ wake_up(&xenbus_watch_queue);
+ } else {
+ printk("unexpected watch token %s\n", event->token);
+ free(event);
+ }
}
else
@@ -265,6 +270,10 @@ void init_xenbus(void)
DEBUG("xenbus on irq %d\n", err);
}
+void fini_xenbus(void)
+{
+}
+
/* Send data to xenbus. This can block. All of the requests are seen
by xenbus as if sent atomically. The header is added
automatically, using type %type, req_id %req_id, and trans_id