From 08331210bb2ed3eae4b2aced1946aba4d4ffd4c6 Mon Sep 17 00:00:00 2001 From: "Peter H. Froehlich" Date: Fri, 2 Oct 2015 23:00:29 -0400 Subject: [PATCH] New uart.h header and adjusted uart.c driver. --- uart.c | 43 +++++++++++++++++++------------------------ uart.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 24 deletions(-) create mode 100644 uart.h diff --git a/uart.c b/uart.c index 576e254..d88a859 100644 --- a/uart.c +++ b/uart.c @@ -2,16 +2,9 @@ #include "types.h" #include "defs.h" -#include "param.h" #include "traps.h" -#include "spinlock.h" -#include "fs.h" -#include "file.h" -#include "mmu.h" -#include "proc.h" #include "x86.h" - -#define COM1 0x3f8 +#include "uart.h" static int uart; // is there a uart? @@ -21,28 +14,30 @@ uartinit(void) char *p; // Turn off the FIFO - outb(COM1+2, 0); - + outb(COM1+UART_FIFO_CONTROL, 0); + // 9600 baud, 8 data bits, 1 stop bit, parity off. - outb(COM1+3, 0x80); // Unlock divisor - outb(COM1+0, 115200/9600); - outb(COM1+1, 0); - outb(COM1+3, 0x03); // Lock divisor, 8 data bits. - outb(COM1+4, 0); - outb(COM1+1, 0x01); // Enable receive interrupts. + outb(COM1+UART_LINE_CONTROL, UART_DIVISOR_LATCH); // Unlock divisor + outb(COM1+UART_DIVISOR_LOW, 115200/9600); + outb(COM1+UART_DIVISOR_HIGH, 0); + outb(COM1+UART_LINE_CONTROL, 0x03); // Lock divisor, 8 data bits. + outb(COM1+UART_MODEM_CONTROL, 0); + + // Enable receive interrupts. + outb(COM1+UART_INTERRUPT_ENABLE, UART_RECEIVE_INTERRUPT); // If status is 0xFF, no serial port. - if(inb(COM1+5) == 0xFF) + if(inb(COM1+UART_LINE_STATUS) == 0xFF) return; uart = 1; // Acknowledge pre-existing interrupt conditions; // enable interrupts. - inb(COM1+2); - inb(COM1+0); + inb(COM1+UART_INTERRUPT_ID); + inb(COM1+UART_RECEIVE_BUFFER); picenable(IRQ_COM1); ioapicenable(IRQ_COM1, 0); - + // Announce that we're here. for(p="xv6...\n"; *p; p++) uartputc(*p); @@ -55,9 +50,9 @@ uartputc(int c) if(!uart) return; - for(i = 0; i < 128 && !(inb(COM1+5) & 0x20); i++) + for(i = 0; i < 128 && !(inb(COM1+UART_LINE_STATUS) & UART_TRANSMIT_READY); i++) microdelay(10); - outb(COM1+0, c); + outb(COM1+UART_TRANSMIT_BUFFER, c); } static int @@ -65,9 +60,9 @@ uartgetc(void) { if(!uart) return -1; - if(!(inb(COM1+5) & 0x01)) + if(!(inb(COM1+UART_LINE_STATUS) & UART_RECEIVE_READY)) return -1; - return inb(COM1+0); + return inb(COM1+UART_RECEIVE_BUFFER); } void diff --git a/uart.h b/uart.h new file mode 100644 index 0000000..1d38920 --- /dev/null +++ b/uart.h @@ -0,0 +1,33 @@ +// Definitions for Intel 8250 serial port (UART). + +// Base addresses. +#define COM1 0x3f8 +#define COM2 0x2f8 +#define COM3 0x3e8 +#define COM4 0x2e8 + +// Registers. Note that the same address can refer to different +// internal registers depending on read/write/DLAB (the "divisor +// latch access bit," see below). +#define UART_TRANSMIT_BUFFER 0 // write +#define UART_RECEIVE_BUFFER 0 // read +#define UART_DIVISOR_LOW 0 // read/write DLAB +#define UART_INTERRUPT_ENABLE 1 // read/write +#define UART_DIVISOR_HIGH 1 // read/write DLAB +#define UART_INTERRUPT_ID 2 // read +#define UART_FIFO_CONTROL 2 // write +#define UART_LINE_CONTROL 3 // read/write +#define UART_MODEM_CONTROL 4 // read/write +#define UART_LINE_STATUS 5 // read +#define UART_MODEM_STATUS 6 // read +#define UART_SCRATCH 7 // read/write + +// Bits in the line control register. +#define UART_DIVISOR_LATCH (1 << 7) // Unlock divisor latch. + +// Bits in the line status register. +#define UART_TRANSMIT_READY (1 << 5) // Can send more data. +#define UART_RECEIVE_READY (1 << 0) // Have received some data. + +// Bits in the interrupt enable register. +#define UART_RECEIVE_INTERRUPT (1 << 0) // Have received some data. -- 2.50.1