1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <fdtdec.h> 9 #include <virtio_types.h> 10 #include <virtio.h> 11 12 int board_init(void) 13 { 14 /* 15 * Make sure virtio bus is enumerated so that peripherals 16 * on the virtio bus can be discovered by their drivers 17 */ 18 virtio_init(); 19 20 return 0; 21 } 22 23 int board_late_init(void) 24 { 25 ulong kernel_start; 26 ofnode chosen_node; 27 int ret; 28 29 chosen_node = ofnode_path("/chosen"); 30 if (!ofnode_valid(chosen_node)) { 31 debug("No chosen node found, can't get kernel start address\n"); 32 return 0; 33 } 34 35 #ifdef CONFIG_ARCH_RV64I 36 ret = ofnode_read_u64(chosen_node, "riscv,kernel-start", 37 (u64 *)&kernel_start); 38 #else 39 ret = ofnode_read_u32(chosen_node, "riscv,kernel-start", 40 (u32 *)&kernel_start); 41 #endif 42 if (ret) { 43 debug("Can't find kernel start address in device tree\n"); 44 return 0; 45 } 46 47 env_set_hex("kernel_start", kernel_start); 48 49 return 0; 50 } 51 52 /* 53 * QEMU specifies the location of Linux (supplied with the -kernel argument) 54 * in the device tree using the riscv,kernel-start and riscv,kernel-end 55 * properties. We currently rely on the SBI implementation of BBL to run 56 * Linux and therefore embed Linux as payload in BBL. This causes an issue, 57 * because BBL detects the kernel properties in the device tree and ignores 58 * the Linux payload as a result. To work around this issue, we clear the 59 * kernel properties before booting Linux. 60 * 61 * This workaround can be removed, once we do not require BBL for its SBI 62 * implementation anymore. 63 */ 64 int ft_board_setup(void *blob, bd_t *bd) 65 { 66 int chosen_offset, ret; 67 68 chosen_offset = fdt_path_offset(blob, "/chosen"); 69 if (chosen_offset < 0) 70 return 0; 71 72 #ifdef CONFIG_ARCH_RV64I 73 ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0); 74 #else 75 ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0); 76 #endif 77 if (ret) 78 return ret; 79 80 #ifdef CONFIG_ARCH_RV64I 81 ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0); 82 #else 83 ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0); 84 #endif 85 if (ret) 86 return ret; 87 88 return 0; 89 } 90