uart rx
This commit is contained in:
parent
a87b119b53
commit
fd2333e81c
@ -30,9 +30,10 @@
|
||||
#include <machine/timer.h>
|
||||
#include <machine/pci.h>
|
||||
|
||||
extern void MachineBoot_AddMem();
|
||||
extern void Loader_LoadInit();
|
||||
extern void PAlloc_LateInit();
|
||||
extern void MachineBoot_AddMem(void);
|
||||
extern void Loader_LoadInit(void);
|
||||
extern void PAlloc_LateInit(void);
|
||||
extern void Console_LateInit(void);
|
||||
|
||||
/**
|
||||
* Machine_SyscallInit --
|
||||
@ -71,7 +72,11 @@ Machine_EarlyInit()
|
||||
static void
|
||||
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
|
||||
*/
|
||||
IRQ_Init();
|
||||
Console_LateInit();
|
||||
|
||||
/*
|
||||
* Initialize Time Keeping
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <machine/cpuop.h>
|
||||
#include <machine/timer.h>
|
||||
|
||||
#define KTIMER_HZ (1)
|
||||
#define KTIMER_HZ (100)
|
||||
#define KTIMER_IRQ (30)
|
||||
// hardcode to 2024/03/14 12:34:56 AM EST
|
||||
#define KTIMER_EPOCH (1710390896ull)
|
||||
@ -36,7 +36,7 @@ PTimer_Tick(UNUSED void * arg)
|
||||
gic_send_eoi(KTIMER_IRQ);
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ IRQ_Init()
|
||||
LIST_INIT(&handlers[i]);
|
||||
}
|
||||
|
||||
enable_interrupts();
|
||||
kprintf("Initialized IRQ!\n");
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include <sys/kassert.h>
|
||||
|
||||
#include <machine/bootinfo.h>
|
||||
#include <sys/irq.h>
|
||||
#include "../console.h"
|
||||
#include <machine/gic.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <sys/fdt_helper.h>
|
||||
|
||||
@ -11,6 +14,7 @@
|
||||
#define UART_DR_OFFSET (0x000)
|
||||
#define UART_FR_OFFSET (0x018)
|
||||
#define UART_FR_BUSY (1 << 3)
|
||||
#define UART_FR_RXFE (1 << 4)
|
||||
#define UART_IBRD_OFFSET (0x024)
|
||||
#define UART_FBRD_OFFSET (0x028)
|
||||
#define UART_LCR_OFFSET (0x02c)
|
||||
@ -19,9 +23,16 @@
|
||||
#define UART_CR_OFFSET (0x030)
|
||||
#define UART_CR_UARTEN (1)
|
||||
#define UART_CR_TXEN (1 << 8)
|
||||
#define UART_CR_RXEN (1 << 9)
|
||||
#define UART_IMSC_OFFSET (0x038)
|
||||
#define UART_IMSC_RXIM (1 << 4)
|
||||
#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 {
|
||||
uintptr_t base;
|
||||
uint64_t clock;
|
||||
@ -40,6 +51,8 @@ static struct uart g_uart0 = {
|
||||
.initialized = 0
|
||||
};
|
||||
|
||||
static struct IRQHandler uartRx;
|
||||
|
||||
static void
|
||||
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;
|
||||
// parity disabled, FIFO disabled, stick parity disabled
|
||||
|
||||
// Mask all interrupts by setting corresponding bits to 1
|
||||
uart_writereg(dev, UART_IMSC_OFFSET, 0x7ff);
|
||||
// enable only RX interrupt
|
||||
uart_writereg(dev, UART_IMSC_OFFSET, UART_IMSC_RXIM);
|
||||
|
||||
// Disable DMA by setting all bits to 0
|
||||
uart_writereg(dev, UART_DMACR_OFFSET, 0x0);
|
||||
|
||||
// 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;
|
||||
}
|
||||
@ -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
|
||||
Serial_Send(const char *data, size_t size)
|
||||
{
|
||||
@ -159,3 +213,10 @@ Serial_Init(void)
|
||||
uart_init(&g_uart0);
|
||||
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
|
||||
Serial_Init(void);
|
||||
|
||||
void
|
||||
Serial_LateInit(void);
|
||||
|
||||
void
|
||||
Serial_Send(const char *data, size_t size);
|
||||
|
@ -50,9 +50,7 @@ Console_Init()
|
||||
void
|
||||
Console_LateInit()
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
Serial_LateInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
char
|
||||
|
@ -28,6 +28,7 @@ typedef struct Console {
|
||||
} Console;
|
||||
|
||||
void Console_Init();
|
||||
void Console_LateInit();
|
||||
char Console_Getc();
|
||||
void Console_Gets(char *str, size_t n);
|
||||
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__)
|
||||
// Normal Logging
|
||||
#define Log(_module, _format, ...) \
|
||||
if (SYSCTL_GETINT(log_##_module) >= 1 || 1) { \
|
||||
if (SYSCTL_GETINT(log_##_module) >= 1) { \
|
||||
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
||||
}
|
||||
// Debug Logging
|
||||
#define DLOG(_module, _format, ...) \
|
||||
if (SYSCTL_GETINT(log_##_module) >= 5 || 1) { \
|
||||
if (SYSCTL_GETINT(log_##_module) >= 5) { \
|
||||
kprintf(#_module ": " _format, ##__VA_ARGS__); \
|
||||
}
|
||||
// Verbose Logging
|
||||
|
@ -25,7 +25,7 @@
|
||||
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(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_o2fs, SYSCTL_FLAG_RW, "O2FS log level", 0) \
|
||||
SYSCTL_INT(log_syscall, SYSCTL_FLAG_RW, "Syscall log level", 0) \
|
||||
|
Loading…
Reference in New Issue
Block a user