From 31578e285a21a749a49e3ac146feb8b02fcc7b52 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Wed, 4 Dec 2019 06:11:35 +0100 Subject: added new metal sdk --- code/fe310/metal/entry.S | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 code/fe310/metal/entry.S (limited to 'code/fe310/metal/entry.S') diff --git a/code/fe310/metal/entry.S b/code/fe310/metal/entry.S new file mode 100644 index 0000000..97da3fd --- /dev/null +++ b/code/fe310/metal/entry.S @@ -0,0 +1,106 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* This code executes before _start, which is contained inside the C library. + * In embedded systems we want to ensure that _enter, which contains the first + * code to be executed, can be loaded at a specific address. To enable this + * feature we provide the '.text.metal.init.enter' section, which is + * defined to have the first address being where execution should start. */ +.section .text.metal.init.enter +.global _enter +_enter: + .cfi_startproc + + /* Inform the debugger that there is nowhere to backtrace past _enter. */ + .cfi_undefined ra + + /* The absolute first thing that must happen is configuring the global + * pointer register, which must be done with relaxation disabled because + * it's not valid to obtain the address of any symbol without GP + * configured. The C environment might go ahead and do this again, but + * that's safe as it's a fixed register. */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + /* Set up a simple trap vector to catch anything that goes wrong early in + * the boot process. */ + la t0, early_trap_vector + csrw mtvec, t0 + /* enable chicken bit if core is bullet series*/ + la t0, __metal_chicken_bit + beqz t0, 1f + csrwi 0x7C1, 0 +1: + + /* There may be pre-initialization routines inside the MBI code that run in + * C, so here we set up a C environment. First we set up a stack pointer, + * which is left as a weak reference in order to allow initialization + * routines that do not need a stack to be set up to transparently be + * called. */ + .weak __metal_stack_pointer + la sp, __metal_stack_pointer + + /* Check for an initialization routine and call it if one exists, otherwise + * just skip over the call entirely. Note that __metal_initialize isn't + * actually a full C function, as it doesn't end up with the .bss or .data + * segments having been initialized. This is done to avoid putting a + * burden on systems that can be initialized without having a C environment + * set up. */ + .weak __metal_before_start + la ra, __metal_before_start + beqz ra, 1f + jalr ra +1: + + /* At this point we can enter the C runtime's startup file. The arguments + * to this function are designed to match those provided to the SEE, just + * so we don't have to write another ABI. */ + csrr a0, mhartid + li a1, 0 + li a2, 0 + call _start + + /* If we've made it back here then there's probably something wrong. We + * allow the METAL to register a handler here. */ + .weak __metal_after_main + la ra, __metal_after_main + beqz ra, 1f + jalr ra +1: + + /* If that handler returns then there's not a whole lot we can do. Just + * try to make some noise. */ + la t0, 1f + csrw mtvec, t0 +1: + lw t1, 0(x0) + j 1b + + .cfi_endproc + +/* For sanity's sake we set up an early trap vector that just does nothing. If + * you end up here then there's a bug in the early boot code somewhere. */ +.section .text.metal.init.trapvec +.align 2 +early_trap_vector: + .cfi_startproc + csrr t0, mcause + csrr t1, mepc + csrr t2, mtval + j early_trap_vector + .cfi_endproc + +/* The GCC port might not emit a __register_frame_info symbol, which eventually + * results in a weak undefined reference that eventually causes crash when it + * is dereference early in boot. We really shouldn't need to put this here, + * but to deal with what I think is probably a bug in the linker script I'm + * going to leave this in for now. At least it's fairly cheap :) */ +.weak __register_frame_info +.global __register_frame_info +.section .text.metal.init.__register_frame_info +__register_frame_info: + .cfi_startproc + ret + .cfi_endproc -- cgit v1.2.3