diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-04-14 14:52:27 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-04-14 14:52:27 +0100 |
commit | 71c0c5fbe55c257427523828842df80f8529847a (patch) | |
tree | 10dc24223f84b507478fedb42abfcabd44728c77 | |
parent | 0c75fee1bc3154c21078c61787a52058aae984e2 (diff) | |
download | xen-71c0c5fbe55c257427523828842df80f8529847a.tar.gz xen-71c0c5fbe55c257427523828842df80f8529847a.tar.bz2 xen-71c0c5fbe55c257427523828842df80f8529847a.zip |
New option conring_size= to allow larger console ring.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/arch/ia64/xen/xensetup.c | 5 | ||||
-rw-r--r-- | xen/arch/x86/setup.c | 6 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 61 | ||||
-rw-r--r-- | xen/include/xen/console.h | 3 |
4 files changed, 56 insertions, 19 deletions
diff --git a/xen/arch/ia64/xen/xensetup.c b/xen/arch/ia64/xen/xensetup.c index c3affb4b0d..61b1d11e1c 100644 --- a/xen/arch/ia64/xen/xensetup.c +++ b/xen/arch/ia64/xen/xensetup.c @@ -374,7 +374,6 @@ void __init start_kernel(void) ns16550_init(0, &ns16550_com1); ns16550_init(1, &ns16550_com2); } - serial_init_preirq(); #ifdef CONFIG_VGA /* Plug in a default VGA mode */ @@ -390,7 +389,7 @@ void __init start_kernel(void) ia64_boot_param->console_info.num_cols; #endif - init_console(); + console_init_preirq(); if (running_on_sim || ia64_boot_param->domain_start == 0 || ia64_boot_param->domain_size == 0) { @@ -648,7 +647,7 @@ printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus); ns16550_init(0, &ns16550_com1); } } - serial_init_postirq(); + console_init_postirq(); } expose_p2m_init(); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 8cf4190144..bf04e43280 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -463,9 +463,7 @@ void __init __start_xen(unsigned long mbi_p) ns16550.io_base = 0x2f8; ns16550.irq = 3; ns16550_init(1, &ns16550); - serial_init_preirq(); - - init_console(); + console_init_preirq(); printk("Command line: %s\n", cmdline); @@ -958,7 +956,7 @@ void __init __start_xen(unsigned long mbi_p) initialize_keytable(); - serial_init_postirq(); + console_init_postirq(); for_each_present_cpu ( i ) { diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index f6ce51aad8..38c540a470 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -58,10 +58,16 @@ boolean_param("console_to_ring", opt_console_to_ring); static int opt_console_timestamps; boolean_param("console_timestamps", opt_console_timestamps); -#define CONRING_SIZE 16384 -#define CONRING_IDX_MASK(i) ((i)&(CONRING_SIZE-1)) -static char conring[CONRING_SIZE]; -static uint32_t conringc, conringp; +/* conring_size: allows a large console ring than default (16kB). */ +static uint32_t opt_conring_size; +static void parse_conring_size(char *s) +{ opt_conring_size = parse_size_and_unit(s, NULL); } +custom_param("conring_size", parse_conring_size); + +#define _CONRING_SIZE 16384 +#define CONRING_IDX_MASK(i) ((i)&(conring_size-1)) +static char _conring[_CONRING_SIZE], *conring = _conring; +static uint32_t conring_size = _CONRING_SIZE, conringc, conringp; static int sercon_handle = -1; @@ -178,8 +184,8 @@ static void putchar_console_ring(int c) { ASSERT(spin_is_locked(&console_lock)); conring[CONRING_IDX_MASK(conringp++)] = c; - if ( (uint32_t)(conringp - conringc) > CONRING_SIZE ) - conringc = conringp - CONRING_SIZE; + if ( (uint32_t)(conringp - conringc) > conring_size ) + conringc = conringp - conring_size; } long read_console_ring(struct xen_sysctl_readconsole *op) @@ -199,8 +205,8 @@ long read_console_ring(struct xen_sysctl_readconsole *op) { idx = CONRING_IDX_MASK(c); len = conringp - c; - if ( (idx + len) > CONRING_SIZE ) - len = CONRING_SIZE - idx; + if ( (idx + len) > conring_size ) + len = conring_size - idx; if ( (sofar + len) > max ) len = max - sofar; if ( copy_to_guest_offset(str, sofar, &conring[idx], len) ) @@ -212,8 +218,8 @@ long read_console_ring(struct xen_sysctl_readconsole *op) if ( op->clear ) { spin_lock_irq(&console_lock); - if ( (uint32_t)(conringp - c) > CONRING_SIZE ) - conringc = conringp - CONRING_SIZE; + if ( (uint32_t)(conringp - c) > conring_size ) + conringc = conringp - conring_size; else conringc = c; spin_unlock_irq(&console_lock); @@ -544,10 +550,12 @@ void printk(const char *fmt, ...) local_irq_restore(flags); } -void __init init_console(void) +void __init console_init_preirq(void) { char *p; + serial_init_preirq(); + /* Where should console output go? */ for ( p = opt_console; p != NULL; p = strchr(p, ',') ) { @@ -587,6 +595,37 @@ void __init init_console(void) } } +void __init console_init_postirq(void) +{ + char *ring; + unsigned int i; + + serial_init_postirq(); + + /* Round size down to a power of two. */ + while ( opt_conring_size & (opt_conring_size - 1) ) + opt_conring_size &= opt_conring_size - 1; + if ( opt_conring_size < conring_size ) + return; + + ring = xmalloc_bytes(opt_conring_size); + if ( ring == NULL ) + { + printk("Unable to allocate console ring of %u bytes.\n", + opt_conring_size); + return; + } + + spin_lock_irq(&console_lock); + for ( i = conringc ; i != conringp; i++ ) + ring[i & (opt_conring_size - 1)] = conring[i & (conring_size - 1)]; + conring_size = opt_conring_size; + conring = ring; + spin_unlock_irq(&console_lock); + + printk("Allocated console ring of %u bytes.\n", opt_conring_size); +} + void __init console_endboot(void) { int i, j; diff --git a/xen/include/xen/console.h b/xen/include/xen/console.h index 5817f74958..50dd1e582e 100644 --- a/xen/include/xen/console.h +++ b/xen/include/xen/console.h @@ -14,7 +14,8 @@ struct xen_sysctl_readconsole; long read_console_ring(struct xen_sysctl_readconsole *op); -void init_console(void); +void console_init_preirq(void); +void console_init_postirq(void); void console_endboot(void); int console_has(const char *device); |