diff options
Diffstat (limited to 'kernel/serial.c')
| -rw-r--r-- | kernel/serial.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/serial.c b/kernel/serial.c new file mode 100644 index 0000000..7f23298 --- /dev/null +++ b/kernel/serial.c @@ -0,0 +1,52 @@ +#include <asm/io.h> +#include <kernel/con.h> + +/* 115200 baud */ +#define DIVISOR 1 + +#define RSBASE 0x3F8 + +#define RSDATA RSBASE +#define RSINTEN (RSBASE + 1) +#define RSFIFOC (RSBASE + 2) +#define RSLINEC (RSBASE + 3) +#define RSMODEMC (RSBASE + 4) +#define RSLINES (RSBASE + 5) +#define RSMODEMS (RSBASE + 6) +#define RSSCRATCH (RSBASE + 7) + +static int rsputs(char *s) { + while(*s) { + while((inb(RSLINES) & 0x20) == 0); + outb(RSDATA, *s++); + } + + return 0; +} + +void serial_init(void) { + outb(RSSCRATCH, 0x00); + outb(RSSCRATCH, 0xAA); + if(inb(RSSCRATCH) != 0xAA) { + printk("[rs] COM0 not detected!\n"); + return; + } + + /* enable access to the divisor */ + outb(RSLINEC, inb(RSLINEC) | 0x80); + /* write the divisor */ + outb(RSBASE, DIVISOR); + outb(RSBASE + 1, DIVISOR >> 8); + /* restore access to the divisor */ + outb(RSLINEC, inb(RSLINEC) & 0x7F); + /* configure port parameters */ + outb(RSLINEC, 0x03); + outb(RSINTEN, 0x00); + + rsputs("[kernel] Serial monitor initialized!\n\r"); + printk("[rs] Serial port COM0 initialized!\n"); +} + +int sys_rsputs(char *s) { + return rsputs(s); +} |
