diff options
author | Robert Morris <[email protected]> | 2019-06-11 09:57:14 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2019-06-11 09:57:14 -0400 |
commit | 5753553213df8f9de851adb68377db43faecb91f (patch) | |
tree | 3b629ff54897fca414146677532cb459a2ed11ba /kernel/uart.c | |
parent | 91ba81110acd3163f7de3580b677eece0c57f5e7 (diff) | |
download | xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.gz xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.bz2 xv6-labs-5753553213df8f9de851adb68377db43faecb91f.zip |
separate source into kernel/ user/ mkfs/
Diffstat (limited to 'kernel/uart.c')
-rw-r--r-- | kernel/uart.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/kernel/uart.c b/kernel/uart.c new file mode 100644 index 0000000..35fac1b --- /dev/null +++ b/kernel/uart.c @@ -0,0 +1,75 @@ +#include "types.h" +#include "param.h" +#include "memlayout.h" +#include "riscv.h" +#include "proc.h" +#include "spinlock.h" +#include "defs.h" + +// +// qemu -machine virt has a 16550a UART +// qemu/hw/riscv/virt.c +// http://byterunner.com/16550.html +// +// caller should lock. +// + +// address of one of the registers +#define R(reg) ((volatile unsigned char *)(UART0 + reg)) + +void +uartinit(void) +{ + // disable interrupts -- IER + *R(1) = 0x00; + + // special mode to set baud rate + *R(3) = 0x80; + + // LSB for baud rate of 38.4K + *R(0) = 0x03; + + // MSB for baud rate of 38.4K + *R(1) = 0x00; + + // leave set-baud mode, + // and set word length to 8 bits, no parity. + *R(3) = 0x03; + + // reset and enable FIFOs -- FCR. + *R(2) = 0x07; + + // enable receive interrupts -- IER. + *R(1) = 0x01; +} + +void +uartputc(int c) +{ + // wait for Transmit Holding Empty to be set in LSR. + while((*R(5) & (1 << 5)) == 0) + ; + *R(0) = c; +} + +int +uartgetc(void) +{ + if(*R(5) & 0x01){ + // input data is ready. + return *R(0); + } else { + return -1; + } +} + +void +uartintr(void) +{ + while(1){ + int c = uartgetc(); + if(c == -1) + break; + consoleintr(c); + } +} |