diff options
| -rw-r--r-- | kernel/console.c | 4 | ||||
| -rw-r--r-- | kernel/uart.c | 62 | 
2 files changed, 40 insertions, 26 deletions
| diff --git a/kernel/console.c b/kernel/console.c index 6fb79cd..87a83ff 100644 --- a/kernel/console.c +++ b/kernel/console.c @@ -192,6 +192,8 @@ consoleinit(void)    uartinit(); -  devsw[CONSOLE].write = consolewrite; +  // connect read and write system calls +  // to consoleread and consolewrite.    devsw[CONSOLE].read = consoleread; +  devsw[CONSOLE].write = consolewrite;  } diff --git a/kernel/uart.c b/kernel/uart.c index ba66237..852a085 100644 --- a/kernel/uart.c +++ b/kernel/uart.c @@ -1,3 +1,7 @@ +// +// low-level driver routines for 16550a UART. +// +  #include "types.h"  #include "param.h"  #include "memlayout.h" @@ -6,41 +10,49 @@  #include "proc.h"  #include "defs.h" -// -// qemu -machine virt has a 16550a UART -// qemu/hw/riscv/virt.c +// the UART control registers are memory-mapped +// at address UART0. this macro returns the +// address of one of the registers. +#define Reg(reg) ((volatile unsigned char *)(UART0 + reg)) + +// the registers. some have different meanings for +// read and write.  // http://byterunner.com/16550.html -// -// caller should lock. -// +#define RHR 0 // receive holding register (for input bytes) +#define THR 0 // transmit holding register (for output bytes) +#define IER 1 // interrupt enable register +#define FCR 2 // FIFO control register +#define ISR 2 // interrupt status register +#define LCR 3 // line control register +#define LSR 5 // line status register -// address of one of the registers -#define R(reg) ((volatile unsigned char *)(UART0 + reg)) +#define ReadReg(reg) (*(Reg(reg))) +#define WriteReg(reg, v) (*(Reg(reg)) = (v))  void  uartinit(void)  { -  // disable interrupts -- IER -  *R(1) = 0x00; +  // disable interrupts. +  WriteReg(IER, 0x00); -  // special mode to set baud rate -  *R(3) = 0x80; +  // special mode to set baud rate. +  WriteReg(LCR, 0x80); -  // LSB for baud rate of 38.4K -  *R(0) = 0x03; +  // LSB for baud rate of 38.4K. +  WriteReg(0, 0x03); -  // MSB for baud rate of 38.4K -  *R(1) = 0x00; +  // MSB for baud rate of 38.4K. +  WriteReg(1, 0x00);    // leave set-baud mode,    // and set word length to 8 bits, no parity. -  *R(3) = 0x03; +  WriteReg(LCR, 0x03); -  // reset and enable FIFOs -- FCR. -  *R(2) = 0x07; +  // reset and enable FIFOs. +  WriteReg(FCR, 0x07); -  // enable receive interrupts -- IER. -  *R(1) = 0x01; +  // enable receive interrupts. +  WriteReg(IER, 0x01);  }  // write one output character to the UART. @@ -48,9 +60,9 @@ void  uartputc(int c)  {    // wait for Transmit Holding Empty to be set in LSR. -  while((*R(5) & (1 << 5)) == 0) +  while((ReadReg(LSR) & (1 << 5)) == 0)      ; -  *R(0) = c; +  WriteReg(THR, c);  }  // read one input character from the UART. @@ -58,9 +70,9 @@ uartputc(int c)  int  uartgetc(void)  { -  if(*R(5) & 0x01){ +  if(ReadReg(LSR) & 0x01){      // input data is ready. -    return *R(0); +    return ReadReg(RHR);    } else {      return -1;    } | 
