diff options
Diffstat (limited to 'roms/opensbi/firmware/payloads')
-rw-r--r-- | roms/opensbi/firmware/payloads/objects.mk | 19 | ||||
-rw-r--r-- | roms/opensbi/firmware/payloads/test.elf.ldS | 87 | ||||
-rw-r--r-- | roms/opensbi/firmware/payloads/test_head.S | 88 | ||||
-rw-r--r-- | roms/opensbi/firmware/payloads/test_main.c | 48 |
4 files changed, 242 insertions, 0 deletions
diff --git a/roms/opensbi/firmware/payloads/objects.mk b/roms/opensbi/firmware/payloads/objects.mk new file mode 100644 index 000000000..21e0185a8 --- /dev/null +++ b/roms/opensbi/firmware/payloads/objects.mk @@ -0,0 +1,19 @@ +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2019 Western Digital Corporation or its affiliates. +# +# Authors: +# Anup Patel <anup.patel@wdc.com> +# + +firmware-bins-$(FW_PAYLOAD) += payloads/test.bin + +test-y += test_head.o +test-y += test_main.o + +%/test.o: $(foreach obj,$(test-y),%/$(obj)) + $(call merge_objs,$@,$^) + +%/test.dep: $(foreach dep,$(test-y:.o=.dep),%/$(dep)) + $(call merge_deps,$@,$^) diff --git a/roms/opensbi/firmware/payloads/test.elf.ldS b/roms/opensbi/firmware/payloads/test.elf.ldS new file mode 100644 index 000000000..f3f3242ab --- /dev/null +++ b/roms/opensbi/firmware/payloads/test.elf.ldS @@ -0,0 +1,87 @@ +/* + * 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 +{ +#ifdef FW_PAYLOAD_OFFSET + . = FW_TEXT_START + FW_PAYLOAD_OFFSET; +#else + . = ALIGN(FW_PAYLOAD_ALIGN); +#endif + + PROVIDE(_payload_start = .); + + . = ALIGN(0x1000); /* Need this to create proper sections */ + + /* Beginning of the code section */ + + .text : + { + PROVIDE(_text_start = .); + *(.entry) + *(.text) + . = ALIGN(8); + PROVIDE(_text_end = .); + } + + . = ALIGN(0x1000); /* Ensure next section is page aligned */ + + /* End of the code sections */ + + /* Beginning of the read-only data sections */ + + . = ALIGN(0x1000); /* Ensure next section is page aligned */ + + .rodata : + { + PROVIDE(_rodata_start = .); + *(.rodata .rodata.*) + . = ALIGN(8); + PROVIDE(_rodata_end = .); + } + + /* End of the read-only data sections */ + + /* Beginning of the read-write data sections */ + + . = ALIGN(0x1000); /* Ensure next section is page aligned */ + + .data : + { + PROVIDE(_data_start = .); + + *(.data) + *(.data.*) + *(.readmostly.data) + *(*.data) + . = ALIGN(8); + + PROVIDE(_data_end = .); + } + + . = ALIGN(0x1000); /* Ensure next section is page aligned */ + + .bss : + { + PROVIDE(_bss_start = .); + *(.bss) + *(.bss.*) + . = ALIGN(8); + PROVIDE(_bss_end = .); + } + + /* End of the read-write data sections */ + + . = ALIGN(0x1000); /* Need this to create proper sections */ + + PROVIDE(_payload_end = .); +} diff --git a/roms/opensbi/firmware/payloads/test_head.S b/roms/opensbi/firmware/payloads/test_head.S new file mode 100644 index 000000000..840013e4e --- /dev/null +++ b/roms/opensbi/firmware/payloads/test_head.S @@ -0,0 +1,88 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + */ + +#include <sbi/riscv_encoding.h> +#define __ASM_STR(x) x + +#if __riscv_xlen == 64 +#define __REG_SEL(a, b) __ASM_STR(a) +#define RISCV_PTR .dword +#elif __riscv_xlen == 32 +#define __REG_SEL(a, b) __ASM_STR(b) +#define RISCV_PTR .word +#else +#error "Unexpected __riscv_xlen" +#endif + +#define REG_L __REG_SEL(ld, lw) +#define REG_S __REG_SEL(sd, sw) + + .section .entry, "ax", %progbits + .align 3 + .globl _start +_start: + /* Pick one hart to run the main boot sequence */ + la a3, _hart_lottery + li a2, 1 + amoadd.w a3, a2, (a3) + bnez a3, _start_hang + + /* Save a0 and a1 */ + la a3, _boot_a0 + REG_S a0, 0(a3) + la a3, _boot_a1 + REG_S a1, 0(a3) + + /* Zero-out BSS */ + la a4, _bss_start + la a5, _bss_end +_bss_zero: + REG_S zero, (a4) + add a4, a4, __SIZEOF_POINTER__ + blt a4, a5, _bss_zero + +_start_warm: + /* Disable and clear all interrupts */ + csrw CSR_SIE, zero + csrw CSR_SIP, zero + + /* Setup exception vectors */ + la a3, _start_hang + csrw CSR_STVEC, a3 + + /* Setup stack */ + la a3, _payload_end + li a4, 0x2000 + add sp, a3, a4 + + /* Jump to C main */ + la a3, _boot_a0 + REG_L a0, 0(a3) + la a3, _boot_a1 + REG_L a1, 0(a3) + call test_main + + /* We don't expect to reach here hence just hang */ + j _start_hang + + .section .entry, "ax", %progbits + .align 3 + .globl _start_hang +_start_hang: + wfi + j _start_hang + + .section .entry, "ax", %progbits + .align 3 +_hart_lottery: + RISCV_PTR 0 +_boot_a0: + RISCV_PTR 0 +_boot_a1: + RISCV_PTR 0 diff --git a/roms/opensbi/firmware/payloads/test_main.c b/roms/opensbi/firmware/payloads/test_main.c new file mode 100644 index 000000000..0d6593023 --- /dev/null +++ b/roms/opensbi/firmware/payloads/test_main.c @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + */ + +#include <sbi/sbi_ecall_interface.h> + +#define SBI_ECALL(__num, __a0, __a1, __a2) \ + ({ \ + register unsigned long a0 asm("a0") = (unsigned long)(__a0); \ + register unsigned long a1 asm("a1") = (unsigned long)(__a1); \ + register unsigned long a2 asm("a2") = (unsigned long)(__a2); \ + register unsigned long a7 asm("a7") = (unsigned long)(__num); \ + asm volatile("ecall" \ + : "+r"(a0) \ + : "r"(a1), "r"(a2), "r"(a7) \ + : "memory"); \ + a0; \ + }) + +#define SBI_ECALL_0(__num) SBI_ECALL(__num, 0, 0, 0) +#define SBI_ECALL_1(__num, __a0) SBI_ECALL(__num, __a0, 0, 0) +#define SBI_ECALL_2(__num, __a0, __a1) SBI_ECALL(__num, __a0, __a1, 0) + +#define sbi_ecall_console_putc(c) SBI_ECALL_1(SBI_EXT_0_1_CONSOLE_PUTCHAR, (c)) + +static inline void sbi_ecall_console_puts(const char *str) +{ + while (str && *str) + sbi_ecall_console_putc(*str++); +} + +#define wfi() \ + do { \ + __asm__ __volatile__("wfi" ::: "memory"); \ + } while (0) + +void test_main(unsigned long a0, unsigned long a1) +{ + sbi_ecall_console_puts("\nTest payload running\n"); + + while (1) + wfi(); +} |