fix printf() in interrupts
This commit is contained in:
parent
823864099d
commit
db0f092ae4
|
@ -42,9 +42,9 @@ consputc(int c)
|
||||||
|
|
||||||
if(c == BACKSPACE){
|
if(c == BACKSPACE){
|
||||||
// if the user typed backspace, overwrite with a space.
|
// if the user typed backspace, overwrite with a space.
|
||||||
uartputc('\b', 0); uartputc(' ', 0); uartputc('\b', 0);
|
uartputc_sync('\b'); uartputc_sync(' '); uartputc_sync('\b');
|
||||||
} else {
|
} else {
|
||||||
uartputc(c, 0);
|
uartputc_sync(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ consolewrite(int user_src, uint64 src, int n)
|
||||||
char c;
|
char c;
|
||||||
if(either_copyin(&c, user_src, src+i, 1) == -1)
|
if(either_copyin(&c, user_src, src+i, 1) == -1)
|
||||||
break;
|
break;
|
||||||
uartputc(c, 1);
|
uartputc(c);
|
||||||
}
|
}
|
||||||
release(&cons.lock);
|
release(&cons.lock);
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,8 @@ void usertrapret(void);
|
||||||
// uart.c
|
// uart.c
|
||||||
void uartinit(void);
|
void uartinit(void);
|
||||||
void uartintr(void);
|
void uartintr(void);
|
||||||
void uartputc(int, int);
|
void uartputc(int);
|
||||||
|
void uartputc_sync(int);
|
||||||
int uartgetc(void);
|
int uartgetc(void);
|
||||||
|
|
||||||
// vm.c
|
// vm.c
|
||||||
|
|
|
@ -69,33 +69,19 @@ uartinit(void)
|
||||||
|
|
||||||
// add a character to the output buffer and tell the
|
// add a character to the output buffer and tell the
|
||||||
// UART to start sending if it isn't already.
|
// UART to start sending if it isn't already.
|
||||||
//
|
// blocks if the output buffer is full.
|
||||||
// usually called from the top-half -- by a process
|
// because it may block, it can't be called
|
||||||
// calling write(). can also be called from a uart
|
// from interrupts; it's only suitable for use
|
||||||
// interrupt to echo a received character, or by printf
|
// by write().
|
||||||
// or panic from anywhere in the kernel.
|
|
||||||
//
|
|
||||||
// the block argument controls what happens if the
|
|
||||||
// buffer is full. for write(), block is 1, and the
|
|
||||||
// process waits. for kernel printf's and echoed
|
|
||||||
// characters, block is 0, and the character is
|
|
||||||
// discarded; this is necessary since sleep() is
|
|
||||||
// not possible in interrupts.
|
|
||||||
void
|
void
|
||||||
uartputc(int c, int block)
|
uartputc(int c)
|
||||||
{
|
{
|
||||||
acquire(&uart_tx_lock);
|
acquire(&uart_tx_lock);
|
||||||
while(1){
|
while(1){
|
||||||
if(((uart_tx_w + 1) % UART_TX_BUF_SIZE) == uart_tx_r){
|
if(((uart_tx_w + 1) % UART_TX_BUF_SIZE) == uart_tx_r){
|
||||||
// buffer is full.
|
// buffer is full.
|
||||||
if(block){
|
|
||||||
// wait for uartstart() to open up space in the buffer.
|
// wait for uartstart() to open up space in the buffer.
|
||||||
sleep(&uart_tx_r, &uart_tx_lock);
|
sleep(&uart_tx_r, &uart_tx_lock);
|
||||||
} else {
|
|
||||||
// caller does not want us to wait.
|
|
||||||
release(&uart_tx_lock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uart_tx_buf[uart_tx_w] = c;
|
uart_tx_buf[uart_tx_w] = c;
|
||||||
uart_tx_w = (uart_tx_w + 1) % UART_TX_BUF_SIZE;
|
uart_tx_w = (uart_tx_w + 1) % UART_TX_BUF_SIZE;
|
||||||
|
@ -106,6 +92,23 @@ uartputc(int c, int block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// alternate version of uartputc() that doesn't
|
||||||
|
// use interrupts, for use by kernel printf() and
|
||||||
|
// to echo characters. it spins waiting for the uart's
|
||||||
|
// output register to be empty.
|
||||||
|
void
|
||||||
|
uartputc_sync(int c)
|
||||||
|
{
|
||||||
|
push_off();
|
||||||
|
|
||||||
|
// wait for Transmit Holding Empty to be set in LSR.
|
||||||
|
while((ReadReg(LSR) & (1 << 5)) == 0)
|
||||||
|
;
|
||||||
|
WriteReg(THR, c);
|
||||||
|
|
||||||
|
pop_off();
|
||||||
|
}
|
||||||
|
|
||||||
// if the UART is idle, and a character is waiting
|
// if the UART is idle, and a character is waiting
|
||||||
// in the transmit buffer, send it.
|
// in the transmit buffer, send it.
|
||||||
// caller must hold uart_tx_lock.
|
// caller must hold uart_tx_lock.
|
||||||
|
|
Loading…
Reference in a new issue