aboutsummaryrefslogtreecommitdiffstats
path: root/roms/opensbi/firmware/payloads
diff options
context:
space:
mode:
Diffstat (limited to 'roms/opensbi/firmware/payloads')
-rw-r--r--roms/opensbi/firmware/payloads/objects.mk19
-rw-r--r--roms/opensbi/firmware/payloads/test.elf.ldS87
-rw-r--r--roms/opensbi/firmware/payloads/test_head.S88
-rw-r--r--roms/opensbi/firmware/payloads/test_main.c48
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();
+}