smol-gilbraltar/kernel/kernel.c

126 lines
3.9 KiB
C

#include <crt.h>
#include <dtb.h>
#include <log.h>
#include <mem.h>
#include <memory.h>
#include <power.h>
#include <serial.h>
#include <stdlib.h>
#include <string.h>
#include <synchronize.h>
#include <sysconfig.h>
#include <tag.h>
extern int main();
extern char __bss_start;
extern char _etext[];
extern char _end[];
#define PROPTAG_GET_COMMAND_LINE 0x00050001
struct __attribute__((packed)) command_line {
uint32_t id;
uint32_t value_len;
uint32_t param_len;
uint8_t str[2048];
};
static size_t split(char *src, char *dst[], size_t len) {
int i = 0;
char *rem = src;
while (rem != NULL && *rem != '\0' && i < len) {
char *e = strstr(rem, " ");
dst[i++] = rem;
if (e != NULL) {
*e = '\0';
while (*(++e) == ' ')
;
}
rem = e;
}
return (i);
}
void gilbraltar_dump(void) {
uintptr_t heap_start;
uintptr_t heap_end;
gilbraltar_get_heap(&heap_start, &heap_end);
uintptr_t kernel_start = MEM_KERNEL_START;
uintptr_t kernel_end = (uintptr_t)_etext;
uintptr_t kernel_top = (uintptr_t)_end;
uintptr_t kernel_stack_start = MEM_KERNEL_STACK - KERNEL_STACK_SIZE;
uintptr_t kernel_stack_end = MEM_KERNEL_STACK;
uintptr_t exn_stack_start = MEM_EXCEPTION_STACK - EXCEPTION_STACK_SIZE;
uintptr_t exn_stack_end = MEM_EXCEPTION_STACK;
uintptr_t irq_stack_start = MEM_IRQ_STACK - EXCEPTION_STACK_SIZE;
uintptr_t irq_stack_end = MEM_IRQ_STACK;
uintptr_t fiq_stack_start = MEM_FIQ_STACK - EXCEPTION_STACK_SIZE;
uintptr_t fiq_stack_end = MEM_FIQ_STACK;
uintptr_t page_table_start = MEM_PAGE_TABLE1;
uintptr_t page_table_end = MEM_PAGE_TABLE1_END;
uintptr_t coherent_region_start = MEM_COHERENT_REGION;
uintptr_t coherent_region_end = MEM_COHERENT_REGION + 4 * MEGABYTE;
gilbraltar_log(INFO, " _____ _ _ _ _ _ \r\n");
gilbraltar_log(INFO, "| __|_| | |_ ___ ___| | |_ ___ ___ \r\n");
gilbraltar_log(INFO, "| | | | | . | _| .'| | _| .'| _|\r\n");
gilbraltar_log(INFO, "|_____|_|_|___|_| |__,|_|_| |__,|_| \r\n");
gilbraltar_log(INFO, " BL31 @ 0x%08x - 0x%08x\r\n", 0x0, 0x8000);
gilbraltar_log(INFO, " EL3 stack @ 0x%08x\r\n", 0x6f000);
gilbraltar_log(INFO, " kernel @ 0x%08lx - 0x%08lx | 0x%08lx\r\n",
kernel_start, kernel_end, kernel_top);
gilbraltar_log(INFO, " stack @ 0x%08lx - 0x%08lx\r\n",
kernel_stack_start, kernel_stack_end);
gilbraltar_log(INFO, "exception stack @ 0x%08lx - 0x%08lx\r\n",
exn_stack_start, exn_stack_end);
gilbraltar_log(INFO, " irq stack @ 0x%08lx - 0x%08lx\r\n",
irq_stack_start, irq_stack_end);
gilbraltar_log(INFO, " fiq stack @ 0x%08lx - 0x%08lx\r\n",
fiq_stack_start, fiq_stack_end);
gilbraltar_log(INFO, " pages table @ 0x%08lx - 0x%08lx\r\n",
page_table_start, page_table_end);
gilbraltar_log(INFO, "coherent region @ 0x%08lx - 0x%08lx\r\n",
coherent_region_start, coherent_region_end);
gilbraltar_log(INFO, " heap @ 0x%08lx - 0x%08lx\r\n", heap_start,
heap_end);
gilbraltar_log(INFO, "\r\n");
}
void gilbraltar_sysinit(void) {
enable_fiqs();
enable_irqs();
memset(&__bss_start, 0, (uintptr_t)_end - (uintptr_t)__bss_start);
crt_init_ssp();
gilbraltar_serial_init();
gilbraltar_memory_init();
struct command_line p;
char *cmdline[64] = {NULL};
size_t ac = 1;
cmdline[0] = "gilbraltar";
if (!gilbraltar_get_tag(PROPTAG_GET_COMMAND_LINE, &p, sizeof(p), 2048)) {
gilbraltar_log(ERROR, "Impossible to retrieve cmdline.txt.\r\n");
ac = 1;
} else if (p.param_len >= sizeof(p.str)) {
gilbraltar_log(ERROR, "cmdline.txt too long.\r\n");
ac = 1;
} else {
p.str[p.param_len] = '\0';
ac = split((char *)p.str, cmdline + 1, 62);
}
gilbraltar_dtb_init();
gilbraltar_dump();
int ret = main(ac + 1, cmdline);
gilbraltar_log(DEBUG, "End of program: %3d.", ret);
if (ret == 0)
poweroff();
}