64 lines
1.8 KiB
C
64 lines
1.8 KiB
C
#include "uart.h"
|
|
#include "stdio.h"
|
|
#include "abi/syscalls.h"
|
|
#include "abi/ipc.h"
|
|
|
|
#define UART_SERVICE_ENDPOINT 2
|
|
|
|
extern void _start(void) {
|
|
uart_init(UART_COM1_PORT, 115200);
|
|
puts("[UART-DRIVER] 16550 UART Server started in Ring 3. Listening for IPC requests...");
|
|
|
|
uint64_t last_client = 0;
|
|
uint64_t reply_val0 = 0;
|
|
uint64_t reply_val1 = 0;
|
|
|
|
while (1) {
|
|
uint64_t sender_tid = 0;
|
|
uint64_t opcode = 0;
|
|
uint64_t arg0 = 0;
|
|
uint64_t arg1 = 0;
|
|
|
|
// Block and wait for next client IPC request, replying to last client if any
|
|
sysret_t ret = sys_ipc_reply_recv_raw(
|
|
UART_SERVICE_ENDPOINT,
|
|
last_client,
|
|
reply_val0,
|
|
reply_val1,
|
|
&sender_tid,
|
|
&opcode,
|
|
&arg0,
|
|
&arg1
|
|
);
|
|
|
|
if (ret == 0 && sender_tid != 0) {
|
|
last_client = sender_tid;
|
|
|
|
if (opcode == IPC_OP_WRITE) {
|
|
// Write received characters to UART hardware
|
|
char c0 = (char)(arg0 & 0xFF);
|
|
char c1 = (char)((arg0 >> 8) & 0xFF);
|
|
char c2 = (char)((arg0 >> 16) & 0xFF);
|
|
char c3 = (char)((arg0 >> 24) & 0xFF);
|
|
|
|
if (c0) uart_putc(UART_COM1_PORT, c0);
|
|
if (c1) uart_putc(UART_COM1_PORT, c1);
|
|
if (c2) uart_putc(UART_COM1_PORT, c2);
|
|
if (c3) uart_putc(UART_COM1_PORT, c3);
|
|
|
|
reply_val0 = 0; // Success
|
|
reply_val1 = 4; // Bytes written
|
|
} else if (opcode == IPC_OP_PING) {
|
|
reply_val0 = IPC_OP_PONG;
|
|
reply_val1 = arg0 + 1;
|
|
} else {
|
|
reply_val0 = (uint64_t)-1;
|
|
reply_val1 = 0;
|
|
}
|
|
} else {
|
|
last_client = 0;
|
|
sys_yield();
|
|
}
|
|
}
|
|
}
|