direct-io.hg

changeset 607:6879a4610638

bitkeeper revision 1.340 (3f1056abln89ZkMr4cSW4WAtN8rLsg)

VGA console support for domain0.

put the following on the kernel command line: console=xencons0 console=tty0
author iap10@labyrinth.cl.cam.ac.uk
date Sat Jul 12 18:42:51 2003 +0000 (2003-07-12)
parents 5e169da77286
children cda951fc1bef
files .rootkeys xen/common/domain.c xen/common/memory.c xen/include/xeno/console.h xenolinux-2.4.21-sparse/arch/xeno/kernel/ioport.c xenolinux-2.4.21-sparse/arch/xeno/kernel/setup.c xenolinux-2.4.21-sparse/arch/xeno/mm/init.c xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c xenolinux-2.4.21-sparse/include/asm-xeno/fixmap.h xenolinux-2.4.21-sparse/include/asm-xeno/vga.h xenolinux-2.4.21-sparse/kernel/printk.c xenolinux-2.4.21-sparse/mkbuildtree
line diff
     1.1 --- a/.rootkeys	Thu Jul 10 13:42:56 2003 +0000
     1.2 +++ b/.rootkeys	Sat Jul 12 18:42:51 2003 +0000
     1.3 @@ -583,11 +583,13 @@ 3e5a4e67AJPjW-zL7p-xWuA6IVeH1g xenolinux
     1.4  3e5a4e68uJz-xI0IBVMD7xRLQKJDFg xenolinux-2.4.21-sparse/include/asm-xeno/segment.h
     1.5  3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA xenolinux-2.4.21-sparse/include/asm-xeno/smp.h
     1.6  3e5a4e68mTr0zcp9SXDbnd-XLrrfxw xenolinux-2.4.21-sparse/include/asm-xeno/system.h
     1.7 +3f1056a9L_kqHcFheV00KbKBzv9j5w xenolinux-2.4.21-sparse/include/asm-xeno/vga.h
     1.8  3f056927gMHl7mWB89rb73JahbhQIA xenolinux-2.4.21-sparse/include/linux/blk.h
     1.9  3e5a4e68WLX3B8owTvktP3HHOtznPQ xenolinux-2.4.21-sparse/include/linux/major.h
    1.10  3e5a4e686V0nioX2ZpFf056sgvdiQw xenolinux-2.4.21-sparse/include/linux/sunrpc/debug.h
    1.11  3e5a4e68W_hpMlM3u_-QOKMp3gzcwQ xenolinux-2.4.21-sparse/init/do_mounts.c
    1.12  3e5a4e68TJJavrunYwTAnLRSBxSYqQ xenolinux-2.4.21-sparse/kernel/panic.c
    1.13 +3f1056a9LXNTgSzITNh1mb-MIKV1Ng xenolinux-2.4.21-sparse/kernel/printk.c
    1.14  3eba8f878XjouY21EkQBXwYBsPsipQ xenolinux-2.4.21-sparse/lndir-rel
    1.15  3e6e7c1efbQe93xCvOpOVCnXTMmQ5w xenolinux-2.4.21-sparse/mkbuildtree
    1.16  3e5a4e68GxCIaFH4sy01v1wjapetaA xenolinux-2.4.21-sparse/mm/memory.c
     2.1 --- a/xen/common/domain.c	Thu Jul 10 13:42:56 2003 +0000
     2.2 +++ b/xen/common/domain.c	Sat Jul 12 18:42:51 2003 +0000
     2.3 @@ -677,7 +677,7 @@ int setup_guestos(struct task_struct *p,
     2.4      // 1) its privileged (need iopl right now)
     2.5      // 2) its the owner of the console (and therefore will get kbd/mouse events)
     2.6      // 3) xen hasnt tried to touch the console (see console.h)
     2.7 -    virt_startinfo_address->flags |= (IS_PRIV(p) && CONSOLE_ISOWNER(p) && opt_console == 0) ? SIF_CONSOLE : 0;
     2.8 +    virt_startinfo_address->flags |= (IS_PRIV(p) && CONSOLE_ISOWNER(p) ) ? SIF_CONSOLE : 0;
     2.9  
    2.10      if ( initrd_len )
    2.11      {
    2.12 @@ -718,6 +718,14 @@ int setup_guestos(struct task_struct *p,
    2.13      }
    2.14      *dst = '\0';
    2.15  
    2.16 +    /* If this guy's getting the console we'd better let go */
    2.17 +    if ( virt_startinfo_address->flags & SIF_CONSOLE )
    2.18 +    {
    2.19 +        // should reset the console, but seems to work anyhow...
    2.20 +        opt_console = 0;
    2.21 +    }  
    2.22 +
    2.23 +
    2.24      /* Reinstate the caller's page tables. */
    2.25      __write_cr3_counted(pagetable_val(current->mm.pagetable));
    2.26      __sti();
     3.1 --- a/xen/common/memory.c	Thu Jul 10 13:42:56 2003 +0000
     3.2 +++ b/xen/common/memory.c	Sat Jul 12 18:42:51 2003 +0000
     3.3 @@ -184,7 +184,7 @@
     3.4  
     3.5  /* Domain 0 is allowed to submit requests on behalf of others. */
     3.6  #define DOMAIN_OKAY(_f) \
     3.7 -    ((((_f) & PG_domain_mask) == current->domain) || (current->domain == 0))
     3.8 +    (((_f) & PG_domain_mask) == current->domain)
     3.9  
    3.10  /* 'get' checks parameter for validity before inc'ing refcnt. */
    3.11  static int get_l2_table(unsigned long page_nr);
     4.1 --- a/xen/include/xeno/console.h	Thu Jul 10 13:42:56 2003 +0000
     4.2 +++ b/xen/include/xeno/console.h	Sat Jul 12 18:42:51 2003 +0000
     4.3 @@ -26,7 +26,8 @@
     4.4  // the notion of privileges for guest os's (e.g. console privilege) has not been explored yet
     4.5  // so this will do for now
     4.6  
     4.7 -#define CONFIG_OUTPUT_CONSOLE 1 // but see also opt_console
     4.8 +#define CONFIG_OUTPUT_CONSOLE 1 //  XXX You need to undef this
     4.9 +				//  but see also opt_console
    4.10  #define CONFIG_OUTPUT_SERIAL  1
    4.11  
    4.12  extern unsigned int opt_console;
     5.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/kernel/ioport.c	Thu Jul 10 13:42:56 2003 +0000
     5.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/kernel/ioport.c	Sat Jul 12 18:42:51 2003 +0000
     5.3 @@ -8,8 +8,33 @@
     5.4  
     5.5  asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
     5.6  {
     5.7 -    /* No IO permission! Selective IO perms aren't virtualised yet. */
     5.8 -    return -EPERM;
     5.9 +    unsigned int new_io_pl = (turn_on)?3:0;
    5.10 +    unsigned int old_io_pl = current->thread.io_pl;
    5.11 +    dom0_op_t op;
    5.12 +
    5.13 +    if ( !(start_info.flags & SIF_PRIVILEGED) )
    5.14 +        return -EPERM;
    5.15 +
    5.16 +    /* Need "raw I/O" privileges for direct port access. */
    5.17 +    if ( (new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO) )
    5.18 +        return -EPERM;
    5.19 +
    5.20 +    /* Maintain OS privileges even if user attempts to relinquish them. */
    5.21 +    if ( (new_io_pl == 0) && (start_info.flags & SIF_PRIVILEGED) )
    5.22 +        new_io_pl = 1;
    5.23 +
    5.24 +    printk("ioperm not properly supported - set iopl to %d\n",new_io_pl);
    5.25 +
    5.26 +    /* Change our version of the privilege levels. */
    5.27 +    current->thread.io_pl = new_io_pl;
    5.28 +
    5.29 +    /* Force the change at ring 0. */
    5.30 +    op.cmd           = DOM0_IOPL;
    5.31 +    op.u.iopl.domain = start_info.dom_id;
    5.32 +    op.u.iopl.iopl   = new_io_pl;
    5.33 +    HYPERVISOR_dom0_op(&op);
    5.34 +
    5.35 +    return 0;
    5.36  }
    5.37  
    5.38  
     6.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/kernel/setup.c	Thu Jul 10 13:42:56 2003 +0000
     6.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/kernel/setup.c	Sat Jul 12 18:42:51 2003 +0000
     6.3 @@ -58,6 +58,8 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 
     6.4  
     6.5  unsigned long mmu_cr4_features;
     6.6  
     6.7 +unsigned char * vgacon_mmap;
     6.8 +
     6.9  /*
    6.10   * Bus types ..
    6.11   */
     7.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/mm/init.c	Thu Jul 10 13:42:56 2003 +0000
     7.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/mm/init.c	Sat Jul 12 18:42:51 2003 +0000
     7.3 @@ -113,10 +113,7 @@ static inline void set_pte_phys (unsigne
     7.4  		return;
     7.5  	}
     7.6  	pte = pte_offset(pmd, vaddr);
     7.7 -#if 0 // XXX Xen ?????
     7.8 -	/* <phys,flags> stored as-is, to permit clearing entries */
     7.9 -	set_pte(pte, mk_pte_phys(phys, flags));
    7.10 -#endif
    7.11 +
    7.12  	if (pte_val(*pte))
    7.13  		pte_ERROR(*pte);
    7.14  
     8.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c	Thu Jul 10 13:42:56 2003 +0000
     8.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c	Sat Jul 12 18:42:51 2003 +0000
     8.3 @@ -296,6 +296,54 @@ void iounmap(void *addr)
     8.4      printk(KERN_ERR "Trying to iounmap() nonexistent vm area (%p)\n", addr);
     8.5  }
     8.6  
     8.7 +void __init *bt_ioremap(unsigned long machine_addr, unsigned long size)
     8.8 +{
     8.9 +        unsigned long offset, last_addr;
    8.10 +        unsigned int nrpages;
    8.11 +        enum fixed_addresses idx;
    8.12 +
    8.13 +        /* Don't allow wraparound or zero size */
    8.14 +        last_addr = machine_addr + size - 1;
    8.15 +        if (!size || last_addr < machine_addr)
    8.16 +                return NULL;
    8.17 +
    8.18 +        /*
    8.19 +         * Mappings have to be page-aligned
    8.20 +         */
    8.21 +        offset = machine_addr & ~PAGE_MASK;
    8.22 +        machine_addr &= PAGE_MASK;
    8.23 +        size = PAGE_ALIGN(last_addr) - machine_addr;
    8.24 +
    8.25 +        /*
    8.26 +         * Mappings have to fit in the FIX_BTMAP area.
    8.27 +         */
    8.28 +        nrpages = size >> PAGE_SHIFT;
    8.29 +        if (nrpages > NR_FIX_BTMAPS)
    8.30 +                return NULL;
    8.31 +
    8.32 +        /*
    8.33 +         * Ok, go for it..
    8.34 +         */
    8.35 +        idx = FIX_BTMAP_BEGIN;
    8.36 +        while (nrpages > 0) {
    8.37 +                set_fixmap(idx, machine_addr);
    8.38 +
    8.39 +		//unsigned long address = __fix_to_virt(idx);
    8.40 +		
    8.41 +
    8.42 +
    8.43 +//direct_set_pte(address, direct_mk_pte_phys(machine_addr, PAGE_KERNEL_NOCACHE));
    8.44 +
    8.45 +                machine_addr += PAGE_SIZE;
    8.46 +                --idx;
    8.47 +                --nrpages;
    8.48 +        }
    8.49 +
    8.50 +flush_tlb_all();
    8.51 +
    8.52 +        return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
    8.53 +}
    8.54 +
    8.55  
    8.56  #if 0 /* We don't support these functions. They shouldn't be required. */
    8.57  void __init *bt_ioremap(unsigned long machine_addr, unsigned long size) {}
     9.1 --- a/xenolinux-2.4.21-sparse/include/asm-xeno/fixmap.h	Thu Jul 10 13:42:56 2003 +0000
     9.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/fixmap.h	Sat Jul 12 18:42:51 2003 +0000
     9.3 @@ -47,8 +47,12 @@ enum fixed_addresses {
     9.4  	FIX_NETRING1_BASE,
     9.5  	FIX_NETRING2_BASE,
     9.6  	FIX_NETRING3_BASE,
     9.7 +#define NR_FIX_BTMAPS   8  /* 32KB For the Dom0 VGA Console */
     9.8 +        FIX_BTMAP_END,
     9.9 +        FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
    9.10 +
    9.11  	__end_of_permanent_fixed_addresses,
    9.12 -	__end_of_fixed_addresses
    9.13 +	__end_of_fixed_addresses = __end_of_permanent_fixed_addresses
    9.14  };
    9.15  
    9.16  extern void __set_fixmap (enum fixed_addresses idx,
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xenolinux-2.4.21-sparse/include/asm-xeno/vga.h	Sat Jul 12 18:42:51 2003 +0000
    10.3 @@ -0,0 +1,57 @@
    10.4 +/*
    10.5 + *	Access to VGA videoram
    10.6 + *
    10.7 + *	(c) 1998 Martin Mares <mj@ucw.cz>
    10.8 + */
    10.9 +
   10.10 +#ifndef _LINUX_ASM_VGA_H_
   10.11 +#define _LINUX_ASM_VGA_H_
   10.12 +
   10.13 +#include <asm/io.h>
   10.14 +
   10.15 +extern unsigned char *vgacon_mmap;
   10.16 +
   10.17 +
   10.18 +static unsigned long VGA_MAP_MEM(unsigned long x)
   10.19 +{
   10.20 +
   10.21 +	if( vgacon_mmap == NULL )
   10.22 +	{
   10.23 +		/* This is our first time in this function. This whole thing
   10.24 +		is a rather grim hack. We know we're going to get asked 
   10.25 +		to map a 32KB region between 0xb0000 and 0xb8000 because
   10.26 +		that's what VGAs are. We used the boot time permanent 
   10.27 +		fixed map region, and map it to machine pages.
   10.28 +		*/
   10.29 +
   10.30 +		if( x != 0xb8000 )
   10.31 +		{
   10.32 +			printk("Argghh! VGA Console is weird. 1:%08lx\n",x);
   10.33 +			BUG();	
   10.34 +		}
   10.35 +
   10.36 +		vgacon_mmap = (unsigned char*) bt_ioremap( 0xb8000, 32*1024 );
   10.37 +//xprintk("VGA_MAP_MEM(%08x) first. return %p\n",x,vgacon_mmap);
   10.38 +		return (unsigned long) vgacon_mmap;
   10.39 +	}
   10.40 +	else
   10.41 +	{
   10.42 +		if( x != 0xc0000 )
   10.43 +                {
   10.44 +                        printk("Argghh! VGA Console is weird. 2:%08lx\n",x);  
   10.45 +                        BUG();
   10.46 +                }
   10.47 +//xprintk("VGA_MAP_MEM(%08x) second. return %p\n",x,(unsigned long) vgacon_mmap+0x8000);
   10.48 +
   10.49 +		return (unsigned long) vgacon_mmap + 0x8000;
   10.50 +
   10.51 +	}
   10.52 +	return 0;
   10.53 +}
   10.54 +
   10.55 +static inline unsigned char vga_readb(unsigned char * x) { 
   10.56 +xprintk("vr %p\n",x);return (*(x)); }
   10.57 +static void vga_writeb(unsigned char x, unsigned char *y) {
   10.58 +xprintk("vw %02x %p\n",x,y); *(y) = (x); }
   10.59 +
   10.60 +#endif
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xenolinux-2.4.21-sparse/kernel/printk.c	Sat Jul 12 18:42:51 2003 +0000
    11.3 @@ -0,0 +1,691 @@
    11.4 +/*
    11.5 + *  linux/kernel/printk.c
    11.6 + *
    11.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
    11.8 + *
    11.9 + * Modified to make sys_syslog() more flexible: added commands to
   11.10 + * return the last 4k of kernel messages, regardless of whether
   11.11 + * they've been read or not.  Added option to suppress kernel printk's
   11.12 + * to the console.  Added hook for sending the console messages
   11.13 + * elsewhere, in preparation for a serial line console (someday).
   11.14 + * Ted Ts'o, 2/11/93.
   11.15 + * Modified for sysctl support, 1/8/97, Chris Horn.
   11.16 + * Fixed SMP synchronization, 08/08/99, Manfred Spraul 
   11.17 + *     manfreds@colorfullife.com
   11.18 + * Rewrote bits to get rid of console_lock
   11.19 + *	01Mar01 Andrew Morton <andrewm@uow.edu.au>
   11.20 + */
   11.21 +
   11.22 +#include <linux/kernel.h>
   11.23 +#include <linux/mm.h>
   11.24 +#include <linux/tty.h>
   11.25 +#include <linux/tty_driver.h>
   11.26 +#include <linux/smp_lock.h>
   11.27 +#include <linux/console.h>
   11.28 +#include <linux/init.h>
   11.29 +#include <linux/module.h>
   11.30 +#include <linux/interrupt.h>			/* For in_interrupt() */
   11.31 +#include <linux/config.h>
   11.32 +
   11.33 +#include <asm/uaccess.h>
   11.34 +
   11.35 +#if defined(CONFIG_MULTIQUAD) || defined(CONFIG_IA64)
   11.36 +#define LOG_BUF_LEN	(65536)
   11.37 +#elif defined(CONFIG_ARCH_S390)
   11.38 +#define LOG_BUF_LEN	(131072)
   11.39 +#elif defined(CONFIG_SMP)
   11.40 +#define LOG_BUF_LEN	(32768)
   11.41 +#else	
   11.42 +#define LOG_BUF_LEN	(16384)			/* This must be a power of two */
   11.43 +#endif
   11.44 +
   11.45 +#define LOG_BUF_MASK	(LOG_BUF_LEN-1)
   11.46 +
   11.47 +#ifndef arch_consoles_callable
   11.48 +#define arch_consoles_callable() (1)
   11.49 +#endif
   11.50 +
   11.51 +/* printk's without a loglevel use this.. */
   11.52 +#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
   11.53 +
   11.54 +/* We show everything that is MORE important than this.. */
   11.55 +#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
   11.56 +#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
   11.57 +
   11.58 +DECLARE_WAIT_QUEUE_HEAD(log_wait);
   11.59 +
   11.60 +int console_printk[4] = {
   11.61 +	DEFAULT_CONSOLE_LOGLEVEL,	/* console_loglevel */
   11.62 +	DEFAULT_MESSAGE_LOGLEVEL,	/* default_message_loglevel */
   11.63 +	MINIMUM_CONSOLE_LOGLEVEL,	/* minimum_console_loglevel */
   11.64 +	DEFAULT_CONSOLE_LOGLEVEL,	/* default_console_loglevel */
   11.65 +};
   11.66 +
   11.67 +int oops_in_progress;
   11.68 +
   11.69 +/*
   11.70 + * console_sem protects the console_drivers list, and also
   11.71 + * provides serialisation for access to the entire console
   11.72 + * driver system.
   11.73 + */
   11.74 +static DECLARE_MUTEX(console_sem);
   11.75 +struct console *console_drivers;
   11.76 +
   11.77 +/*
   11.78 + * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
   11.79 + * It is also used in interesting ways to provide interlocking in
   11.80 + * release_console_sem().
   11.81 + */
   11.82 +static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED;
   11.83 +
   11.84 +static char log_buf[LOG_BUF_LEN];
   11.85 +#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
   11.86 +
   11.87 +/*
   11.88 + * The indices into log_buf are not constrained to LOG_BUF_LEN - they
   11.89 + * must be masked before subscripting
   11.90 + */
   11.91 +static unsigned long log_start;			/* Index into log_buf: next char to be read by syslog() */
   11.92 +static unsigned long con_start;			/* Index into log_buf: next char to be sent to consoles */
   11.93 +static unsigned long log_end;			/* Index into log_buf: most-recently-written-char + 1 */
   11.94 +static unsigned long logged_chars;		/* Number of chars produced since last read+clear operation */
   11.95 +
   11.96 +struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
   11.97 +static int preferred_console = -1;
   11.98 +
   11.99 +/* Flag: console code may call schedule() */
  11.100 +static int console_may_schedule;
  11.101 +
  11.102 +/*
  11.103 + *	Setup a list of consoles. Called from init/main.c
  11.104 + */
  11.105 +static int __init console_setup(char *str)
  11.106 +{
  11.107 +	struct console_cmdline *c;
  11.108 +	char name[sizeof(c->name)];
  11.109 +	char *s, *options;
  11.110 +	int i, idx;
  11.111 +
  11.112 +	/*
  11.113 +	 *	Decode str into name, index, options.
  11.114 +	 */
  11.115 +	if (str[0] >= '0' && str[0] <= '9') {
  11.116 +		strcpy(name, "ttyS");
  11.117 +		strncpy(name + 4, str, sizeof(name) - 5);
  11.118 +	} else
  11.119 +		strncpy(name, str, sizeof(name) - 1);
  11.120 +	name[sizeof(name) - 1] = 0;
  11.121 +	if ((options = strchr(str, ',')) != NULL)
  11.122 +		*(options++) = 0;
  11.123 +#ifdef __sparc__
  11.124 +	if (!strcmp(str, "ttya"))
  11.125 +		strcpy(name, "ttyS0");
  11.126 +	if (!strcmp(str, "ttyb"))
  11.127 +		strcpy(name, "ttyS1");
  11.128 +#endif
  11.129 +	for(s = name; *s; s++)
  11.130 +		if (*s >= '0' && *s <= '9')
  11.131 +			break;
  11.132 +	idx = simple_strtoul(s, NULL, 10);
  11.133 +	*s = 0;
  11.134 +
  11.135 +	/*
  11.136 +	 *	See if this tty is not yet registered, and
  11.137 +	 *	if we have a slot free.
  11.138 +	 */
  11.139 +	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
  11.140 +		if (strcmp(console_cmdline[i].name, name) == 0 &&
  11.141 +			  console_cmdline[i].index == idx) {
  11.142 +				preferred_console = i;
  11.143 +				return 1;
  11.144 +		}
  11.145 +	if (i == MAX_CMDLINECONSOLES)
  11.146 +		return 1;
  11.147 +	preferred_console = i;
  11.148 +	c = &console_cmdline[i];
  11.149 +	memcpy(c->name, name, sizeof(c->name));
  11.150 +	c->options = options;
  11.151 +	c->index = idx;
  11.152 +	return 1;
  11.153 +}
  11.154 +
  11.155 +__setup("console=", console_setup);
  11.156 +
  11.157 +/*
  11.158 + * Commands to do_syslog:
  11.159 + *
  11.160 + * 	0 -- Close the log.  Currently a NOP.
  11.161 + * 	1 -- Open the log. Currently a NOP.
  11.162 + * 	2 -- Read from the log.
  11.163 + * 	3 -- Read all messages remaining in the ring buffer.
  11.164 + * 	4 -- Read and clear all messages remaining in the ring buffer
  11.165 + * 	5 -- Clear ring buffer.
  11.166 + * 	6 -- Disable printk's to console
  11.167 + * 	7 -- Enable printk's to console
  11.168 + *	8 -- Set level of messages printed to console
  11.169 + *	9 -- Return number of unread characters in the log buffer
  11.170 + */
  11.171 +int do_syslog(int type, char * buf, int len)
  11.172 +{
  11.173 +	unsigned long i, j, limit, count;
  11.174 +	int do_clear = 0;
  11.175 +	char c;
  11.176 +	int error = 0;
  11.177 +
  11.178 +	switch (type) {
  11.179 +	case 0:		/* Close log */
  11.180 +		break;
  11.181 +	case 1:		/* Open log */
  11.182 +		break;
  11.183 +	case 2:		/* Read from log */
  11.184 +		error = -EINVAL;
  11.185 +		if (!buf || len < 0)
  11.186 +			goto out;
  11.187 +		error = 0;
  11.188 +		if (!len)
  11.189 +			goto out;
  11.190 +		error = verify_area(VERIFY_WRITE,buf,len);
  11.191 +		if (error)
  11.192 +			goto out;
  11.193 +		error = wait_event_interruptible(log_wait, (log_start - log_end));
  11.194 +		if (error)
  11.195 +			goto out;
  11.196 +		i = 0;
  11.197 +		spin_lock_irq(&logbuf_lock);
  11.198 +		while ((log_start != log_end) && i < len) {
  11.199 +			c = LOG_BUF(log_start);
  11.200 +			log_start++;
  11.201 +			spin_unlock_irq(&logbuf_lock);
  11.202 +			__put_user(c,buf);
  11.203 +			buf++;
  11.204 +			i++;
  11.205 +			spin_lock_irq(&logbuf_lock);
  11.206 +		}
  11.207 +		spin_unlock_irq(&logbuf_lock);
  11.208 +		error = i;
  11.209 +		break;
  11.210 +	case 4:		/* Read/clear last kernel messages */
  11.211 +		do_clear = 1; 
  11.212 +		/* FALL THRU */
  11.213 +	case 3:		/* Read last kernel messages */
  11.214 +		error = -EINVAL;
  11.215 +		if (!buf || len < 0)
  11.216 +			goto out;
  11.217 +		error = 0;
  11.218 +		if (!len)
  11.219 +			goto out;
  11.220 +		error = verify_area(VERIFY_WRITE,buf,len);
  11.221 +		if (error)
  11.222 +			goto out;
  11.223 +		count = len;
  11.224 +		if (count > LOG_BUF_LEN)
  11.225 +			count = LOG_BUF_LEN;
  11.226 +		spin_lock_irq(&logbuf_lock);
  11.227 +		if (count > logged_chars)
  11.228 +			count = logged_chars;
  11.229 +		if (do_clear)
  11.230 +			logged_chars = 0;
  11.231 +		limit = log_end;
  11.232 +		/*
  11.233 +		 * __put_user() could sleep, and while we sleep
  11.234 +		 * printk() could overwrite the messages 
  11.235 +		 * we try to copy to user space. Therefore
  11.236 +		 * the messages are copied in reverse. <manfreds>
  11.237 +		 */
  11.238 +		for(i=0;i < count;i++) {
  11.239 +			j = limit-1-i;
  11.240 +			if (j+LOG_BUF_LEN < log_end)
  11.241 +				break;
  11.242 +			c = LOG_BUF(j);
  11.243 +			spin_unlock_irq(&logbuf_lock);
  11.244 +			__put_user(c,&buf[count-1-i]);
  11.245 +			spin_lock_irq(&logbuf_lock);
  11.246 +		}
  11.247 +		spin_unlock_irq(&logbuf_lock);
  11.248 +		error = i;
  11.249 +		if(i != count) {
  11.250 +			int offset = count-error;
  11.251 +			/* buffer overflow during copy, correct user buffer. */
  11.252 +			for(i=0;i<error;i++) {
  11.253 +				__get_user(c,&buf[i+offset]);
  11.254 +				__put_user(c,&buf[i]);
  11.255 +			}
  11.256 +		}
  11.257 +
  11.258 +		break;
  11.259 +	case 5:		/* Clear ring buffer */
  11.260 +		spin_lock_irq(&logbuf_lock);
  11.261 +		logged_chars = 0;
  11.262 +		spin_unlock_irq(&logbuf_lock);
  11.263 +		break;
  11.264 +	case 6:		/* Disable logging to console */
  11.265 +		spin_lock_irq(&logbuf_lock);
  11.266 +		console_loglevel = minimum_console_loglevel;
  11.267 +		spin_unlock_irq(&logbuf_lock);
  11.268 +		break;
  11.269 +	case 7:		/* Enable logging to console */
  11.270 +		spin_lock_irq(&logbuf_lock);
  11.271 +		console_loglevel = default_console_loglevel;
  11.272 +		spin_unlock_irq(&logbuf_lock);
  11.273 +		break;
  11.274 +	case 8:		/* Set level of messages printed to console */
  11.275 +		error = -EINVAL;
  11.276 +		if (len < 1 || len > 8)
  11.277 +			goto out;
  11.278 +		if (len < minimum_console_loglevel)
  11.279 +			len = minimum_console_loglevel;
  11.280 +		spin_lock_irq(&logbuf_lock);
  11.281 +		console_loglevel = len;
  11.282 +		spin_unlock_irq(&logbuf_lock);
  11.283 +		error = 0;
  11.284 +		break;
  11.285 +	case 9:		/* Number of chars in the log buffer */
  11.286 +		spin_lock_irq(&logbuf_lock);
  11.287 +		error = log_end - log_start;
  11.288 +		spin_unlock_irq(&logbuf_lock);
  11.289 +		break;
  11.290 +	default:
  11.291 +		error = -EINVAL;
  11.292 +		break;
  11.293 +	}
  11.294 +out:
  11.295 +	return error;
  11.296 +}
  11.297 +
  11.298 +asmlinkage long sys_syslog(int type, char * buf, int len)
  11.299 +{
  11.300 +	if ((type != 3) && !capable(CAP_SYS_ADMIN))
  11.301 +		return -EPERM;
  11.302 +	return do_syslog(type, buf, len);
  11.303 +}
  11.304 +
  11.305 +/*
  11.306 + * Call the console drivers on a range of log_buf
  11.307 + */
  11.308 +static void __call_console_drivers(unsigned long start, unsigned long end)
  11.309 +{
  11.310 +	struct console *con;
  11.311 +
  11.312 +	for (con = console_drivers; con; con = con->next) {
  11.313 +		if ((con->flags & CON_ENABLED) && con->write)
  11.314 +			con->write(con, &LOG_BUF(start), end - start);
  11.315 +	}
  11.316 +}
  11.317 +
  11.318 +/*
  11.319 + * Write out chars from start to end - 1 inclusive
  11.320 + */
  11.321 +static void _call_console_drivers(unsigned long start, unsigned long end, int msg_log_level)
  11.322 +{
  11.323 +	if (msg_log_level < console_loglevel && console_drivers && start != end) {
  11.324 +		if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
  11.325 +			/* wrapped write */
  11.326 +			__call_console_drivers(start & LOG_BUF_MASK, LOG_BUF_LEN);
  11.327 +			__call_console_drivers(0, end & LOG_BUF_MASK);
  11.328 +		} else {
  11.329 +			__call_console_drivers(start, end);
  11.330 +		}
  11.331 +	}
  11.332 +}
  11.333 +
  11.334 +/*
  11.335 + * Call the console drivers, asking them to write out
  11.336 + * log_buf[start] to log_buf[end - 1].
  11.337 + * The console_sem must be held.
  11.338 + */
  11.339 +static void call_console_drivers(unsigned long start, unsigned long end)
  11.340 +{
  11.341 +	unsigned long cur_index, start_print;
  11.342 +	static int msg_level = -1;
  11.343 +
  11.344 +	if (((long)(start - end)) > 0)
  11.345 +		BUG();
  11.346 +
  11.347 +	cur_index = start;
  11.348 +	start_print = start;
  11.349 +	while (cur_index != end) {
  11.350 +		if (	msg_level < 0 &&
  11.351 +			((end - cur_index) > 2) &&
  11.352 +			LOG_BUF(cur_index + 0) == '<' &&
  11.353 +			LOG_BUF(cur_index + 1) >= '0' &&
  11.354 +			LOG_BUF(cur_index + 1) <= '7' &&
  11.355 +			LOG_BUF(cur_index + 2) == '>')
  11.356 +		{
  11.357 +			msg_level = LOG_BUF(cur_index + 1) - '0';
  11.358 +			cur_index += 3;
  11.359 +			start_print = cur_index;
  11.360 +		}
  11.361 +		while (cur_index != end) {
  11.362 +			char c = LOG_BUF(cur_index);
  11.363 +			cur_index++;
  11.364 +
  11.365 +			if (c == '\n') {
  11.366 +				if (msg_level < 0) {
  11.367 +					/*
  11.368 +					 * printk() has already given us loglevel tags in
  11.369 +					 * the buffer.  This code is here in case the
  11.370 +					 * log buffer has wrapped right round and scribbled
  11.371 +					 * on those tags
  11.372 +					 */
  11.373 +					msg_level = default_message_loglevel;
  11.374 +				}
  11.375 +				_call_console_drivers(start_print, cur_index, msg_level);
  11.376 +				msg_level = -1;
  11.377 +				start_print = cur_index;
  11.378 +				break;
  11.379 +			}
  11.380 +		}
  11.381 +	}
  11.382 +	_call_console_drivers(start_print, end, msg_level);
  11.383 +}
  11.384 +
  11.385 +static void emit_log_char(char c)
  11.386 +{
  11.387 +	LOG_BUF(log_end) = c;
  11.388 +	log_end++;
  11.389 +	if (log_end - log_start > LOG_BUF_LEN)
  11.390 +		log_start = log_end - LOG_BUF_LEN;
  11.391 +	if (log_end - con_start > LOG_BUF_LEN)
  11.392 +		con_start = log_end - LOG_BUF_LEN;
  11.393 +	if (logged_chars < LOG_BUF_LEN)
  11.394 +		logged_chars++;
  11.395 +}
  11.396 +
  11.397 +/*
  11.398 + * This is printk.  It can be called from any context.  We want it to work.
  11.399 + * 
  11.400 + * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
  11.401 + * call the console drivers.  If we fail to get the semaphore we place the output
  11.402 + * into the log buffer and return.  The current holder of the console_sem will
  11.403 + * notice the new output in release_console_sem() and will send it to the
  11.404 + * consoles before releasing the semaphore.
  11.405 + *
  11.406 + * One effect of this deferred printing is that code which calls printk() and
  11.407 + * then changes console_loglevel may break. This is because console_loglevel
  11.408 + * is inspected when the actual printing occurs.
  11.409 + */
  11.410 +asmlinkage int printk(const char *fmt, ...)
  11.411 +{
  11.412 +	va_list args;
  11.413 +	unsigned long flags;
  11.414 +	int printed_len;
  11.415 +	char *p;
  11.416 +	static char printk_buf[1024];
  11.417 +	static int log_level_unknown = 1;
  11.418 +
  11.419 +	if (oops_in_progress) {
  11.420 +		/* If a crash is occurring, make sure we can't deadlock */
  11.421 +		spin_lock_init(&logbuf_lock);
  11.422 +		/* And make sure that we print immediately */
  11.423 +		init_MUTEX(&console_sem);
  11.424 +	}
  11.425 +
  11.426 +	/* This stops the holder of console_sem just where we want him */
  11.427 +	spin_lock_irqsave(&logbuf_lock, flags);
  11.428 +
  11.429 +	/* Emit the output into the temporary buffer */
  11.430 +	va_start(args, fmt);
  11.431 +	printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
  11.432 +	va_end(args);
  11.433 +
  11.434 +#if 0
  11.435 +// Useful Hack if things are going wrong very early in the day
  11.436 +(void)HYPERVISOR_console_write(printk_buf, sizeof(printk_buf));
  11.437 +#endif
  11.438 +	/*
  11.439 +	 * Copy the output into log_buf.  If the caller didn't provide
  11.440 +	 * appropriate log level tags, we insert them here
  11.441 +	 */
  11.442 +	for (p = printk_buf; *p; p++) {
  11.443 +		if (log_level_unknown) {
  11.444 +			if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') {
  11.445 +				emit_log_char('<');
  11.446 +				emit_log_char(default_message_loglevel + '0');
  11.447 +				emit_log_char('>');
  11.448 +			}
  11.449 +			log_level_unknown = 0;
  11.450 +		}
  11.451 +		emit_log_char(*p);
  11.452 +		if (*p == '\n')
  11.453 +			log_level_unknown = 1;
  11.454 +	}
  11.455 +
  11.456 +	if (!arch_consoles_callable()) {
  11.457 +		/*
  11.458 +		 * On some architectures, the consoles are not usable
  11.459 +		 * on secondary CPUs early in the boot process.
  11.460 +		 */
  11.461 +		spin_unlock_irqrestore(&logbuf_lock, flags);
  11.462 +		goto out;
  11.463 +	}
  11.464 +	if (!down_trylock(&console_sem)) {
  11.465 +		/*
  11.466 +		 * We own the drivers.  We can drop the spinlock and let
  11.467 +		 * release_console_sem() print the text
  11.468 +		 */
  11.469 +		spin_unlock_irqrestore(&logbuf_lock, flags);
  11.470 +		console_may_schedule = 0;
  11.471 +		release_console_sem();
  11.472 +	} else {
  11.473 +		/*
  11.474 +		 * Someone else owns the drivers.  We drop the spinlock, which
  11.475 +		 * allows the semaphore holder to proceed and to call the
  11.476 +		 * console drivers with the output which we just produced.
  11.477 +		 */
  11.478 +		spin_unlock_irqrestore(&logbuf_lock, flags);
  11.479 +	}
  11.480 +out:
  11.481 +	return printed_len;
  11.482 +}
  11.483 +EXPORT_SYMBOL(printk);
  11.484 +
  11.485 +/**
  11.486 + * acquire_console_sem - lock the console system for exclusive use.
  11.487 + *
  11.488 + * Acquires a semaphore which guarantees that the caller has
  11.489 + * exclusive access to the console system and the console_drivers list.
  11.490 + *
  11.491 + * Can sleep, returns nothing.
  11.492 + */
  11.493 +void acquire_console_sem(void)
  11.494 +{
  11.495 +	if (in_interrupt())
  11.496 +		BUG();
  11.497 +	down(&console_sem);
  11.498 +	console_may_schedule = 1;
  11.499 +}
  11.500 +EXPORT_SYMBOL(acquire_console_sem);
  11.501 +
  11.502 +/**
  11.503 + * release_console_sem - unlock the console system
  11.504 + *
  11.505 + * Releases the semaphore which the caller holds on the console system
  11.506 + * and the console driver list.
  11.507 + *
  11.508 + * While the semaphore was held, console output may have been buffered
  11.509 + * by printk().  If this is the case, release_console_sem() emits
  11.510 + * the output prior to releasing the semaphore.
  11.511 + *
  11.512 + * If there is output waiting for klogd, we wake it up.
  11.513 + *
  11.514 + * release_console_sem() may be called from any context.
  11.515 + */
  11.516 +void release_console_sem(void)
  11.517 +{
  11.518 +	unsigned long flags;
  11.519 +	unsigned long _con_start, _log_end;
  11.520 +	unsigned long must_wake_klogd = 0;
  11.521 +
  11.522 +	for ( ; ; ) {
  11.523 +		spin_lock_irqsave(&logbuf_lock, flags);
  11.524 +		must_wake_klogd |= log_start - log_end;
  11.525 +		if (con_start == log_end)
  11.526 +			break;			/* Nothing to print */
  11.527 +		_con_start = con_start;
  11.528 +		_log_end = log_end;
  11.529 +		con_start = log_end;		/* Flush */
  11.530 +		spin_unlock_irqrestore(&logbuf_lock, flags);
  11.531 +		call_console_drivers(_con_start, _log_end);
  11.532 +	}
  11.533 +	console_may_schedule = 0;
  11.534 +	up(&console_sem);
  11.535 +	spin_unlock_irqrestore(&logbuf_lock, flags);
  11.536 +	if (must_wake_klogd && !oops_in_progress)
  11.537 +		wake_up_interruptible(&log_wait);
  11.538 +}
  11.539 +
  11.540 +/** console_conditional_schedule - yield the CPU if required
  11.541 + *
  11.542 + * If the console code is currently allowed to sleep, and
  11.543 + * if this CPU should yield the CPU to another task, do
  11.544 + * so here.
  11.545 + *
  11.546 + * Must be called within acquire_console_sem().
  11.547 + */
  11.548 +void console_conditional_schedule(void)
  11.549 +{
  11.550 +	if (console_may_schedule && current->need_resched) {
  11.551 +		set_current_state(TASK_RUNNING);
  11.552 +		schedule();
  11.553 +	}
  11.554 +}
  11.555 +
  11.556 +void console_print(const char *s)
  11.557 +{
  11.558 +	printk(KERN_EMERG "%s", s);
  11.559 +}
  11.560 +EXPORT_SYMBOL(console_print);
  11.561 +
  11.562 +void console_unblank(void)
  11.563 +{
  11.564 +	struct console *c;
  11.565 +
  11.566 +	acquire_console_sem();
  11.567 +	for (c = console_drivers; c != NULL; c = c->next)
  11.568 +		if ((c->flags & CON_ENABLED) && c->unblank)
  11.569 +			c->unblank();
  11.570 +	release_console_sem();
  11.571 +}
  11.572 +EXPORT_SYMBOL(console_unblank);
  11.573 +
  11.574 +/*
  11.575 + * The console driver calls this routine during kernel initialization
  11.576 + * to register the console printing procedure with printk() and to
  11.577 + * print any messages that were printed by the kernel before the
  11.578 + * console driver was initialized.
  11.579 + */
  11.580 +void register_console(struct console * console)
  11.581 +{
  11.582 +	int     i;
  11.583 +	unsigned long flags;
  11.584 +
  11.585 +	/*
  11.586 +	 *	See if we want to use this console driver. If we
  11.587 +	 *	didn't select a console we take the first one
  11.588 +	 *	that registers here.
  11.589 +	 */
  11.590 +	if (preferred_console < 0) {
  11.591 +		if (console->index < 0)
  11.592 +			console->index = 0;
  11.593 +		if (console->setup == NULL ||
  11.594 +		    console->setup(console, NULL) == 0) {
  11.595 +			console->flags |= CON_ENABLED | CON_CONSDEV;
  11.596 +			preferred_console = 0;
  11.597 +		}
  11.598 +	}
  11.599 +
  11.600 +	/*
  11.601 +	 *	See if this console matches one we selected on
  11.602 +	 *	the command line.
  11.603 +	 */
  11.604 +	for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
  11.605 +		if (strcmp(console_cmdline[i].name, console->name) != 0)
  11.606 +			continue;
  11.607 +		if (console->index >= 0 &&
  11.608 +		    console->index != console_cmdline[i].index)
  11.609 +			continue;
  11.610 +		if (console->index < 0)
  11.611 +			console->index = console_cmdline[i].index;
  11.612 +		if (console->setup &&
  11.613 +		    console->setup(console, console_cmdline[i].options) != 0)
  11.614 +			break;
  11.615 +		console->flags |= CON_ENABLED;
  11.616 +		console->index = console_cmdline[i].index;
  11.617 +		if (i == preferred_console)
  11.618 +			console->flags |= CON_CONSDEV;
  11.619 +		break;
  11.620 +	}
  11.621 +
  11.622 +	if (!(console->flags & CON_ENABLED))
  11.623 +		return;
  11.624 +
  11.625 +	/*
  11.626 +	 *	Put this console in the list - keep the
  11.627 +	 *	preferred driver at the head of the list.
  11.628 +	 */
  11.629 +	acquire_console_sem();
  11.630 +	if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {
  11.631 +		console->next = console_drivers;
  11.632 +		console_drivers = console;
  11.633 +	} else {
  11.634 +		console->next = console_drivers->next;
  11.635 +		console_drivers->next = console;
  11.636 +	}
  11.637 +	if (console->flags & CON_PRINTBUFFER) {
  11.638 +		/*
  11.639 +		 * release_console_sem() will print out the buffered messages for us.
  11.640 +		 */
  11.641 +		spin_lock_irqsave(&logbuf_lock, flags);
  11.642 +		con_start = log_start;
  11.643 +		spin_unlock_irqrestore(&logbuf_lock, flags);
  11.644 +	}
  11.645 +	release_console_sem();
  11.646 +}
  11.647 +EXPORT_SYMBOL(register_console);
  11.648 +
  11.649 +int unregister_console(struct console * console)
  11.650 +{
  11.651 +        struct console *a,*b;
  11.652 +	int res = 1;
  11.653 +
  11.654 +	acquire_console_sem();
  11.655 +	if (console_drivers == console) {
  11.656 +		console_drivers=console->next;
  11.657 +		res = 0;
  11.658 +	} else {
  11.659 +		for (a=console_drivers->next, b=console_drivers ;
  11.660 +		     a; b=a, a=b->next) {
  11.661 +			if (a == console) {
  11.662 +				b->next = a->next;
  11.663 +				res = 0;
  11.664 +				break;
  11.665 +			}  
  11.666 +		}
  11.667 +	}
  11.668 +	
  11.669 +	/* If last console is removed, we re-enable picking the first
  11.670 +	 * one that gets registered. Without that, pmac early boot console
  11.671 +	 * would prevent fbcon from taking over.
  11.672 +	 */
  11.673 +	if (console_drivers == NULL)
  11.674 +		preferred_console = -1;
  11.675 +		
  11.676 +
  11.677 +	release_console_sem();
  11.678 +	return res;
  11.679 +}
  11.680 +EXPORT_SYMBOL(unregister_console);
  11.681 +	
  11.682 +/**
  11.683 + * tty_write_message - write a message to a certain tty, not just the console.
  11.684 + *
  11.685 + * This is used for messages that need to be redirected to a specific tty.
  11.686 + * We don't put it into the syslog queue right now maybe in the future if
  11.687 + * really needed.
  11.688 + */
  11.689 +void tty_write_message(struct tty_struct *tty, char *msg)
  11.690 +{
  11.691 +	if (tty && tty->driver.write)
  11.692 +		tty->driver.write(tty, 0, msg, strlen(msg));
  11.693 +	return;
  11.694 +}
    12.1 --- a/xenolinux-2.4.21-sparse/mkbuildtree	Thu Jul 10 13:42:56 2003 +0000
    12.2 +++ b/xenolinux-2.4.21-sparse/mkbuildtree	Sat Jul 12 18:42:51 2003 +0000
    12.3 @@ -169,7 +169,6 @@ ln -sf ../asm-i386/ucontext.h
    12.4  ln -sf ../asm-i386/unaligned.h
    12.5  ln -sf ../asm-i386/unistd.h 
    12.6  ln -sf ../asm-i386/user.h 
    12.7 -ln -sf ../asm-i386/vga.h 
    12.8  ln -sf ../asm-i386/xor.h 
    12.9  
   12.10  cd ../../arch/xeno/kernel