diff --git a/cpu/fe310/context_frame.c b/cpu/fe310/context_frame.c index 4aa6448150..c3700ebaad 100644 --- a/cpu/fe310/context_frame.c +++ b/cpu/fe310/context_frame.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 JP Bonn + * Copyright (C) 2017, 2019 JP Bonn, Ken Rabold * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -40,8 +40,6 @@ static void check_context_switch_frame_alignment(void) "Stack pointer should be 16 byte aligned"); _Static_assert(sizeof(struct context_switch_frame) == CONTEXT_FRAME_SIZE, "context_switch_frame size mismatch"); - CHECK_OFFSET(pad); - CHECK_OFFSET(pc); CHECK_OFFSET(s0); CHECK_OFFSET(s1); CHECK_OFFSET(s2); @@ -55,7 +53,6 @@ static void check_context_switch_frame_alignment(void) CHECK_OFFSET(s10); CHECK_OFFSET(s11); CHECK_OFFSET(ra); - CHECK_OFFSET(tp); CHECK_OFFSET(t0); CHECK_OFFSET(t1); CHECK_OFFSET(t2); @@ -71,6 +68,8 @@ static void check_context_switch_frame_alignment(void) CHECK_OFFSET(a5); CHECK_OFFSET(a6); CHECK_OFFSET(a7); + CHECK_OFFSET(pc); + CHECK_OFFSET(pad); /* * also check the SP offset in the _frame structure diff --git a/cpu/fe310/cpu.c b/cpu/fe310/cpu.c index fb9b5e7b20..77f5c5f106 100644 --- a/cpu/fe310/cpu.c +++ b/cpu/fe310/cpu.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Ken Rabold, JP Bonn + * Copyright (C) 2017, 2019 Ken Rabold, JP Bonn * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -18,6 +18,7 @@ */ #include +#include #include #include "thread.h" @@ -39,8 +40,8 @@ volatile int __in_isr = 0; +/* ISR trap vector */ void trap_entry(void); -void thread_start(void); /* PLIC external ISR function list */ static external_isr_ptr_t _ext_isrs[PLIC_NUM_INTERRUPTS]; @@ -160,8 +161,12 @@ void external_isr(void) /** * @brief Global trap and interrupt handler */ -void handle_trap(unsigned int mcause) +void handle_trap(unsigned int mcause, unsigned int mepc, unsigned int mtval) { +#ifndef DEVELHELP + (void) mepc; + (void) mtval; +#endif /* Tell RIOT to set sched_context_switch_request instead of * calling thread_yield(). */ __in_isr = 1; @@ -170,6 +175,12 @@ void handle_trap(unsigned int mcause) if ((mcause & MCAUSE_INT) == MCAUSE_INT) { /* Cause is an interrupt - determine type */ switch (mcause & MCAUSE_CAUSE) { + case IRQ_M_SOFT: + /* Handle software interrupt - flag for context switch */ + sched_context_switch_request = 1; + CLINT_REG(0) = 0; + break; + #ifdef MODULE_PERIPH_TIMER case IRQ_M_TIMER: /* Handle timer interrupt */ @@ -188,10 +199,21 @@ void handle_trap(unsigned int mcause) } } else { +#ifdef DEVELHELP + printf("Unhandled trap:\n"); + printf(" mcause: 0x%08x\n", mcause); + printf(" mepc: 0x%08x\n", mepc); + printf(" mtval: 0x%08x\n", mtval); +#endif /* Unknown trap */ core_panic(PANIC_GENERAL_ERROR, "Unhandled trap"); } + /* Check if context change was requested */ + if (sched_context_switch_request) { + sched_run(); + } + /* ISR done - no more changes to thread states */ __in_isr = 0; } @@ -253,7 +275,6 @@ char *thread_stack_init(thread_task_func_t task_func, int stack_size) { struct context_switch_frame *sf; - uint32_t *reg; uint32_t *stk_top; /* calculate the top of the stack */ @@ -275,11 +296,10 @@ char *thread_stack_init(thread_task_func_t task_func, /* populate the stack frame with default values for starting the thread. */ sf = (struct context_switch_frame *) stk_top; - /* a7 is register with highest memory address in frame */ - reg = &sf->a7; - while (reg != &sf->pc) { - *reg-- = 0; - } + /* Clear stack frame */ + memset(sf, 0, sizeof(*sf)); + + /* set initial reg values */ sf->pc = (uint32_t) task_func; sf->a0 = (uint32_t) arg; @@ -292,7 +312,11 @@ char *thread_stack_init(thread_task_func_t task_func, void thread_print_stack(void) { int count = 0; - uint32_t *sp = (uint32_t *) sched_active_thread->sp; + uint32_t *sp = (uint32_t *) ((sched_active_thread) ? sched_active_thread->sp : NULL); + + if (sp == NULL) { + return; + } printf("printing the current stack of thread %" PRIkernel_pid "\n", thread_getpid()); diff --git a/cpu/fe310/include/context_frame.h b/cpu/fe310/include/context_frame.h index 49c65d5ed5..5b07458ba1 100644 --- a/cpu/fe310/include/context_frame.h +++ b/cpu/fe310/include/context_frame.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 JP Bonn + * Copyright (C) 2017, 2019 JP Bonn, Ken Rabold * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -40,8 +40,6 @@ extern "C" { * */ struct context_switch_frame { - uint32_t pad[2]; /**< padding to maintain 16 byte alignment */ - uint32_t pc; /**< program counter */ /* Callee saved registers */ uint32_t s0; /**< s0 register */ uint32_t s1; /**< s1 register */ @@ -57,7 +55,6 @@ struct context_switch_frame { uint32_t s11; /**< s11 register */ /* Caller saved registers */ uint32_t ra; /**< ra register */ - uint32_t tp; /**< tp register */ uint32_t t0; /**< t0 register */ uint32_t t1; /**< t1 register */ uint32_t t2; /**< t2 register */ @@ -73,6 +70,9 @@ struct context_switch_frame { uint32_t a5; /**< a5 register */ uint32_t a6; /**< a6 register */ uint32_t a7; /**< a7 register */ + /* Saved PC for return from ISR */ + uint32_t pc; /**< program counter */ + uint32_t pad[3]; /**< padding to maintain 16 byte alignment */ }; #endif /* __ASSEMBLER__ */ @@ -83,43 +83,42 @@ struct context_switch_frame { * @{ */ /* These values are checked for correctness in context_frame.c */ -#define pad_OFFSET 0 -#define pc_OFFSET 8 -#define s0_OFFSET 12 -#define s1_OFFSET 16 -#define s2_OFFSET 20 -#define s3_OFFSET 24 -#define s4_OFFSET 28 -#define s5_OFFSET 32 -#define s6_OFFSET 36 -#define s7_OFFSET 40 -#define s8_OFFSET 44 -#define s9_OFFSET 48 -#define s10_OFFSET 52 -#define s11_OFFSET 56 -#define ra_OFFSET 60 -#define tp_OFFSET 64 -#define t0_OFFSET 68 -#define t1_OFFSET 72 -#define t2_OFFSET 76 -#define t3_OFFSET 80 -#define t4_OFFSET 84 -#define t5_OFFSET 88 -#define t6_OFFSET 92 -#define a0_OFFSET 96 -#define a1_OFFSET 100 -#define a2_OFFSET 104 -#define a3_OFFSET 108 -#define a4_OFFSET 112 -#define a5_OFFSET 116 -#define a6_OFFSET 120 -#define a7_OFFSET 124 +#define s0_OFFSET 0 +#define s1_OFFSET 4 +#define s2_OFFSET 8 +#define s3_OFFSET 12 +#define s4_OFFSET 16 +#define s5_OFFSET 20 +#define s6_OFFSET 24 +#define s7_OFFSET 28 +#define s8_OFFSET 32 +#define s9_OFFSET 36 +#define s10_OFFSET 40 +#define s11_OFFSET 44 +#define ra_OFFSET 48 +#define t0_OFFSET 52 +#define t1_OFFSET 56 +#define t2_OFFSET 60 +#define t3_OFFSET 64 +#define t4_OFFSET 68 +#define t5_OFFSET 72 +#define t6_OFFSET 76 +#define a0_OFFSET 80 +#define a1_OFFSET 84 +#define a2_OFFSET 88 +#define a3_OFFSET 92 +#define a4_OFFSET 96 +#define a5_OFFSET 100 +#define a6_OFFSET 104 +#define a7_OFFSET 108 +#define pc_OFFSET 112 +#define pad_OFFSET 116 /** @} */ /** * @brief Size of context switch frame */ -#define CONTEXT_FRAME_SIZE (a7_OFFSET + 4) +#define CONTEXT_FRAME_SIZE (pad_OFFSET + 12) /** * @brief Offset of stack pointer in struct _thread diff --git a/cpu/fe310/intr.S b/cpu/fe310/intr.S index 1755545c1b..cb759759c7 100644 --- a/cpu/fe310/intr.S +++ b/cpu/fe310/intr.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 JP Bonn + * Copyright (C) 2017, 2019 JP Bonn, Ken Rabold * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -9,22 +9,12 @@ #include "vendor/encoding.h" #include "context_frame.h" -/* from platform.h TODO:fix this hard code.... */ -CLINT_CTRL_ADDR = 0x02000000 - .section .text.entry .align 2 .global trap_entry trap_entry: - /* - * Save all regs on the currently active stack. - * This coule be the active thread's stack, - * or if no thread is active, it is saved on ISR stack - * (if initial startup) or on the deactivated threads - * stack (in the case of thread exit). In the latter - * two cases the stack is just abandoned. - */ + /* Save registers to stack */ addi sp, sp, -CONTEXT_FRAME_SIZE sw s0, s0_OFFSET(sp) @@ -40,7 +30,6 @@ trap_entry: sw s10, s10_OFFSET(sp) sw s11, s11_OFFSET(sp) sw ra, ra_OFFSET(sp) - sw tp, tp_OFFSET(sp) sw t0, t0_OFFSET(sp) sw t1, t1_OFFSET(sp) sw t2, t2_OFFSET(sp) @@ -58,33 +47,40 @@ trap_entry: sw a7, a7_OFFSET(sp) - /* Get the interrupt cause */ + /* Get the interrupt cause, PC, and address */ csrr a0, mcause + csrr a1, mepc + csrr a2, mtval - /* Save active thread stack pointer in a callee save register */ - mv s1, sp + /* Save return PC in stack frame */ + sw a1, pc_OFFSET(sp) + /* Get the active thread (could be NULL) */ + lw tp, sched_active_thread + beqz tp, null_thread + + /* Save stack pointer of current thread */ + sw sp, SP_OFFSET_IN_THREAD(tp) + +null_thread: /* Switch to ISR stack. Interrupts are not nested so use fixed * starting address and just abandon stack when finished. */ la sp, _sp - addi sp, sp, -4 - /* Is it a software interrupt? */ - li t0, 0x80000003 - beq a0, t0, context_switch + /* Call handle_trap with MCAUSE and MEPC register value as args */ + call handle_trap - /* Call handle_trap with MCAUSE register value as arg */ - jal handle_trap + /* Get the active thread (guaranteed to be non NULL) */ + lw tp, sched_active_thread - /* See if a context switch was requested by the ISR */ - lw a0, sched_context_switch_request - bnez a0, context_switch + /* Load the thread SP of scheduled thread */ + lw sp, SP_OFFSET_IN_THREAD(tp) - /* Restore active thread stack pointer */ - mv sp, s1 + /* Set return PC */ + lw a1, pc_OFFSET(sp) + csrw mepc, a1 - /* Restore remaining registers */ -trap_exit: + /* Restore registers from stack */ lw s0, s0_OFFSET(sp) lw s1, s1_OFFSET(sp) lw s2, s2_OFFSET(sp) @@ -98,7 +94,6 @@ trap_exit: lw s10, s10_OFFSET(sp) lw s11, s11_OFFSET(sp) lw ra, ra_OFFSET(sp) - lw tp, tp_OFFSET(sp) lw t0, t0_OFFSET(sp) lw t1, t1_OFFSET(sp) lw t2, t2_OFFSET(sp) @@ -117,35 +112,3 @@ trap_exit: addi sp, sp, CONTEXT_FRAME_SIZE mret - - - context_switch: - /* clear the software interrupt */ - li t0, CLINT_CTRL_ADDR - sw zero, (t0) - - /* save the active thread's PC prior to interrupt on the stack */ - csrr a0, mepc - sw a0, pc_OFFSET(s1) - - /* get the active thread - it may be 0 if none currently active */ - lw t0, sched_active_thread - /* was there a previously running thread? */ - beqz t0, no_sp_save - /* if so, save the thread's SP in the _thread structure */ - sw s1,SP_OFFSET_IN_THREAD(t0) - -no_sp_save: - /* all current thread state is saved - schedule a new thread */ - call sched_run - lw tp, sched_active_thread - - /* set the threads SP from the newly scheduled thread - * and abandon ISR stack. */ - lw sp, SP_OFFSET_IN_THREAD(tp) - - /* restore the PC */ - lw a0, pc_OFFSET(sp) - csrw mepc, a0 - - j trap_exit diff --git a/cpu/fe310/ldscripts/fe310_base.ld b/cpu/fe310/ldscripts/fe310_base.ld new file mode 100644 index 0000000000..922fe6f671 --- /dev/null +++ b/cpu/fe310/ldscripts/fe310_base.ld @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2017, 2019 Ken Rabold + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup cpu_fe310 + * @{ + * + * @file + * @brief Common linker directives for the SiFive FE310 + * + * @author Ken Rabold + * + * @} + */ + +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 256; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >flash AT>flash :flash + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.ramfunc .ramfunc.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + PROVIDE( _heap_start = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +} diff --git a/cpu/fe310/ldscripts/fe310_g000.ld b/cpu/fe310/ldscripts/fe310_g000.ld index 56c73cd12a..0886577103 100644 --- a/cpu/fe310/ldscripts/fe310_g000.ld +++ b/cpu/fe310/ldscripts/fe310_g000.ld @@ -18,10 +18,6 @@ * @} */ -OUTPUT_ARCH( "riscv" ) - -ENTRY( _start ) - MEMORY { flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 0x1fc00000 @@ -29,156 +25,4 @@ MEMORY itim (wxa!ri) : ORIGIN = 0x08000000, LENGTH = 0x00002000 } -PHDRS -{ - flash PT_LOAD; - ram_init PT_LOAD; - ram PT_NULL; -} - -SECTIONS -{ - __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; - - .init : - { - KEEP (*(SORT_NONE(.init))) - } >flash AT>flash :flash - - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - *(.text .text.*) - *(.gnu.linkonce.t.*) - } >flash AT>flash :flash - - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } >flash AT>flash :flash - - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - .rodata : - { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >flash AT>flash :flash - - . = ALIGN(4); - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >flash AT>flash :flash - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } >flash AT>flash :flash - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >flash AT>flash :flash - - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } >flash AT>flash :flash - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } >flash AT>flash :flash - - .lalign : - { - . = ALIGN(4); - PROVIDE( _data_lma = . ); - } >flash AT>flash :flash - - .dalign : - { - . = ALIGN(4); - PROVIDE( _data = . ); - } >ram AT>flash :ram_init - - .data : - { - *(.ramfunc .ramfunc.*) - *(.data .data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - PROVIDE( __global_pointer$ = . + 0x800 ); - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } >ram AT>flash :ram_init - - . = ALIGN(4); - PROVIDE( _edata = . ); - PROVIDE( edata = . ); - - PROVIDE( _fbss = . ); - PROVIDE( __bss_start = . ); - .bss : - { - *(.sbss*) - *(.gnu.linkonce.sb.*) - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >ram AT>ram :ram - - . = ALIGN(8); - PROVIDE( _end = . ); - PROVIDE( end = . ); - PROVIDE( _heap_start = . ); - - .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : - { - PROVIDE( _heap_end = . ); - . = __stack_size; - PROVIDE( _sp = . ); - } >ram AT>ram :ram -} +INCLUDE fe310_base.ld \ No newline at end of file diff --git a/cpu/fe310/ldscripts/fe310_g002.ld b/cpu/fe310/ldscripts/fe310_g002.ld index 58317fbb8f..980be111c0 100644 --- a/cpu/fe310/ldscripts/fe310_g002.ld +++ b/cpu/fe310/ldscripts/fe310_g002.ld @@ -18,10 +18,6 @@ * @} */ -OUTPUT_ARCH( "riscv" ) - -ENTRY( _start ) - MEMORY { flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x0006a120 @@ -29,156 +25,4 @@ MEMORY itim (wxa!ri) : ORIGIN = 0x08000000, LENGTH = 0x00002000 } -PHDRS -{ - flash PT_LOAD; - ram_init PT_LOAD; - ram PT_NULL; -} - -SECTIONS -{ - __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; - - .init : - { - KEEP (*(SORT_NONE(.init))) - } >flash AT>flash :flash - - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - *(.text .text.*) - *(.gnu.linkonce.t.*) - } >flash AT>flash :flash - - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } >flash AT>flash :flash - - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - .rodata : - { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - } >flash AT>flash :flash - - . = ALIGN(4); - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >flash AT>flash :flash - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } >flash AT>flash :flash - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >flash AT>flash :flash - - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } >flash AT>flash :flash - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } >flash AT>flash :flash - - .lalign : - { - . = ALIGN(4); - PROVIDE( _data_lma = . ); - } >flash AT>flash :flash - - .dalign : - { - . = ALIGN(4); - PROVIDE( _data = . ); - } >ram AT>flash :ram_init - - .data : - { - *(.ramfunc .ramfunc.*) - *(.data .data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - PROVIDE( __global_pointer$ = . + 0x800 ); - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } >ram AT>flash :ram_init - - . = ALIGN(4); - PROVIDE( _edata = . ); - PROVIDE( edata = . ); - - PROVIDE( _fbss = . ); - PROVIDE( __bss_start = . ); - .bss : - { - *(.sbss*) - *(.gnu.linkonce.sb.*) - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >ram AT>ram :ram - - . = ALIGN(8); - PROVIDE( _end = . ); - PROVIDE( end = . ); - PROVIDE( _heap_start = . ); - - .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : - { - PROVIDE( _heap_end = . ); - . = __stack_size; - PROVIDE( _sp = . ); - } >ram AT>ram :ram -} +INCLUDE fe310_base.ld