{
keyhandler_t *h;
unsigned char key = keypress_key;
- console_start_sync();
+ console_start_log_everything();
if ( (h = key_table[key].u.handler) != NULL )
(*h)(key);
- console_end_sync();
+ console_end_log_everything();
}
static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0);
if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) )
{
- console_start_sync();
+ console_start_log_everything();
if ( (h = key_table[key].u.irq_handler) != NULL )
(*h)(key, regs);
- console_end_sync();
+ console_end_log_everything();
}
else
{
{
unsigned int cpu;
+ /* We want to get everything out that we possibly can. */
+ console_start_sync();
+
printk("'%c' pressed -> dumping registers\n", key);
/* Get local execution state out immediately, in case we get stuck. */
}
printk("\n");
+
+ console_end_sync();
}
static void dump_dom0_registers(unsigned char key)
return 0;
}
+void console_start_log_everything(void)
+{
+ serial_start_log_everything(sercon_handle);
+ atomic_inc(&print_everything);
+}
+
+void console_end_log_everything(void)
+{
+ serial_end_log_everything(sercon_handle);
+ atomic_dec(&print_everything);
+}
+
void console_force_unlock(void)
{
spin_lock_init(&console_lock);
if ( (port->txbufp - port->txbufc) == serial_txbufsz )
{
-#ifdef SERIAL_NEVER_DROP_CHARS
- /* Buffer is full: we spin waiting for space to appear. */
- int i;
- while ( !port->driver->tx_empty(port) )
- cpu_relax();
- for ( i = 0; i < port->tx_fifo_size; i++ )
- port->driver->putc(
- port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
- port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c;
-#else
- /* Buffer is full: drop characters until buffer is half empty. */
- port->tx_quench = 1;
-#endif
+ if ( port->tx_log_everything )
+ {
+ /* Buffer is full: we spin waiting for space to appear. */
+ int i;
+ while ( !port->driver->tx_empty(port) )
+ cpu_relax();
+ for ( i = 0; i < port->tx_fifo_size; i++ )
+ port->driver->putc(
+ port,
+ port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
+ port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c;
+ }
+ else
+ {
+ /* Buffer is full: drop chars until buffer is half empty. */
+ port->tx_quench = 1;
+ }
return;
}
spin_unlock_irqrestore(&port->tx_lock, flags);
}
+void serial_start_log_everything(int handle)
+{
+ struct serial_port *port;
+ unsigned long flags;
+
+ if ( handle == -1 )
+ return;
+
+ port = &com[handle & SERHND_IDX];
+
+ spin_lock_irqsave(&port->tx_lock, flags);
+ port->tx_log_everything++;
+ port->tx_quench = 0;
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+}
+
+void serial_end_log_everything(int handle)
+{
+ struct serial_port *port;
+ unsigned long flags;
+
+ if ( handle == -1 )
+ return;
+
+ port = &com[handle & SERHND_IDX];
+
+ spin_lock_irqsave(&port->tx_lock, flags);
+ port->tx_log_everything--;
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+}
+
int serial_tx_space(int handle)
{
struct serial_port *port;
void console_start_sync(void);
void console_end_sync(void);
+void console_start_log_everything(void);
+void console_end_log_everything(void);
+
/*
* Steal output from the console. Returns +ve identifier, else -ve error.
* Takes the handle of the serial line to steal, and steal callback function.
char *txbuf;
unsigned int txbufp, txbufc;
bool_t tx_quench;
+ int tx_log_everything;
/* Force synchronous transmit. */
int sync;
/* Receiver callback functions (asynchronous receivers). */
void serial_start_sync(int handle);
void serial_end_sync(int handle);
+/* Start/end a region where we will wait rather than drop characters. */
+void serial_start_log_everything(int handle);
+void serial_end_log_everything(int handle);
+
/* Return number of bytes headroom in transmit buffer. */
int serial_tx_space(int handle);