diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/fw_dynamic.S | 118 | ||||
-rw-r--r-- | firmware/fw_dynamic.elf.ldS | 16 | ||||
-rw-r--r-- | firmware/objects.mk | 2 |
3 files changed, 136 insertions, 0 deletions
diff --git a/firmware/fw_dynamic.S b/firmware/fw_dynamic.S new file mode 100644 index 0000000..cf97b60 --- /dev/null +++ b/firmware/fw_dynamic.S @@ -0,0 +1,118 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + */ + +#include <sbi/fw_dynamic.h> + +#include "fw_base.S" + + .align 3 + .section .entry, "ax", %progbits +_bad_dynamic_info: + wfi + j _bad_dynamic_info + + .align 3 + .section .entry, "ax", %progbits + .global fw_save_info + /* + * We can only use a0, a1, a2, a3, and a4 registers here. + * The a0, a1, and a2 registers will be same as passed by + * previous booting stage. + * Nothing to be returned here. + */ +fw_save_info: + la a4, _dynamic_next_arg1 + REG_S a1, (a4) + li a4, FW_DYNAMIC_INFO_MAGIC_VALUE + REG_L a3, FW_DYNAMIC_INFO_MAGIC_OFFSET(a2) + bne a3, a4, _bad_dynamic_info + li a4, FW_DYNAMIC_INFO_VERSION_MAX + REG_L a3, FW_DYNAMIC_INFO_VERSION_OFFSET(a2) + bgt a3, a4, _bad_dynamic_info + la a4, _dynamic_next_addr + REG_L a3, FW_DYNAMIC_INFO_NEXT_ADDR_OFFSET(a2) + REG_S a3, (a4) + la a4, _dynamic_next_mode + REG_L a3, FW_DYNAMIC_INFO_NEXT_MODE_OFFSET(a2) + REG_S a3, (a4) + la a4, _dynamic_options + REG_L a3, FW_DYNAMIC_INFO_OPTIONS_OFFSET(a2) + REG_S a3, (a4) + ret + + .align 3 + .section .entry, "ax", %progbits + .global fw_prev_arg1 + /* + * We can only use a0, a1, and a2 registers here. + * The previous arg1 should be returned in 'a0'. + */ +fw_prev_arg1: + add a0, zero, zero + ret + + .align 3 + .section .entry, "ax", %progbits + .global fw_next_arg1 + /* + * We can only use a0, a1, and a2 registers here. + * The next arg1 should be returned in 'a0'. + */ +fw_next_arg1: + la a0, _dynamic_next_arg1 + REG_L a0, (a0) + ret + + .align 3 + .section .entry, "ax", %progbits + .global fw_next_addr + /* + * We can only use a0, a1, and a2 registers here. + * The next address should be returned in 'a0'. + */ +fw_next_addr: + la a0, _dynamic_next_addr + REG_L a0, (a0) + ret + + .align 3 + .section .entry, "ax", %progbits + .global fw_next_mode + /* + * We can only use a0, a1, and a2 registers here. + * The next address should be returned in 'a0' + */ +fw_next_mode: + la a0, _dynamic_next_mode + REG_L a0, (a0) + ret + + .align 3 + .section .entry, "ax", %progbits + .global fw_options + /* + * We can only use a0, a1, and a2 registers here. + * The 'a4' register will have default options. + * The next address should be returned in 'a0'. + */ +fw_options: + la a0, _dynamic_options + REG_L a0, (a0) + ret + + .align 3 + .section .entry, "ax", %progbits +_dynamic_next_arg1: + RISCV_PTR 0x0 +_dynamic_next_addr: + RISCV_PTR 0x0 +_dynamic_next_mode: + RISCV_PTR PRV_S +_dynamic_options: + RISCV_PTR 0x0 diff --git a/firmware/fw_dynamic.elf.ldS b/firmware/fw_dynamic.elf.ldS new file mode 100644 index 0000000..7ee0787 --- /dev/null +++ b/firmware/fw_dynamic.elf.ldS @@ -0,0 +1,16 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + */ + +OUTPUT_ARCH(riscv) +ENTRY(_start) + +SECTIONS +{ + #include "fw_base.ldS" +} diff --git a/firmware/objects.mk b/firmware/objects.mk index cc38283..e8969e6 100644 --- a/firmware/objects.mk +++ b/firmware/objects.mk @@ -17,6 +17,8 @@ ifdef FW_TEXT_START firmware-genflags-y += -DFW_TEXT_START=$(FW_TEXT_START) endif +firmware-bins-$(FW_DYNAMIC) += fw_dynamic.bin + firmware-bins-$(FW_JUMP) += fw_jump.bin ifdef FW_JUMP_ADDR firmware-genflags-$(FW_JUMP) += -DFW_JUMP_ADDR=$(FW_JUMP_ADDR) |