diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2008-06-19 12:46:26 +0900 |
---|---|---|
committer | Isaku Yamahata <yamahata@valinux.co.jp> | 2008-06-19 12:46:26 +0900 |
commit | d20f38afdaf61331547a3436e9d7311b75628d21 (patch) | |
tree | 0eab6105ee58ad8397365ce5d4d598ad049f70e7 /extras | |
parent | 006dff9e0417b59020b675f1b0ee49713a9a5739 (diff) | |
parent | d9a2559fc45a21e727e44a5261695dbbba8a517b (diff) | |
download | xen-d20f38afdaf61331547a3436e9d7311b75628d21.tar.gz xen-d20f38afdaf61331547a3436e9d7311b75628d21.tar.bz2 xen-d20f38afdaf61331547a3436e9d7311b75628d21.zip |
merge with xen-unstable.hg
Diffstat (limited to 'extras')
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 |