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 <cpu.h> 8 #include <dm.h> 9 #include <log.h> 10 #include <asm/csr.h> 11 #include <dm/uclass-internal.h> 12 13 /* 14 * prior_stage_fdt_address must be stored in the data section since it is used 15 * before the bss section is available. 16 */ 17 phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); 18 19 static inline bool supports_extension(char ext) 20 { 21 #ifdef CONFIG_CPU 22 struct udevice *dev; 23 char desc[32]; 24 25 uclass_find_first_device(UCLASS_CPU, &dev); 26 if (!dev) { 27 debug("unable to find the RISC-V cpu device\n"); 28 return false; 29 } 30 if (!cpu_get_desc(dev, desc, sizeof(desc))) { 31 /* skip the first 4 characters (rv32|rv64) */ 32 if (strchr(desc + 4, ext)) 33 return true; 34 } 35 36 return false; 37 #else /* !CONFIG_CPU */ 38 #ifdef CONFIG_RISCV_MMODE 39 return csr_read(misa) & (1 << (ext - 'a')); 40 #else /* !CONFIG_RISCV_MMODE */ 41 #warning "There is no way to determine the available extensions in S-mode." 42 #warning "Please convert your board to use the RISC-V CPU driver." 43 return false; 44 #endif /* CONFIG_RISCV_MMODE */ 45 #endif /* CONFIG_CPU */ 46 } 47 48 static int riscv_cpu_probe(void) 49 { 50 #ifdef CONFIG_CPU 51 int ret; 52 53 /* probe cpus so that RISC-V timer can be bound */ 54 ret = cpu_probe_all(); 55 if (ret) 56 return log_msg_ret("RISC-V cpus probe failed\n", ret); 57 #endif 58 59 return 0; 60 } 61 62 int arch_cpu_init_dm(void) 63 { 64 return riscv_cpu_probe(); 65 } 66 67 int arch_early_init_r(void) 68 { 69 return riscv_cpu_probe(); 70 } 71