#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(); } } }