main.c

Commit: 2a3b0c04 Author: jokerz Raw Copy
1
/* ============================================================================
2
 * Pactor64 — Raspberry Pi 5 Kernel Main (AArch64)
3
 * Minimal kernel: UART console + interactive shell
4
 * ============================================================================ */
5
6
/* PL011 UART registers */
7
#define UART0_BASE  0xFE201000UL
8
#define UART_DR     (*(volatile unsigned int *)(UART0_BASE + 0x00))
9
#define UART_FR     (*(volatile unsigned int *)(UART0_BASE + 0x18))
10
11
/* PL011 FR bits */
12
#define FR_TXFF     (1 << 5)
13
#define FR_RXFE     (1 << 4)
14
15
/* Shell buffer */
16
#define CMD_BUF_SIZE 128
17
18
/* Forward declarations */
19
extern void uart_putc(int c);
20
extern void uart_puts(const char *s);
21
extern int  uart_getc(void);
22
extern int  uart_poll(void);
23
24
/* Simple strlen */
25
static int kstrlen(const char *s) {
26
    int len = 0;
27
    while (s[len]) len++;
28
    return len;
29
}
30
31
/* Simple strcmp */
32
static int kstrcmp(const char *a, const char *b) {
33
    while (*a && *a == *b) { a++; b++; }
34
    return (unsigned char)*a - (unsigned char)*b;
35
}
36
37
/* Simple kstrncmp */
38
static int kstrncmp(const char *a, const char *b, int n) {
39
    while (n && *a && *a == *b) { a++; b++; n--; }
40
    return n ? (unsigned char)*a - (unsigned char)*b : 0;
41
}
42
43
/* Simple kprintf (supports %d, %s, %x, %c) */
44
static void kprintf(const char *fmt, ...) {
45
    __builtin_va_list ap;
46
    __builtin_va_start(ap, fmt);
47
48
    for (int i = 0; fmt[i]; i++) {
49
        if (fmt[i] == '%' && fmt[i + 1]) {
50
            i++;
51
            switch (fmt[i]) {
52
                case 'd': {
53
                    long val = __builtin_va_arg(ap, long);
54
                    if (val < 0) { uart_putc('-'); val = -val; }
55
                    char buf[21]; int j = 0;
56
                    if (val == 0) { uart_putc('0'); break; }
57
                    while (val > 0) { buf[j++] = '0' + (val % 10); val /= 10; }
58
                    while (j > 0) uart_putc(buf[--j]);
59
                    break;
60
                }
61
                case 'x': {
62
                    unsigned long val = __builtin_va_arg(ap, unsigned long);
63
                    char buf[17]; int j = 0;
64
                    if (val == 0) { uart_putc('0'); break; }
65
                    while (val > 0) {
66
                        int d = val & 0xF;
67
                        buf[j++] = d < 10 ? '0' + d : 'a' + d - 10;
68
                        val >>= 4;
69
                    }
70
                    while (j > 0) uart_putc(buf[--j]);
71
                    break;
72
                }
73
                case 's': {
74
                    const char *s = __builtin_va_arg(ap, const char *);
75
                    if (!s) s = "(null)";
76
                    uart_puts(s);
77
                    break;
78
                }
79
                case 'c': {
80
                    int c = __builtin_va_arg(ap, int);
81
                    uart_putc(c);
82
                    break;
83
                }
84
                case '%':
85
                    uart_putc('%');
86
                    break;
87
                default:
88
                    uart_putc('%');
89
                    uart_putc(fmt[i]);
90
                    break;
91
            }
92
        } else {
93
            uart_putc(fmt[i]);
94
        }
95
    }
96
    __builtin_va_end(ap);
97
}
98
99
/* Shell commands */
100
static void cmd_help(void) {
101
    uart_puts("  Available commands:\r\n");
102
    uart_puts("    help    - Show this help\r\n");
103
    uart_puts("    sysinfo - System information\r\n");
104
    uart_puts("    ticks   - Timer tick count\r\n");
105
    uart_puts("    reboot  - Reboot the system\r\n");
106
    uart_puts("    halt    - Halt the system\r\n");
107
}
108
109
static void cmd_sysinfo(void) {
110
    uart_puts("  ================================\r\n");
111
    uart_puts("  Pactor64 System Information\r\n");
112
    uart_puts("  ================================\r\n");
113
    uart_puts("  Architecture:  AArch64 (ARMv8.2-A)\r\n");
114
    uart_puts("  CPU:           Cortex-A76\r\n");
115
    uart_puts("  Board:         Raspberry Pi 5\r\n");
116
    uart_puts("  SoC:           BCM2712\r\n");
117
    uart_puts("  Console:       PL011 UART @ 115200 baud\r\n");
118
    uart_puts("  ================================\r\n");
119
}
120
121
/* Timer tick counter (updated by IRQ handler) */
122
static volatile unsigned long timer_ticks = 0;
123
124
static void cmd_ticks(void) {
125
    kprintf("  Timer ticks: %d\r\n", timer_ticks);
126
}
127
128
static void cmd_uptime(void) {
129
    kprintf("  Uptime: %d seconds\r\n", timer_ticks / 100);
130
}
131
132
static void execute_command(const char *cmd) {
133
    while (*cmd == ' ') cmd++;
134
    if (*cmd == '\0') return;
135
136
    if (kstrcmp(cmd, "help") == 0) {
137
        cmd_help();
138
    } else if (kstrcmp(cmd, "sysinfo") == 0) {
139
        cmd_sysinfo();
140
    } else if (kstrcmp(cmd, "ticks") == 0) {
141
        cmd_ticks();
142
    } else if (kstrcmp(cmd, "uptime") == 0) {
143
        cmd_uptime();
144
    } else if (kstrcmp(cmd, "halt") == 0) {
145
        uart_puts("  System halted.\r\n");
146
        for (;;) __asm__ volatile("wfe");
147
    } else if (kstrcmp(cmd, "reboot") == 0) {
148
        uart_puts("  Rebooting...\r\n");
149
        /* PM_RSTC register: write PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET */
150
        volatile unsigned int *PM_RSTC = (volatile unsigned int *)0xFE10001C;
151
        volatile unsigned int *PM_WDOG = (volatile unsigned int *)0xFE100024;
152
        *PM_WDOG = 0x5A000001;        // 1 second timeout
153
        *PM_RSTC = 0x5A000020;        // Full reset
154
        for (;;) __asm__ volatile("wfe");
155
    } else {
156
        kprintf("  Unknown: '%s'. Type 'help' for options.\r\n", cmd);
157
    }
158
}
159
160
/* Shell main loop */
161
static void shell_run(void) {
162
    char buf[CMD_BUF_SIZE];
163
    int pos = 0;
164
165
    uart_puts("pactor64> ");
166
167
    for (;;) {
168
        int c = uart_getc();
169
        if (c < 0) {
170
            __asm__ volatile("wfi");   // Wait for interrupt
171
            continue;
172
        }
173
174
        char ch = (char)c;
175
176
        if (ch == '\r' || ch == '\n') {
177
            uart_puts("\r\n");
178
            buf[pos] = '\0';
179
            execute_command(buf);
180
            pos = 0;
181
            uart_puts("pactor64> ");
182
        } else if (ch == 0x7F || ch == '\b') {
183
            // Backspace
184
            if (pos > 0) {
185
                pos--;
186
                uart_puts("\b \b");
187
            }
188
        } else if (pos < CMD_BUF_SIZE - 1) {
189
            buf[pos++] = ch;
190
            uart_putc(ch);  // Echo
191
        }
192
    }
193
}
194
195
/* Kernel main — called from entry.S */
196
void kernel_main(void) {
197
    uart_puts("  [OK] UART initialized\r\n");
198
    uart_puts("  [OK] Pactor64 kernel running on AArch64\r\n");
199
    uart_puts("  [OK] Cortex-A76 @ Raspberry Pi 5\r\n");
200
    uart_puts("\r\n");
201
    uart_puts("  Type 'help' for available commands.\r\n");
202
    uart_puts("\r\n");
203
204
    shell_run();
205
206
    /* Should never reach here */
207
    for (;;) __asm__ volatile("wfe");
208
}
209