146 lines
3.6 KiB
C
146 lines
3.6 KiB
C
// Types
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <sys/types.h>
|
|
#include <kernel/bits/mpu.h>
|
|
// Internal helpers
|
|
#include <kernel/util/atomic.h>
|
|
#include <kernel/util/casio.h>
|
|
// Modules
|
|
#include <kernel/bits/context.h>
|
|
#include <kernel/process.h>
|
|
#include <kernel/syscall.h>
|
|
#include <kernel/scheduler.h>
|
|
#include <kernel/loader.h>
|
|
#include <kernel/driver.h>
|
|
// Devices
|
|
#include <kernel/devices/earlyterm.h>
|
|
// Libs
|
|
#include <lib/display.h>
|
|
#include <lib/string.h>
|
|
|
|
// Symbols defined by the linker
|
|
extern uint32_t bbss;
|
|
extern uint32_t sbss;
|
|
extern uint32_t bdata_ram;
|
|
extern uint32_t bdata_rom;
|
|
extern uint32_t sdata;
|
|
extern uint32_t brom;
|
|
extern uint32_t srom;
|
|
extern uint32_t bctors;
|
|
extern uint32_t ectors;
|
|
extern uint32_t bdtors;
|
|
extern uint32_t edtors;
|
|
|
|
// Internal bootstrap funtions
|
|
extern mpu_t mpu_get(void);
|
|
extern void bootstrap_filesystem_init(void);
|
|
|
|
//
|
|
// rom_explore() - explore all add-in ROM part.
|
|
// @note:
|
|
// For now, we can not use the MMU so we can
|
|
// not handle TLB miss. Casio load only the first 4ko
|
|
// of the add-in. To avoid TLB miss we explore all
|
|
// add-in binary to force Casio to generate all pages
|
|
// into the TLB.
|
|
//
|
|
static void rom_explore(volatile void *rom, int32_t size)
|
|
{
|
|
uint8_t unused;
|
|
|
|
(void)unused;
|
|
while (size >= 0)
|
|
{
|
|
unused = *(volatile uint8_t*)rom;
|
|
size = size - 1024;
|
|
rom = rom + 1024;
|
|
}
|
|
}
|
|
|
|
/* section_execute() - Used to execute contructors and destructors */
|
|
static void section_execute(void *bsection, void *esection)
|
|
{
|
|
while (bsection < esection)
|
|
{
|
|
((void (*)(void))*((void**)bsection))();
|
|
bsection = bsection + sizeof(void (*)(void));
|
|
}
|
|
}
|
|
|
|
/* start() - Kernel entry point */
|
|
__attribute__((section(".pretext")))
|
|
int start(void)
|
|
{
|
|
// Casio do not load all add-in page and we can not use the MMU.
|
|
// So we need to "force" update TLB before switching the VBR to
|
|
// avoid TLB miss exception that we can not handle for now.
|
|
rom_explore(&brom, (int32_t)&srom);
|
|
|
|
// Wipe .bss section and dump .data / Vhex sections
|
|
memset(&bbss, 0x00, (size_t)&sbss);
|
|
memcpy(&bdata_ram, &bdata_rom, (size_t)&sdata);
|
|
|
|
// Start early terminal device
|
|
// This device is used by the kernel to display
|
|
// some logs on screen
|
|
if (earlyterm_init() != 0)
|
|
return (-1);
|
|
earlyterm_clear();
|
|
earlyterm_write("Kernel initialisation...\n");
|
|
|
|
// Load all drivers on-the-fly
|
|
drivers_install(1);
|
|
|
|
// Execute constructor.
|
|
// FIXME: remove me ?
|
|
section_execute(&bctors, &ectors);
|
|
|
|
|
|
// Initialize all File Systems and Virtual File System
|
|
// TODO: rename into initramfs ?
|
|
bootstrap_filesystem_init();
|
|
|
|
|
|
//---
|
|
// Start first process !
|
|
//---
|
|
//TODO: move me !!
|
|
|
|
// Load programe.
|
|
earlyterm_write("Create first process...\n");
|
|
struct process *vhex_process = process_create();
|
|
if (vhex_process == NULL || loader(vhex_process, "/mnt/casio/VHEX/shell.elf") != 0)
|
|
{
|
|
// Display message.
|
|
earlyterm_clear();
|
|
earlyterm_write("Vhex fatal error !\n");
|
|
earlyterm_write("Unable to create the first process !\n");
|
|
if (vhex_process->context.spc == 0xffffffff)
|
|
earlyterm_write("process_create() error\n");
|
|
else
|
|
earlyterm_write("File \"VHEX/shell.elf\" not found !\n");
|
|
earlyterm_write("Press [MENU key]...\n");
|
|
|
|
// Restore Casio's context and wait MENU key
|
|
casio_return_menu(1);
|
|
}
|
|
|
|
|
|
//---
|
|
// Initialize sheduler !!
|
|
//---
|
|
//TODO: move me ?
|
|
earlyterm_write("Initialize scheduler...\n");
|
|
sched_initialize();
|
|
sched_task_add(vhex_process);
|
|
sched_start();
|
|
|
|
// normally the kernel SHOULD / CAN not arrive here.
|
|
uint32_t sr;
|
|
__asm__ volatile ("stc sr, %0" : "=r"(sr) );
|
|
earlyterm_write("Kernel job fini !\n");
|
|
earlyterm_write("SR -> %p\n", sr);
|
|
while (1) { __asm__ volatile ("sleep"); }
|
|
}
|