cleans up moonlight dir
This commit is contained in:
128
port/moonlight/src/bootup.c
Normal file
128
port/moonlight/src/bootup.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
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>
|
||||
#include <picotls.h>
|
||||
#include <tx_port.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 const uint8_t __data_source;
|
||||
EXTERN_C uint8_t __tbss_start;
|
||||
EXTERN_C uintptr_t __tbss_size;
|
||||
EXTERN_C const uint8_t __tdata_source;
|
||||
EXTERN_C uint8_t __tls_base;
|
||||
EXTERN_C uintptr_t __tdata_size;
|
||||
|
||||
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.boot")));
|
||||
|
||||
// Entry and exit points as C functions.
|
||||
EXTERN_C void _initialize(void) __attribute__ ((noreturn,section(".text.boot")));
|
||||
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.
|
||||
// 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;"
|
||||
#if defined(__riscv_zicsr)
|
||||
"csrr t0, mhartid;"
|
||||
#else
|
||||
"li t0, 0;"
|
||||
#endif
|
||||
"la t1, __stack_size;"
|
||||
"la t1, __stack_size;"
|
||||
"la sp, _sp;"
|
||||
// Loop incase M extension is not present
|
||||
"1:;"
|
||||
"beqz t0, 2f;"
|
||||
"sub sp, sp, t1;"
|
||||
"addi t0, t0, -1;"
|
||||
"j 1b;"
|
||||
"2:;"
|
||||
#ifdef TX_THREAD_SMP_MAX_CORES
|
||||
"call _tx_thread_smp_initialize_wait;"
|
||||
#endif
|
||||
"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_start));
|
||||
// Clear the .tbss section (thread local variables with no initial values)
|
||||
memset((void*) &__tbss_start, 0, __tbss_size);
|
||||
// Initialize the .tls section (thread local variables with initial values)
|
||||
memcpy((void*) &__tls_base, (const void*)&__tdata_source, __tdata_size);
|
||||
// Call constructors
|
||||
for (const function_t* entry=&__init_array_start;
|
||||
entry < &__init_array_end;
|
||||
++entry) {
|
||||
(*entry)();
|
||||
}
|
||||
#ifdef __THREAD_LOCAL_STORAGE
|
||||
_set_tls(__tls_base)
|
||||
#endif
|
||||
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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user