[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Mini-os console
The patch implements console for Mini-os. It also fixes 2 bugs: a) in initialising new page table frames b) in initialising idle thread. Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx> Could you apply Keir? Thanks Gregor diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/Makefile --- a/extras/mini-os/Makefile Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/Makefile Wed Mar 15 19:09:01 2006 @@ -32,7 +32,7 @@ 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,%.o,$(wildcard console/*.c)) HDRS := $(wildcard include/*.h) HDRS += $(wildcard include/xen/*.h) diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/events.c --- a/extras/mini-os/events.c Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/events.c Wed Mar 15 19:09:01 2006 @@ -21,6 +21,7 @@ #include <hypervisor.h> #include <events.h> #include <lib.h> + static ev_action_t ev_actions[NR_EVS]; void default_handler(int port, struct pt_regs *regs); @@ -58,7 +59,7 @@ int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) ) { - if(ev_actions[port].handler) + if(ev_actions[port].handler != default_handler) printk("WARN: Handler for port %d already registered, replacing\n", port); @@ -73,7 +74,7 @@ void unbind_evtchn( u32 port ) { - if (!ev_actions[port].handler) + if (ev_actions[port].handler) printk("WARN: No handler for port %d when unbinding\n", port); ev_actions[port].handler = NULL; ev_actions[port].status |= EVS_DISABLED; diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/include/lib.h --- a/extras/mini-os/include/lib.h Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/include/lib.h Wed Mar 15 19:09:01 2006 @@ -56,13 +56,10 @@ #define _LIB_H_ #include <stdarg.h> - +#include <console.h> /* printing */ -#define printk printf -#define kprintf printf #define _p(_x) ((void *)(unsigned long)(_x)) -void printf(const char *fmt, ...); int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); int snprintf(char * buf, size_t size, const char *fmt, ...); diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/kernel.c Wed Mar 15 19:09:01 2006 @@ -76,6 +76,8 @@ } +extern void init_console(void); + /* * INITIAL C ENTRY POINT. */ @@ -127,15 +129,19 @@ /* set up events */ init_events(); + /* init time and timers */ init_time(); - + + /* init the console driver */ + init_console(); + /* init scheduler */ init_sched(); /* init xenbus */ xs_init(); - + /* Everything initialised, start idle thread */ run_idle_thread(); } diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/lib/printf.c --- a/extras/mini-os/lib/printf.c Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/lib/printf.c Wed Mar 15 19:09:01 2006 @@ -556,19 +556,6 @@ return i; } - -void printf(const char *fmt, ...) -{ - static char buf[1024]; - va_list args; - - va_start(args, fmt); - (void)vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - - (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); -} - /** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/mm.c --- a/extras/mini-os/mm.c Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/mm.c Wed Mar 15 19:09:01 2006 @@ -380,6 +380,10 @@ "prev_l_mfn=%lx, offset=%lx\n", level, *pt_pfn, prev_l_mfn, offset); + /* 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); + if (level == L1_FRAME) { prot_e = L1_PROT; diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/sched.c --- a/extras/mini-os/sched.c Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/sched.c Wed Mar 15 19:09:01 2006 @@ -46,6 +46,7 @@ #include <sched.h> #include <semaphore.h> + #ifdef SCHED_DEBUG #define DEBUG(_f, _a...) \ printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a) @@ -61,7 +62,7 @@ #define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG) -struct thread *idle_thread; +struct thread *idle_thread = NULL; LIST_HEAD(exited_threads); void dump_stack(struct thread *thread) @@ -225,7 +226,6 @@ for(;;) { schedule(); - printk("Blocking the domain\n"); block_domain(10000); } } diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/console/console.c --- /dev/null Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/console/console.c Wed Mar 15 19:09:01 2006 @@ -0,0 +1,149 @@ +/* + **************************************************************************** + * (C) 2006 - Grzegorz Milos - Cambridge University + **************************************************************************** + * + * File: console.h + * Author: Grzegorz Milos + * Changes: + * + * Date: Mar 2006 + * + * Environment: Xen Minimal OS + * Description: Console interface. + * + * Handles console I/O. Defines printk. + * + **************************************************************************** + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <types.h> +#include <wait.h> +#include <mm.h> +#include <hypervisor.h> +#include <events.h> +#include <os.h> +#include <lib.h> +#include <xenbus.h> +#include <xen/io/console.h> + + +/* 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; + + +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) +{ + if(len > 0) + { + /* Just repeat what's written */ + buf[len] = '\0'; + printk("%s", buf); + + if(buf[len-1] == '\r') + printk("\nNo console input handler.\n"); + } +} + +void xencons_tx(void) +{ + /* Do nothing, handled by _rx */ +} + + +void console_print(char *data, int length) +{ + char *curr_char, saved_char; + int part_len; + int (*ring_send_fn)(const char *data, unsigned length); + + if(!console_initialised) + ring_send_fn = xencons_ring_send_no_notify; + else + ring_send_fn = xencons_ring_send; + + for(curr_char = data; curr_char < data+length-1; curr_char++) + { + if(*curr_char == '\n') + { + saved_char = *(curr_char+1); + *(curr_char+1) = '\r'; + part_len = curr_char - data + 2; + ring_send_fn(data, part_len); + *(curr_char+1) = saved_char; + data = curr_char+1; + length -= part_len - 1; + } + } + + ring_send_fn(data, length); + + if(data[length-1] == '\n') + ring_send_fn("\r", 1); +} + +void print(int direct, const char *fmt, va_list args) +{ + static char buf[1024]; + + (void)vsnprintf(buf, sizeof(buf), fmt, args); + + if(direct) + { + (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); + return; + } + + if(!console_initialised) + (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); + + console_print(buf, strlen(buf)); +} + +void printk(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + print(0, fmt, args); + va_end(args); +} + +void xprintk(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + print(1, fmt, args); + va_end(args); +} +void init_console(void) +{ + printk("Initialising console ... "); + xencons_ring_init(); + console_initialised = 1; + /* This is also required to notify the daemon */ + printk("done.\n"); +} diff -r c445d4a0dd76 -r 0cd76c3fa05b extras/mini-os/console/xencons_ring.c --- /dev/null Tue Mar 14 18:33:45 2006 +++ b/extras/mini-os/console/xencons_ring.c Wed Mar 15 19:09:01 2006 @@ -0,0 +1,104 @@ +#include <types.h> +#include <wait.h> +#include <mm.h> +#include <hypervisor.h> +#include <events.h> +#include <os.h> +#include <lib.h> +#include <xenbus.h> +#include <xen/io/console.h> + + +/* TODO - need to define BUG_ON for whole mini-os, need crash-dump as well */ +extern void do_exit(void); +#define BUG_ON(_cond) do{if(_cond) do_exit();} while(0); + +static inline struct xencons_interface *xencons_interface(void) +{ + return mfn_to_virt(start_info.console_mfn); +} + +static inline void notify_daemon(void) +{ + /* Use evtchn: this is called early, before irq is set up. */ + notify_remote_via_evtchn(start_info.console_evtchn); +} + +int xencons_ring_send_no_notify(const char *data, unsigned len) +{ + int sent = 0; + struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; + + cons = intf->out_cons; + prod = intf->out_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->out)); + + while ((sent < len) && ((prod - cons) < sizeof(intf->out))) + intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; + + wmb(); + intf->out_prod = prod; + + return sent; +} + +int xencons_ring_send(const char *data, unsigned len) +{ + int sent; + sent = xencons_ring_send_no_notify(data, len); + notify_daemon(); + + return sent; +} + + + +static void handle_input(int port, struct pt_regs *regs) +{ + 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)); + + while (cons != prod) { + xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs); + cons++; + } + + mb(); + intf->in_cons = cons; + + notify_daemon(); + + xencons_tx(); +} + +int xencons_ring_init(void) +{ + int err; + + if (!start_info.console_evtchn) + return 0; + + err = bind_evtchn(start_info.console_evtchn, handle_input); + if (err <= 0) { + printk("XEN console request chn bind failed %i\n", err); + return err; + } + + /* In case we have in-flight data after save/restore... */ + notify_daemon(); + + return 0; +} + +void xencons_resume(void) +{ + (void)xencons_ring_init(); +} + _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |