diff options
author | Olivier Gayot <duskcoder@gmail.com> | 2015-10-29 14:25:57 +0100 |
---|---|---|
committer | Olivier Gayot <duskcoder@gmail.com> | 2015-10-29 14:25:57 +0100 |
commit | 74eb20d8c4810b7757d85f7066359a566621a661 (patch) | |
tree | f511c21ad6d4f2b45ad2c42f689758ea294f2541 | |
parent | e7edce9f232e1359097793b2610e04b16dab7f7e (diff) |
kfs: added the serial print
* 38400 bauds
* 1 stop bit
* no parity check
* 8 bits words
Signed-off-by: Olivier Gayot <duskcoder@gmail.com>
-rw-r--r-- | src/main.c | 48 | ||||
-rw-r--r-- | src/serial.c | 57 | ||||
-rw-r--r-- | src/serial.h | 7 | ||||
-rw-r--r-- | src/uart_16550.h | 24 | ||||
-rw-r--r-- | src/vga.h | 11 |
5 files changed, 118 insertions, 29 deletions
@@ -1,9 +1,5 @@ -#define NB_COLS 80 -#define NB_ROWS 25 -#define BPC 2 -#define BPR (BPC * NB_COLS) - -#define VIDEO_BUFFER 0xB8000 +#include "serial.h" +#include "vga.h" /* XXX doest not always handle memory overlaps */ static void my_memmove(void *_dest, const void *_src, int n) @@ -16,21 +12,12 @@ static void my_memmove(void *_dest, const void *_src, int n) } } -static void my_memset(void *_dest, int c, int n) -{ - char *dest = _dest; - - for (int i = 0; i < n; ++i) { - dest[i] = c; - } -} - static void clear_line(void *_addr) { char *addr = _addr; - for (int i = 0; i < NB_COLS; ++i) { - if (i % BPC == 0) { + for (int i = 0; i < VGA_COLS; ++i) { + if (i % VGA_BPC == 0) { *addr++ = ' '; } else { *addr++ = 0x7; @@ -40,33 +27,33 @@ static void clear_line(void *_addr) int printk(const char *str) { - static const long int offset = VIDEO_BUFFER; - static char *addr = (char *) VIDEO_BUFFER; + static const long int offset = VGA_BASE; + static char *addr = (char *) VGA_BASE; int count = 0; for (int i = 0; str[i]; ++i) { - /* TODO add the serial port handling */ + serial_putchar(str[i]); char chr; char *new_addr = addr; - char *addr_line = (char *)(((long)(addr - offset) / BPR) * BPR) + offset; + char *addr_line = (char *)(((long)(addr - offset) / VGA_BPR) * + VGA_BPR) + offset; - if ((long)addr >= offset + NB_ROWS * BPR) { + if ((long)addr >= offset + VGA_ROWS * VGA_BPR) { /* shift up */ - addr -= BPR; - addr_line -= BPR; - my_memmove((void *)offset, (void *)offset + BPR, BPR * (NB_ROWS - 1)); - clear_line(addr_line); + addr -= VGA_BPR; + addr_line -= VGA_BPR; + my_memmove((void *)offset, (void *)offset + VGA_BPR, VGA_BPR + * (VGA_ROWS - 1)); clear_line(addr_line); } - switch (str[i]) { case '\n': - new_addr = addr_line + BPR; + new_addr = addr_line + VGA_BPR; chr = '\0'; break; default: - new_addr = addr + BPC; + new_addr = addr + VGA_BPC; chr = str[i]; break; } @@ -83,4 +70,7 @@ int printk(const char *str) int main(void) { + serial_init(); + + return 0; } diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..720d454 --- /dev/null +++ b/src/serial.c @@ -0,0 +1,57 @@ +#define COM1_BASE 0x3f8 +#define COM2_BASE 0x2f8 +#define COM3_BASE 0x3e8 +#define COM4_BASE 0x2e8 + +#include "uart_16550.h" + +static inline void outb(unsigned char value, unsigned short port) +{ + asm volatile("outb %0,%1" : : "a" (value), "dN" (port)); +} + +static inline unsigned char inb(unsigned short port) +{ + unsigned char value; + + asm volatile("inb %1,%0" : "=a" (value) : "dN" (port)); + + return value; +} + +int serial_putchar(unsigned char c) +{ + outb(c, COM1_BASE); + + return 1; +} + +int serial_init(void) +{ + /* set the communication parameters */ + unsigned char lcr_value = 0x0; + + lcr_value = DATA_WORD_LEN_8 + | STOP_BIT_1 + | PARITY_NONE + | BREAK_SIGNAL_DISABLED + | DLAB_ACCESSIBLE_DLL_DLM; + + outb(lcr_value, COM1_BASE + 3); + + unsigned char dll_value = 0x03; + unsigned char dlm_value = 0x00; + + outb(dll_value, COM1_BASE + 0); + outb(dlm_value, COM1_BASE + 1); + + lcr_value = DATA_WORD_LEN_8 + | STOP_BIT_1 + | PARITY_NONE + | BREAK_SIGNAL_DISABLED + | DLAB_ACCESSIBLE_RBR_THR_IER; + + outb(lcr_value, COM1_BASE + 3); + + return 0; +} diff --git a/src/serial.h b/src/serial.h new file mode 100644 index 0000000..da70b03 --- /dev/null +++ b/src/serial.h @@ -0,0 +1,7 @@ +#ifndef SERIAL_H +#define SERIAL_H + +int serial_putchar(unsigned char c); +int serial_init(void); + +#endif /* SERIAL_H */ diff --git a/src/uart_16550.h b/src/uart_16550.h new file mode 100644 index 0000000..2e20eff --- /dev/null +++ b/src/uart_16550.h @@ -0,0 +1,24 @@ +#ifndef UART_16550_H +#define UART_16550_H + +#define DATA_WORD_LEN_5 0b00 +#define DATA_WORD_LEN_6 0b01 +#define DATA_WORD_LEN_7 0b10 +#define DATA_WORD_LEN_8 0b11 + +#define STOP_BIT_1 0b000 +#define STOP_BIT_2 0b100 /* 1.5 stop bits for 5 bits words */ + +#define PARITY_NONE 0b000000 +#define PARITY_ODD 0b001000 +#define PARITY_EVEN 0b011000 +#define PARITY_HIGH 0b101000 +#define PARITY_LOW 0b111000 + +#define BREAK_SIGNAL_DISABLED 0b0000000 +#define BREAK_SIGNAL_ENABLED 0b1000000 + +#define DLAB_ACCESSIBLE_RBR_THR_IER 0b00000000 +#define DLAB_ACCESSIBLE_DLL_DLM 0b10000000 + +#endif /* UART_16550_H */ diff --git a/src/vga.h b/src/vga.h new file mode 100644 index 0000000..a8f41ba --- /dev/null +++ b/src/vga.h @@ -0,0 +1,11 @@ +#ifndef VGA_H +#define VGA_H + +#define VGA_BASE 0xB8000 + +#define VGA_COLS 80 +#define VGA_ROWS 25 +#define VGA_BPC 2 +#define VGA_BPR (VGA_BPC * VGA_COLS) + +#endif /* VGA_H */ |