aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-04-14 14:52:27 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-04-14 14:52:27 +0100
commit71c0c5fbe55c257427523828842df80f8529847a (patch)
tree10dc24223f84b507478fedb42abfcabd44728c77
parent0c75fee1bc3154c21078c61787a52058aae984e2 (diff)
downloadxen-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.c5
-rw-r--r--xen/arch/x86/setup.c6
-rw-r--r--xen/drivers/char/console.c61
-rw-r--r--xen/include/xen/console.h3
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);