/ src / arch / riscv / opensbi.c
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  }