uart rx
This commit is contained in:
parent
a87b119b53
commit
fd2333e81c
@ -30,9 +30,10 @@
|
|||||||
#include <machine/timer.h>
|
#include <machine/timer.h>
|
||||||
#include <machine/pci.h>
|
#include <machine/pci.h>
|
||||||
|
|
||||||
extern void MachineBoot_AddMem();
|
extern void MachineBoot_AddMem(void);
|
||||||
extern void Loader_LoadInit();
|
extern void Loader_LoadInit(void);
|
||||||
extern void PAlloc_LateInit();
|
extern void PAlloc_LateInit(void);
|
||||||
|
extern void Console_LateInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Machine_SyscallInit --
|
* Machine_SyscallInit --
|
||||||
@ -71,7 +72,11 @@ Machine_EarlyInit()
|
|||||||
static void
|
static void
|
||||||
Machine_IdleThread(UNUSED void *test)
|
Machine_IdleThread(UNUSED void *test)
|
||||||
{
|
{
|
||||||
while (1) { kprintf("Idle Thread!\n"); enable_interrupts(); hlt(); }
|
while (1) {
|
||||||
|
// kprintf("Idle Thread!\n");
|
||||||
|
enable_interrupts();
|
||||||
|
hlt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,6 +107,7 @@ void Machine_Init()
|
|||||||
* Initialize Interrupts
|
* Initialize Interrupts
|
||||||
*/
|
*/
|
||||||
IRQ_Init();
|
IRQ_Init();
|
||||||
|
Console_LateInit();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize Time Keeping
|
* Initialize Time Keeping
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#include <machine/cpuop.h>
|
#include <machine/cpuop.h>
|
||||||
#include <machine/timer.h>
|
#include <machine/timer.h>
|
||||||
|
|
||||||
#define KTIMER_HZ (1)
|
#define KTIMER_HZ (100)
|
||||||
#define KTIMER_IRQ (30)
|
#define KTIMER_IRQ (30)
|
||||||
// hardcode to 2024/03/14 12:34:56 AM EST
|
// hardcode to 2024/03/14 12:34:56 AM EST
|
||||||
#define KTIMER_EPOCH (1710390896ull)
|
#define KTIMER_EPOCH (1710390896ull)
|
||||||
@ -36,7 +36,7 @@ PTimer_Tick(UNUSED void * arg)
|
|||||||
gic_send_eoi(KTIMER_IRQ);
|
gic_send_eoi(KTIMER_IRQ);
|
||||||
|
|
||||||
KTimer_Process();
|
KTimer_Process();
|
||||||
kprintf("Hardware timer tick, epoch = %lu, tsc = %lu, CVAL = %lu.\n", KTime_GetEpoch(), Time_GetTSC(), SYSREG_GET(CNTP_CVAL_EL0));
|
//kprintf("Hardware timer tick, epoch = %lu, tsc = %lu, CVAL = %lu.\n", KTime_GetEpoch(), Time_GetTSC(), SYSREG_GET(CNTP_CVAL_EL0));
|
||||||
|
|
||||||
Sched_Scheduler();
|
Sched_Scheduler();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@ IRQ_Init()
|
|||||||
LIST_INIT(&handlers[i]);
|
LIST_INIT(&handlers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_interrupts();
|
|
||||||
kprintf("Initialized IRQ!\n");
|
kprintf("Initialized IRQ!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include <sys/kassert.h>
|
#include <sys/kassert.h>
|
||||||
|
|
||||||
#include <machine/bootinfo.h>
|
#include <machine/bootinfo.h>
|
||||||
|
#include <sys/irq.h>
|
||||||
|
#include "../console.h"
|
||||||
|
#include <machine/gic.h>
|
||||||
#include <machine/pmap.h>
|
#include <machine/pmap.h>
|
||||||
#include <sys/fdt_helper.h>
|
#include <sys/fdt_helper.h>
|
||||||
|
|
||||||
@ -11,6 +14,7 @@
|
|||||||
#define UART_DR_OFFSET (0x000)
|
#define UART_DR_OFFSET (0x000)
|
||||||
#define UART_FR_OFFSET (0x018)
|
#define UART_FR_OFFSET (0x018)
|
||||||
#define UART_FR_BUSY (1 << 3)
|
#define UART_FR_BUSY (1 << 3)
|
||||||
|
#define UART_FR_RXFE (1 << 4)
|
||||||
#define UART_IBRD_OFFSET (0x024)
|
#define UART_IBRD_OFFSET (0x024)
|
||||||
#define UART_FBRD_OFFSET (0x028)
|
#define UART_FBRD_OFFSET (0x028)
|
||||||
#define UART_LCR_OFFSET (0x02c)
|
#define UART_LCR_OFFSET (0x02c)
|
||||||
@ -19,9 +23,16 @@
|
|||||||
#define UART_CR_OFFSET (0x030)
|
#define UART_CR_OFFSET (0x030)
|
||||||
#define UART_CR_UARTEN (1)
|
#define UART_CR_UARTEN (1)
|
||||||
#define UART_CR_TXEN (1 << 8)
|
#define UART_CR_TXEN (1 << 8)
|
||||||
|
#define UART_CR_RXEN (1 << 9)
|
||||||
#define UART_IMSC_OFFSET (0x038)
|
#define UART_IMSC_OFFSET (0x038)
|
||||||
|
#define UART_IMSC_RXIM (1 << 4)
|
||||||
#define UART_DMACR_OFFSET (0x048)
|
#define UART_DMACR_OFFSET (0x048)
|
||||||
|
|
||||||
|
#define UART_ISR_OFFSET (0x3C)
|
||||||
|
#define UART_ICR_OFFSET (0x44)
|
||||||
|
#define UART_ICR_RXIC (1 << 4)
|
||||||
|
#define UART_INTR_NUM (37)
|
||||||
|
|
||||||
struct uart {
|
struct uart {
|
||||||
uintptr_t base;
|
uintptr_t base;
|
||||||
uint64_t clock;
|
uint64_t clock;
|
||||||
@ -40,6 +51,8 @@ static struct uart g_uart0 = {
|
|||||||
.initialized = 0
|
.initialized = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct IRQHandler uartRx;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
uart_writereg(const struct uart *dev, uintptr_t offset, uint32_t val)
|
uart_writereg(const struct uart *dev, uintptr_t offset, uint32_t val)
|
||||||
{
|
{
|
||||||
@ -117,14 +130,14 @@ uart_init(struct uart *dev)
|
|||||||
lcr |= UART_LCR_STP2;
|
lcr |= UART_LCR_STP2;
|
||||||
// parity disabled, FIFO disabled, stick parity disabled
|
// parity disabled, FIFO disabled, stick parity disabled
|
||||||
|
|
||||||
// Mask all interrupts by setting corresponding bits to 1
|
// enable only RX interrupt
|
||||||
uart_writereg(dev, UART_IMSC_OFFSET, 0x7ff);
|
uart_writereg(dev, UART_IMSC_OFFSET, UART_IMSC_RXIM);
|
||||||
|
|
||||||
// Disable DMA by setting all bits to 0
|
// Disable DMA by setting all bits to 0
|
||||||
uart_writereg(dev, UART_DMACR_OFFSET, 0x0);
|
uart_writereg(dev, UART_DMACR_OFFSET, 0x0);
|
||||||
|
|
||||||
// enable tx & uart
|
// enable tx & uart
|
||||||
uart_writereg(dev, UART_CR_OFFSET, UART_CR_TXEN | UART_CR_UARTEN);
|
uart_writereg(dev, UART_CR_OFFSET, UART_CR_TXEN | UART_CR_UARTEN | UART_CR_RXEN);
|
||||||
|
|
||||||
dev->initialized = 1;
|
dev->initialized = 1;
|
||||||
}
|
}
|
||||||
@ -145,6 +158,47 @@ uart_send(const struct uart *dev, const char *data, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char
|
||||||
|
uart_char_sanitize(char ch)
|
||||||
|
{
|
||||||
|
if (ch == 13) {
|
||||||
|
return 0x0A;
|
||||||
|
} else {
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uart_rx_intr(void * arg)
|
||||||
|
{
|
||||||
|
const struct uart * dev = (const struct uart *)arg;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
const uint16_t flags = uart_readreg(dev, UART_FR_OFFSET);
|
||||||
|
|
||||||
|
if (flags & UART_FR_RXFE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const uint16_t data = uart_readreg(dev, UART_DR_OFFSET);
|
||||||
|
const char ch = data & 0xff;
|
||||||
|
// kprintf("UART KEY: %d\n", ch);
|
||||||
|
Console_EnqueueKey(uart_char_sanitize(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear RX interrupt flag
|
||||||
|
uart_writereg(dev, UART_ICR_OFFSET, UART_ICR_RXIC);
|
||||||
|
gic_send_eoi(UART_INTR_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
uart_rx_init(const struct uart *dev)
|
||||||
|
{
|
||||||
|
uartRx.arg = &g_uart0;
|
||||||
|
uartRx.irq = UART_INTR_NUM;
|
||||||
|
uartRx.cb = uart_rx_intr;
|
||||||
|
IRQ_Register(UART_INTR_NUM, &uartRx);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial_Send(const char *data, size_t size)
|
Serial_Send(const char *data, size_t size)
|
||||||
{
|
{
|
||||||
@ -159,3 +213,10 @@ Serial_Init(void)
|
|||||||
uart_init(&g_uart0);
|
uart_init(&g_uart0);
|
||||||
kprintf("Initialized PL011 UART, base = 0x%lx.\n", g_uart0.base);
|
kprintf("Initialized PL011 UART, base = 0x%lx.\n", g_uart0.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Serial_LateInit(void)
|
||||||
|
{
|
||||||
|
uart_rx_init(&g_uart0);
|
||||||
|
kprintf("Initialized PL011 RX mode.\n");
|
||||||
|
}
|
@ -5,5 +5,8 @@
|
|||||||
void
|
void
|
||||||
Serial_Init(void);
|
Serial_Init(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
Serial_LateInit(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial_Send(const char *data, size_t size);
|
Serial_Send(const char *data, size_t size);
|
||||||
|
@ -50,9 +50,7 @@ Console_Init()
|
|||||||
void
|
void
|
||||||
Console_LateInit()
|
Console_LateInit()
|
||||||
{
|
{
|
||||||
#if defined(__x86_64__)
|
|
||||||
Serial_LateInit();
|
Serial_LateInit();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char
|
char
|
||||||
|
@ -28,6 +28,7 @@ typedef struct Console {
|
|||||||
} Console;
|
} Console;
|
||||||
|
|
||||||
void Console_Init();
|
void Console_Init();
|
||||||
|
void Console_LateInit();
|
||||||
char Console_Getc();
|
char Console_Getc();
|
||||||
void Console_Gets(char *str, size_t n);
|
void Console_Gets(char *str, size_t n);
|
||||||
void Console_Putc(char ch);
|
void Console_Putc(char ch);
|
||||||
|
@ -42,12 +42,12 @@ NO_RETURN void Debug_Assert(const char *fmt, ...);
|
|||||||
#define Warning(_module, _format, ...) kprintf(#_module ": " _format, ##__VA_ARGS__)
|
#define Warning(_module, _format, ...) kprintf(#_module ": " _format, ##__VA_ARGS__)
|
||||||
// Normal Logging
|
// Normal Logging
|
||||||
#define Log(_module, _format, ...) \
|
#define Log(_module, _format, ...) \
|
||||||
if (SYSCTL_GETINT(log_##_module) >= 1 || 1) { \
|
if (SYSCTL_GETINT(log_##_module) >= 1) { \
|
||||||
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
||||||
}
|
}
|
||||||
// Debug Logging
|
// Debug Logging
|
||||||
#define DLOG(_module, _format, ...) \
|
#define DLOG(_module, _format, ...) \
|
||||||
if (SYSCTL_GETINT(log_##_module) >= 5 || 1) { \
|
if (SYSCTL_GETINT(log_##_module) >= 5) { \
|
||||||
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
||||||
}
|
}
|
||||||
// Verbose Logging
|
// Verbose Logging
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
SYSCTL_INT(kern_hz, SYSCTL_FLAG_RW, "Tick frequency", 100) \
|
SYSCTL_INT(kern_hz, SYSCTL_FLAG_RW, "Tick frequency", 100) \
|
||||||
SYSCTL_INT(time_tzadj, SYSCTL_FLAG_RW, "Time zone offset in seconds", 0) \
|
SYSCTL_INT(time_tzadj, SYSCTL_FLAG_RW, "Time zone offset in seconds", 0) \
|
||||||
SYSCTL_INT(log_e1000, SYSCTL_FLAG_RW, "E1000 log level", 10) \
|
SYSCTL_INT(log_e1000, SYSCTL_FLAG_RW, "E1000 log level", 10) \
|
||||||
SYSCTL_INT(log_ide, SYSCTL_FLAG_RW, "IDE log level", 0) \
|
SYSCTL_INT(log_ide, SYSCTL_FLAG_RW, "IDE log level", 1) \
|
||||||
SYSCTL_INT(log_loader, SYSCTL_FLAG_RW, "Loader log level", 0) \
|
SYSCTL_INT(log_loader, SYSCTL_FLAG_RW, "Loader log level", 0) \
|
||||||
SYSCTL_INT(log_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \
|
SYSCTL_INT(log_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \
|
||||||
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
|
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
|
||||||
|
Loading…
Reference in New Issue
Block a user