Serial support

This commit is contained in:
Ali Mashtizadeh 2014-07-13 13:04:14 -07:00
parent 65fb17870e
commit 34aad175e9
4 changed files with 127 additions and 0 deletions

View File

@ -20,6 +20,7 @@ src_amd64 = [
"amd64/ioapic.c",
"amd64/irq.c",
"dev/x86/debugcons.c",
"dev/x86/sercons.c",
"dev/x86/vgacons.c",
"dev/x86/ide.c",
]

View File

@ -3,21 +3,42 @@
#include "console.h"
#include "x86/vgacons.h"
#include "x86/sercons.h"
#include "x86/debugcons.h"
/*
* Initialize console devices for debugging purposes. At this point interrupts
* and device state is not initialized.
*/
void
Console_Init()
{
VGA_Init();
Serial_Init();
DebugConsole_Init();
Console_Puts("Castor Operating System\n");
}
/*
* Setup interrupts and input devices that may not be ready
*/
void
Console_LateInit()
{
Serial_LateInit();
}
void
Console_Getc(char ch)
{
}
void
Console_Putc(char ch)
{
VGA_Putc(ch);
Serial_Putc(ch);
DebugConsole_Putc(ch);
}
@ -25,6 +46,7 @@ void
Console_Puts(const char *str)
{
VGA_Puts(str);
Serial_Puts(str);
DebugConsole_Puts(str);
}

View File

@ -0,0 +1,96 @@
#include <stdint.h>
#include <kassert.h>
#include <irq.h>
#include "ioport.h"
#include "sercons.h"
#define COM1_BASE 0x3F8
#define COM2_BASE 0x2F8
#define COM3_BASE 0x3E8
#define COM4_BASE 0x2E8
#define COM1_IRQ 4
#define COM2_IRQ 3
#define COM3_IRQ 4
#define COM4_IRQ 3
// Inputs
#define UART_OFFSET_DATA 0 /* Data Register */
#define UART_OFFSET_IER 1 /* Interrupt Enable Register */
#define UART_OFFSET_IIR 2 /* Interrupt Identification & FIFO Control */
#define UART_OFFSET_LCR 3 /* Line Control Register */
#define UART_LCR_DLAB 0x80
#define UART_LCR_8N1 0x03
#define UART_OFFSET_MCR 4 /* Modem Control Register */
#define UART_OFFSET_LSR 5 /* Line Status Register */
#define UART_OFFSET_MSR 6 /* Modem Status Register */
#define UART_OFFSET_SR 7 /* Scratch Register */
#define UART_OFFSET_DIVLO 0 /* Divisors DLAB == 1 */
#define UART_OFFSET_DIVHI 1
IRQHandler handler;
uint16_t base;
uint8_t irq;
void Serial_Init(void)
{
base = COM1_BASE;
irq = COM1_IRQ;
// Disable interrupts
outb(base + UART_OFFSET_IER, 0);
// Enable DLAB
outb(base + UART_OFFSET_LCR, UART_LCR_DLAB);
outb(base + UART_OFFSET_DIVLO, 1); // 115200 Baud
outb(base + UART_OFFSET_DIVLO, 0);
outb(base + UART_OFFSET_LCR, UART_LCR_8N1);
// Enable interrupts
outb(base + UART_OFFSET_IIR, 0xC7);
outb(base + UART_OFFSET_MCR, 0x0B);
}
void Serial_LateInit(void)
{
handler.irq = irq;
handler.cb = &Serial_Interrupt;
handler.arg = NULL;
IRQ_Register(irq, &handler);
}
void Serial_Interrupt(void *arg)
{
kprintf("Serial interrupt!\n");
}
char Serial_Getc()
{
while ((inb(base + UART_OFFSET_LSR) & 0x01) == 0)
{
// Timeout!
}
return inb(base + UART_OFFSET_DATA);
}
void Serial_Putc(char ch)
{
while ((inb(base + UART_OFFSET_LSR) & 0x20) == 0)
{
// Timeout!
}
outb(base + UART_OFFSET_DATA, ch);
}
void Serial_Puts(const char *str)
{
const char *p = str;
while (*p != '\0')
Serial_Putc(*p++);
}

View File

@ -0,0 +1,8 @@
void Serial_Init(void);
void Serial_LateInit(void);
void Serial_Interrupt(void *arg);
char Serial_Getc();
void Serial_Putc(char ch);
void Serial_Puts(const char *str);