initial commit

This commit is contained in:
2026-01-27 20:45:47 +01:00
commit 1e5eb44ca9
53 changed files with 11048 additions and 0 deletions

101
port/moonlight/bootup.c Normal file
View File

@@ -0,0 +1,101 @@
/*
Simple C++ startup routine to setup CRT
SPDX-License-Identifier: Unlicense
(https://five-embeddev.com/ | http://www.shincbm.com/)
*/
#include <stdint.h>
#include <string.h>
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C extern
#endif
// Generic C function pointer.
typedef void(*function_t)(void) ;
// These symbols are defined by the linker script.
// See linker.lds
EXTERN_C uint8_t __bss_start;
EXTERN_C uint8_t __bss_end;
EXTERN_C const uint8_t __data_source;
EXTERN_C uint8_t __data_start;
EXTERN_C uint8_t __data_end;
EXTERN_C function_t __init_array_start;
EXTERN_C function_t __init_array_end;
EXTERN_C function_t __fini_array_start;
EXTERN_C function_t __fini_array_end;
// This function will be placed by the linker script according to the section
// Raw function 'called' by the CPU with no runtime.
EXTERN_C void _start(void) __attribute__ ((naked,section(".text.init")));
// Entry and exit points as C functions.
EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".init")));
EXTERN_C void _exit(int exit_code) __attribute__ ((noreturn,noinline,weak));
// Standard entry point, no arguments.
extern int main(void);
// The linker script will place this in the reset entry point.
// It will be 'called' with no stack or C runtime configuration.
// NOTE - this only supports a single hart.
// tp will not be initialized
void _start(void) {
// Setup SP and GP
// The locations are defined in the linker script
__asm__ volatile (
".option push;"
// The 'norelax' option is critical here.
// Without 'norelax' the global pointer will
// be loaded relative to the global pointer!
".option norelax;"
"la gp, __global_pointer$;"
".option pop;"
"la sp, _sp;"
"jal zero, _initialize;"
: /* output: none %0 */
: /* input: none */
: /* clobbers: none */);
// This point will not be executed, _initialize() will be called with no return.
}
// At this point we have a stack and global poiner, but no access to global variables.
void _initialize(void) {
// Init memory regions
// Clear the .bss section (global variables with no initial values)
memset((void*) &__bss_start,
0,
(&__bss_end - &__bss_start));
// Initialize the .data section (global variables with initial values)
memcpy((void*)&__data_start,
(const void*)&__data_source,
(&__data_end - &__data_end));
// Call constructors
for (const function_t* entry=&__init_array_start;
entry < &__init_array_end;
++entry) {
(*entry)();
}
int rc = main();
// Call destructors
for (const function_t* entry=&__fini_array_start;
entry < &__fini_array_end;
++entry) {
(*entry)();
}
_exit(rc);
}
// This should never be called. Busy loop with the CPU in idle state.
void _exit(int exit_code) {
(void)exit_code;
// Halt
while (1) {
__asm__ volatile ("wfi");
}
}