Serial support
This commit is contained in:
parent
65fb17870e
commit
34aad175e9
@ -20,6 +20,7 @@ src_amd64 = [
|
|||||||
"amd64/ioapic.c",
|
"amd64/ioapic.c",
|
||||||
"amd64/irq.c",
|
"amd64/irq.c",
|
||||||
"dev/x86/debugcons.c",
|
"dev/x86/debugcons.c",
|
||||||
|
"dev/x86/sercons.c",
|
||||||
"dev/x86/vgacons.c",
|
"dev/x86/vgacons.c",
|
||||||
"dev/x86/ide.c",
|
"dev/x86/ide.c",
|
||||||
]
|
]
|
||||||
|
@ -3,21 +3,42 @@
|
|||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "x86/vgacons.h"
|
#include "x86/vgacons.h"
|
||||||
|
#include "x86/sercons.h"
|
||||||
#include "x86/debugcons.h"
|
#include "x86/debugcons.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize console devices for debugging purposes. At this point interrupts
|
||||||
|
* and device state is not initialized.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Console_Init()
|
Console_Init()
|
||||||
{
|
{
|
||||||
VGA_Init();
|
VGA_Init();
|
||||||
|
Serial_Init();
|
||||||
DebugConsole_Init();
|
DebugConsole_Init();
|
||||||
|
|
||||||
Console_Puts("Castor Operating System\n");
|
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
|
void
|
||||||
Console_Putc(char ch)
|
Console_Putc(char ch)
|
||||||
{
|
{
|
||||||
VGA_Putc(ch);
|
VGA_Putc(ch);
|
||||||
|
Serial_Putc(ch);
|
||||||
DebugConsole_Putc(ch);
|
DebugConsole_Putc(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +46,7 @@ void
|
|||||||
Console_Puts(const char *str)
|
Console_Puts(const char *str)
|
||||||
{
|
{
|
||||||
VGA_Puts(str);
|
VGA_Puts(str);
|
||||||
|
Serial_Puts(str);
|
||||||
DebugConsole_Puts(str);
|
DebugConsole_Puts(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user