/* ============================================================================ * Pactor64 — Raspberry Pi 5 Kernel Main (AArch64) * Minimal kernel: UART console + interactive shell * ============================================================================ */ /* PL011 UART registers */ #define UART0_BASE 0xFE201000UL #define UART_DR (*(volatile unsigned int *)(UART0_BASE + 0x00)) #define UART_FR (*(volatile unsigned int *)(UART0_BASE + 0x18)) /* PL011 FR bits */ #define FR_TXFF (1 << 5) #define FR_RXFE (1 << 4) /* Shell buffer */ #define CMD_BUF_SIZE 128 /* Forward declarations */ extern void uart_putc(int c); extern void uart_puts(const char *s); extern int uart_getc(void); extern int uart_poll(void); /* Simple strlen */ static int kstrlen(const char *s) { int len = 0; while (s[len]) len++; return len; } /* Simple strcmp */ static int kstrcmp(const char *a, const char *b) { while (*a && *a == *b) { a++; b++; } return (unsigned char)*a - (unsigned char)*b; } /* Simple kstrncmp */ static int kstrncmp(const char *a, const char *b, int n) { while (n && *a && *a == *b) { a++; b++; n--; } return n ? (unsigned char)*a - (unsigned char)*b : 0; } /* Simple kprintf (supports %d, %s, %x, %c) */ static void kprintf(const char *fmt, ...) { __builtin_va_list ap; __builtin_va_start(ap, fmt); for (int i = 0; fmt[i]; i++) { if (fmt[i] == '%' && fmt[i + 1]) { i++; switch (fmt[i]) { case 'd': { long val = __builtin_va_arg(ap, long); if (val < 0) { uart_putc('-'); val = -val; } char buf[21]; int j = 0; if (val == 0) { uart_putc('0'); break; } while (val > 0) { buf[j++] = '0' + (val % 10); val /= 10; } while (j > 0) uart_putc(buf[--j]); break; } case 'x': { unsigned long val = __builtin_va_arg(ap, unsigned long); char buf[17]; int j = 0; if (val == 0) { uart_putc('0'); break; } while (val > 0) { int d = val & 0xF; buf[j++] = d < 10 ? '0' + d : 'a' + d - 10; val >>= 4; } while (j > 0) uart_putc(buf[--j]); break; } case 's': { const char *s = __builtin_va_arg(ap, const char *); if (!s) s = "(null)"; uart_puts(s); break; } case 'c': { int c = __builtin_va_arg(ap, int); uart_putc(c); break; } case '%': uart_putc('%'); break; default: uart_putc('%'); uart_putc(fmt[i]); break; } } else { uart_putc(fmt[i]); } } __builtin_va_end(ap); } /* Shell commands */ static void cmd_help(void) { uart_puts(" Available commands:\r\n"); uart_puts(" help - Show this help\r\n"); uart_puts(" sysinfo - System information\r\n"); uart_puts(" ticks - Timer tick count\r\n"); uart_puts(" reboot - Reboot the system\r\n"); uart_puts(" halt - Halt the system\r\n"); } static void cmd_sysinfo(void) { uart_puts(" ================================\r\n"); uart_puts(" Pactor64 System Information\r\n"); uart_puts(" ================================\r\n"); uart_puts(" Architecture: AArch64 (ARMv8.2-A)\r\n"); uart_puts(" CPU: Cortex-A76\r\n"); uart_puts(" Board: Raspberry Pi 5\r\n"); uart_puts(" SoC: BCM2712\r\n"); uart_puts(" Console: PL011 UART @ 115200 baud\r\n"); uart_puts(" ================================\r\n"); } /* Timer tick counter (updated by IRQ handler) */ static volatile unsigned long timer_ticks = 0; static void cmd_ticks(void) { kprintf(" Timer ticks: %d\r\n", timer_ticks); } static void cmd_uptime(void) { kprintf(" Uptime: %d seconds\r\n", timer_ticks / 100); } static void execute_command(const char *cmd) { while (*cmd == ' ') cmd++; if (*cmd == '\0') return; if (kstrcmp(cmd, "help") == 0) { cmd_help(); } else if (kstrcmp(cmd, "sysinfo") == 0) { cmd_sysinfo(); } else if (kstrcmp(cmd, "ticks") == 0) { cmd_ticks(); } else if (kstrcmp(cmd, "uptime") == 0) { cmd_uptime(); } else if (kstrcmp(cmd, "halt") == 0) { uart_puts(" System halted.\r\n"); for (;;) __asm__ volatile("wfe"); } else if (kstrcmp(cmd, "reboot") == 0) { uart_puts(" Rebooting...\r\n"); /* PM_RSTC register: write PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET */ volatile unsigned int *PM_RSTC = (volatile unsigned int *)0xFE10001C; volatile unsigned int *PM_WDOG = (volatile unsigned int *)0xFE100024; *PM_WDOG = 0x5A000001; // 1 second timeout *PM_RSTC = 0x5A000020; // Full reset for (;;) __asm__ volatile("wfe"); } else { kprintf(" Unknown: '%s'. Type 'help' for options.\r\n", cmd); } } /* Shell main loop */ static void shell_run(void) { char buf[CMD_BUF_SIZE]; int pos = 0; uart_puts("pactor64> "); for (;;) { int c = uart_getc(); if (c < 0) { __asm__ volatile("wfi"); // Wait for interrupt continue; } char ch = (char)c; if (ch == '\r' || ch == '\n') { uart_puts("\r\n"); buf[pos] = '\0'; execute_command(buf); pos = 0; uart_puts("pactor64> "); } else if (ch == 0x7F || ch == '\b') { // Backspace if (pos > 0) { pos--; uart_puts("\b \b"); } } else if (pos < CMD_BUF_SIZE - 1) { buf[pos++] = ch; uart_putc(ch); // Echo } } } /* Kernel main — called from entry.S */ void kernel_main(void) { uart_puts(" [OK] UART initialized\r\n"); uart_puts(" [OK] Pactor64 kernel running on AArch64\r\n"); uart_puts(" [OK] Cortex-A76 @ Raspberry Pi 5\r\n"); uart_puts("\r\n"); uart_puts(" Type 'help' for available commands.\r\n"); uart_puts("\r\n"); shell_run(); /* Should never reach here */ for (;;) __asm__ volatile("wfe"); }