opensbi.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <arch/boot.h> 4 #include <arch/encoding.h> 5 #include <stdint.h> 6 #include <stddef.h> 7 8 #define FW_DYNAMIC_INFO_VERSION_2 2 9 #define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f // "OSBI" 10 11 /* 12 * structure passed to OpenSBI as 3rd argument 13 * NOTE: This structure may need to be updated when the OpenSBI submodule is updated. 14 */ 15 static struct __packed fw_dynamic_info { 16 unsigned long magic; // magic value "OSBI" 17 unsigned long version; // version number (2) 18 unsigned long next_addr; // Next booting stage address (payload address) 19 unsigned long next_mode; // Next booting stage mode (usually supervisor mode) 20 unsigned long options; // options for OpenSBI library 21 unsigned long boot_hart; // usually CONFIG_RISCV_WORKING_HARTID 22 } info; 23 24 void run_opensbi(const int hart_id, 25 const void *fdt, 26 const void *opensbi, 27 const void *payload, 28 const int payload_mode) 29 { 30 info.magic = FW_DYNAMIC_INFO_MAGIC_VALUE, 31 info.version = FW_DYNAMIC_INFO_VERSION_2, 32 info.next_mode = payload_mode, 33 info.next_addr = (uintptr_t)payload, 34 info.options = 0, 35 info.boot_hart = CONFIG_OPENSBI_FW_DYNAMIC_BOOT_HART, 36 37 write_csr(mepc, opensbi); // set program counter to OpenSBI (jumped to with mret) 38 asm volatile ( 39 "mv a0, %0\n\t" 40 "mv a1, %1\n\t" 41 "mv a2, %2\n\t" 42 "mret" 43 : 44 : "r"(hart_id), "r"(fdt), "r"(&info) 45 : "a0", "a1", "a2" 46 ); 47 }