ia64/xen-unstable

changeset 9298:1569bc48b0b8

Implement console for Mini-os and also fix 2 bugs:
a) in initialising new page table frames
b) in initialising idle thread.

Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
author kaf24@firebug.cl.cam.ac.uk
date Wed Mar 15 20:25:50 2006 +0100 (2006-03-15)
parents d3b0d74702b5
children 00aba64e034e
files extras/mini-os/Makefile extras/mini-os/console/console.c extras/mini-os/console/xencons_ring.c extras/mini-os/events.c extras/mini-os/include/lib.h extras/mini-os/kernel.c extras/mini-os/lib/printf.c extras/mini-os/mm.c extras/mini-os/sched.c
line diff
     1.1 --- a/extras/mini-os/Makefile	Wed Mar 15 20:22:31 2006 +0100
     1.2 +++ b/extras/mini-os/Makefile	Wed Mar 15 20:25:50 2006 +0100
     1.3 @@ -32,7 +32,7 @@ OBJS := $(TARGET_ARCH).o
     1.4  OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
     1.5  OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
     1.6  OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
     1.7 -#OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
     1.8 +OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
     1.9  										   
    1.10  HDRS := $(wildcard include/*.h)
    1.11  HDRS += $(wildcard include/xen/*.h)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/extras/mini-os/console/console.c	Wed Mar 15 20:25:50 2006 +0100
     2.3 @@ -0,0 +1,149 @@
     2.4 +/* 
     2.5 + ****************************************************************************
     2.6 + * (C) 2006 - Grzegorz Milos - Cambridge University
     2.7 + ****************************************************************************
     2.8 + *
     2.9 + *        File: console.h
    2.10 + *      Author: Grzegorz Milos
    2.11 + *     Changes: 
    2.12 + *              
    2.13 + *        Date: Mar 2006
    2.14 + * 
    2.15 + * Environment: Xen Minimal OS
    2.16 + * Description: Console interface.
    2.17 + *
    2.18 + * Handles console I/O. Defines printk.
    2.19 + *
    2.20 + ****************************************************************************
    2.21 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    2.22 + * of this software and associated documentation files (the "Software"), to
    2.23 + * deal in the Software without restriction, including without limitation the
    2.24 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    2.25 + * sell copies of the Software, and to permit persons to whom the Software is
    2.26 + * furnished to do so, subject to the following conditions:
    2.27 + * 
    2.28 + * The above copyright notice and this permission notice shall be included in
    2.29 + * all copies or substantial portions of the Software.
    2.30 + * 
    2.31 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    2.32 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    2.33 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    2.34 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    2.35 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    2.36 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    2.37 + * DEALINGS IN THE SOFTWARE.
    2.38 + */
    2.39 + 
    2.40 +#include <types.h>
    2.41 +#include <wait.h>
    2.42 +#include <mm.h>
    2.43 +#include <hypervisor.h>
    2.44 +#include <events.h>
    2.45 +#include <os.h>
    2.46 +#include <lib.h>
    2.47 +#include <xenbus.h>
    2.48 +#include <xen/io/console.h>
    2.49 +
    2.50 +
    2.51 +/* Low level functions defined in xencons_ring.c */
    2.52 +extern int xencons_ring_init(void);
    2.53 +extern int xencons_ring_send(const char *data, unsigned len);
    2.54 +extern int xencons_ring_send_no_notify(const char *data, unsigned len);
    2.55 +
    2.56 +
    2.57 +/* If console not initialised the printk will be sent to xen serial line 
    2.58 +   NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
    2.59 +static int console_initialised = 0;
    2.60 +
    2.61 +
    2.62 +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
    2.63 +{
    2.64 +    if(len > 0)
    2.65 +    {
    2.66 +        /* Just repeat what's written */
    2.67 +        buf[len] = '\0';
    2.68 +        printk("%s", buf);
    2.69 +        
    2.70 +        if(buf[len-1] == '\r')
    2.71 +            printk("\nNo console input handler.\n");
    2.72 +    }
    2.73 +}
    2.74 +
    2.75 +void xencons_tx(void)
    2.76 +{
    2.77 +    /* Do nothing, handled by _rx */
    2.78 +}
    2.79 +
    2.80 +
    2.81 +void console_print(char *data, int length)
    2.82 +{
    2.83 +    char *curr_char, saved_char;
    2.84 +    int part_len;
    2.85 +    int (*ring_send_fn)(const char *data, unsigned length);
    2.86 +
    2.87 +    if(!console_initialised)
    2.88 +        ring_send_fn = xencons_ring_send_no_notify;
    2.89 +    else
    2.90 +        ring_send_fn = xencons_ring_send;
    2.91 +        
    2.92 +    for(curr_char = data; curr_char < data+length-1; curr_char++)
    2.93 +    {
    2.94 +        if(*curr_char == '\n')
    2.95 +        {
    2.96 +            saved_char = *(curr_char+1);
    2.97 +            *(curr_char+1) = '\r';
    2.98 +            part_len = curr_char - data + 2;
    2.99 +            ring_send_fn(data, part_len);
   2.100 +            *(curr_char+1) = saved_char;
   2.101 +            data = curr_char+1;
   2.102 +            length -= part_len - 1;
   2.103 +        }
   2.104 +    }
   2.105 +    
   2.106 +    ring_send_fn(data, length);
   2.107 +    
   2.108 +    if(data[length-1] == '\n')
   2.109 +        ring_send_fn("\r", 1);
   2.110 +}
   2.111 +
   2.112 +void print(int direct, const char *fmt, va_list args)
   2.113 +{
   2.114 +    static char   buf[1024];
   2.115 +    
   2.116 +    (void)vsnprintf(buf, sizeof(buf), fmt, args);
   2.117 + 
   2.118 +    if(direct)
   2.119 +    {
   2.120 +        (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
   2.121 +        return;
   2.122 +    }
   2.123 +    
   2.124 +    if(!console_initialised)
   2.125 +        (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
   2.126 +        
   2.127 +    console_print(buf, strlen(buf));
   2.128 +}
   2.129 +
   2.130 +void printk(const char *fmt, ...)
   2.131 +{
   2.132 +    va_list       args;
   2.133 +    va_start(args, fmt);
   2.134 +    print(0, fmt, args);
   2.135 +    va_end(args);        
   2.136 +}
   2.137 +
   2.138 +void xprintk(const char *fmt, ...)
   2.139 +{
   2.140 +    va_list       args;
   2.141 +    va_start(args, fmt);
   2.142 +    print(1, fmt, args);
   2.143 +    va_end(args);        
   2.144 +}
   2.145 +void init_console(void)
   2.146 +{   
   2.147 +    printk("Initialising console ... ");
   2.148 +    xencons_ring_init();    
   2.149 +    console_initialised = 1;
   2.150 +    /* This is also required to notify the daemon */
   2.151 +    printk("done.\n");
   2.152 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/extras/mini-os/console/xencons_ring.c	Wed Mar 15 20:25:50 2006 +0100
     3.3 @@ -0,0 +1,104 @@
     3.4 +#include <types.h>
     3.5 +#include <wait.h>
     3.6 +#include <mm.h>
     3.7 +#include <hypervisor.h>
     3.8 +#include <events.h>
     3.9 +#include <os.h>
    3.10 +#include <lib.h>
    3.11 +#include <xenbus.h>
    3.12 +#include <xen/io/console.h>
    3.13 +
    3.14 +
    3.15 +/* TODO - need to define BUG_ON for whole mini-os, need crash-dump as well */
    3.16 +extern void do_exit(void);
    3.17 +#define BUG_ON(_cond)   do{if(_cond) do_exit();} while(0);
    3.18 +
    3.19 +static inline struct xencons_interface *xencons_interface(void)
    3.20 +{
    3.21 +    return mfn_to_virt(start_info.console_mfn);
    3.22 +}
    3.23 +
    3.24 +static inline void notify_daemon(void)
    3.25 +{
    3.26 +    /* Use evtchn: this is called early, before irq is set up. */
    3.27 +    notify_remote_via_evtchn(start_info.console_evtchn);
    3.28 +}
    3.29 +
    3.30 +int xencons_ring_send_no_notify(const char *data, unsigned len)
    3.31 +{	
    3.32 +    int sent = 0;
    3.33 +	struct xencons_interface *intf = xencons_interface();
    3.34 +	XENCONS_RING_IDX cons, prod;
    3.35 +
    3.36 +	cons = intf->out_cons;
    3.37 +	prod = intf->out_prod;
    3.38 +	mb();
    3.39 +	BUG_ON((prod - cons) > sizeof(intf->out));
    3.40 +
    3.41 +	while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
    3.42 +		intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
    3.43 +
    3.44 +	wmb();
    3.45 +	intf->out_prod = prod;
    3.46 +    
    3.47 +    return sent;
    3.48 +}
    3.49 +
    3.50 +int xencons_ring_send(const char *data, unsigned len)
    3.51 +{
    3.52 +    int sent;
    3.53 +    sent = xencons_ring_send_no_notify(data, len);
    3.54 +	notify_daemon();
    3.55 +
    3.56 +	return sent;
    3.57 +}	
    3.58 +
    3.59 +
    3.60 +
    3.61 +static void handle_input(int port, struct pt_regs *regs)
    3.62 +{
    3.63 +	struct xencons_interface *intf = xencons_interface();
    3.64 +	XENCONS_RING_IDX cons, prod;
    3.65 +
    3.66 +	cons = intf->in_cons;
    3.67 +	prod = intf->in_prod;
    3.68 +	mb();
    3.69 +	BUG_ON((prod - cons) > sizeof(intf->in));
    3.70 +
    3.71 +	while (cons != prod) {
    3.72 +		xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
    3.73 +		cons++;
    3.74 +	}
    3.75 +
    3.76 +	mb();
    3.77 +	intf->in_cons = cons;
    3.78 +
    3.79 +	notify_daemon();
    3.80 +
    3.81 +	xencons_tx();
    3.82 +}
    3.83 +
    3.84 +int xencons_ring_init(void)
    3.85 +{
    3.86 +	int err;
    3.87 +
    3.88 +	if (!start_info.console_evtchn)
    3.89 +		return 0;
    3.90 +
    3.91 +	err = bind_evtchn(start_info.console_evtchn, handle_input);
    3.92 +	if (err <= 0) {
    3.93 +		printk("XEN console request chn bind failed %i\n", err);
    3.94 +		return err;
    3.95 +	}
    3.96 +
    3.97 +	/* In case we have in-flight data after save/restore... */
    3.98 +	notify_daemon();
    3.99 +
   3.100 +	return 0;
   3.101 +}
   3.102 +
   3.103 +void xencons_resume(void)
   3.104 +{
   3.105 +	(void)xencons_ring_init();
   3.106 +}
   3.107 +
     4.1 --- a/extras/mini-os/events.c	Wed Mar 15 20:22:31 2006 +0100
     4.2 +++ b/extras/mini-os/events.c	Wed Mar 15 20:25:50 2006 +0100
     4.3 @@ -22,6 +22,7 @@
     4.4  #include <events.h>
     4.5  #include <lib.h>
     4.6  
     4.7 +
     4.8  static ev_action_t ev_actions[NR_EVS];
     4.9  void default_handler(int port, struct pt_regs *regs);
    4.10  
    4.11 @@ -58,7 +59,7 @@ int do_event(u32 port, struct pt_regs *r
    4.12  
    4.13  int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
    4.14  {
    4.15 - 	if(ev_actions[port].handler)
    4.16 + 	if(ev_actions[port].handler != default_handler)
    4.17          printk("WARN: Handler for port %d already registered, replacing\n",
    4.18  				port);
    4.19  
    4.20 @@ -73,7 +74,7 @@ int bind_evtchn( u32 port, void (*handle
    4.21  
    4.22  void unbind_evtchn( u32 port )
    4.23  {
    4.24 -	if (!ev_actions[port].handler)
    4.25 +	if (ev_actions[port].handler)
    4.26  		printk("WARN: No handler for port %d when unbinding\n", port);
    4.27  	ev_actions[port].handler = NULL;
    4.28  	ev_actions[port].status |= EVS_DISABLED;
     5.1 --- a/extras/mini-os/include/lib.h	Wed Mar 15 20:22:31 2006 +0100
     5.2 +++ b/extras/mini-os/include/lib.h	Wed Mar 15 20:25:50 2006 +0100
     5.3 @@ -56,13 +56,10 @@
     5.4  #define _LIB_H_
     5.5  
     5.6  #include <stdarg.h>
     5.7 -
     5.8 +#include <console.h>
     5.9  
    5.10  /* printing */
    5.11 -#define printk  printf
    5.12 -#define kprintf printf
    5.13  #define _p(_x) ((void *)(unsigned long)(_x))
    5.14 -void printf(const char *fmt, ...);
    5.15  int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
    5.16  int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
    5.17  int snprintf(char * buf, size_t size, const char *fmt, ...);
     6.1 --- a/extras/mini-os/kernel.c	Wed Mar 15 20:22:31 2006 +0100
     6.2 +++ b/extras/mini-os/kernel.c	Wed Mar 15 20:25:50 2006 +0100
     6.3 @@ -76,6 +76,8 @@ static shared_info_t *map_shared_info(un
     6.4  }
     6.5  
     6.6  
     6.7 +extern void init_console(void);
     6.8 +
     6.9  /*
    6.10   * INITIAL C ENTRY POINT.
    6.11   */
    6.12 @@ -127,15 +129,19 @@ void start_kernel(start_info_t *si)
    6.13  
    6.14      /* set up events */
    6.15      init_events();
    6.16 +    
    6.17      /* init time and timers */
    6.18      init_time();
    6.19 -    
    6.20 +
    6.21 +    /* init the console driver */
    6.22 +    init_console();
    6.23 +
    6.24      /* init scheduler */
    6.25      init_sched();
    6.26  
    6.27      /* init xenbus */
    6.28      xs_init();
    6.29 -    
    6.30 +   
    6.31      /* Everything initialised, start idle thread */
    6.32      run_idle_thread();
    6.33  }
     7.1 --- a/extras/mini-os/lib/printf.c	Wed Mar 15 20:22:31 2006 +0100
     7.2 +++ b/extras/mini-os/lib/printf.c	Wed Mar 15 20:25:50 2006 +0100
     7.3 @@ -556,19 +556,6 @@ int sprintf(char * buf, const char *fmt,
     7.4      return i;
     7.5  }
     7.6  
     7.7 -
     7.8 -void printf(const char *fmt, ...)
     7.9 -{
    7.10 -    static char   buf[1024];
    7.11 -    va_list       args;
    7.12 -    
    7.13 -    va_start(args, fmt);
    7.14 -    (void)vsnprintf(buf, sizeof(buf), fmt, args);
    7.15 -    va_end(args);        
    7.16 -   
    7.17 -    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
    7.18 -}
    7.19 -
    7.20  /**
    7.21   * vsscanf - Unformat a buffer into a list of arguments
    7.22   * @buf:	input buffer
     8.1 --- a/extras/mini-os/mm.c	Wed Mar 15 20:22:31 2006 +0100
     8.2 +++ b/extras/mini-os/mm.c	Wed Mar 15 20:25:50 2006 +0100
     8.3 @@ -380,6 +380,10 @@ void new_pt_frame(unsigned long *pt_pfn,
     8.4             "prev_l_mfn=%lx, offset=%lx\n", 
     8.5             level, *pt_pfn, prev_l_mfn, offset);
     8.6  
     8.7 +    /* We need to clear the page, otherwise we might fail to map it
     8.8 +       as a page table page */
     8.9 +    memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);  
    8.10 + 
    8.11      if (level == L1_FRAME)
    8.12      {
    8.13           prot_e = L1_PROT;
     9.1 --- a/extras/mini-os/sched.c	Wed Mar 15 20:22:31 2006 +0100
     9.2 +++ b/extras/mini-os/sched.c	Wed Mar 15 20:25:50 2006 +0100
     9.3 @@ -46,6 +46,7 @@
     9.4  #include <sched.h>
     9.5  #include <semaphore.h>
     9.6  
     9.7 +
     9.8  #ifdef SCHED_DEBUG
     9.9  #define DEBUG(_f, _a...) \
    9.10      printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
    9.11 @@ -61,7 +62,7 @@
    9.12  #define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
    9.13  
    9.14  
    9.15 -struct thread *idle_thread;
    9.16 +struct thread *idle_thread = NULL;
    9.17  LIST_HEAD(exited_threads);
    9.18  
    9.19  void dump_stack(struct thread *thread)
    9.20 @@ -225,7 +226,6 @@ void idle_thread_fn(void *unused)
    9.21      for(;;)
    9.22      {
    9.23          schedule();
    9.24 -        printk("Blocking the domain\n"); 
    9.25          block_domain(10000);
    9.26      }
    9.27  }