]>
Commit | Line | Data |
---|---|---|
2fab2e9c BM |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright (C) 2018, Bin Meng <[email protected]> | |
4 | */ | |
5 | ||
6 | #include <common.h> | |
39cad5bc | 7 | #include <cpu.h> |
aef59e5c | 8 | #include <dm.h> |
691d719d | 9 | #include <init.h> |
39cad5bc | 10 | #include <log.h> |
485e8223 | 11 | #include <asm/encoding.h> |
aef59e5c | 12 | #include <dm/uclass-internal.h> |
cd93d625 | 13 | #include <linux/bitops.h> |
2fab2e9c | 14 | |
5d8b2e77 | 15 | /* |
3dea63c8 | 16 | * The variables here must be stored in the data section since they are used |
5d8b2e77 LA |
17 | * before the bss section is available. |
18 | */ | |
f9281b89 | 19 | #ifdef CONFIG_OF_PRIOR_STAGE |
5d8b2e77 | 20 | phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); |
f9281b89 | 21 | #endif |
bdce3896 | 22 | #ifndef CONFIG_XIP |
3dea63c8 LA |
23 | u32 hart_lottery __attribute__((section(".data"))) = 0; |
24 | ||
25 | /* | |
26 | * The main hart running U-Boot has acquired available_harts_lock until it has | |
27 | * finished initialization of global data. | |
28 | */ | |
29 | u32 available_harts_lock = 1; | |
bdce3896 | 30 | #endif |
5d8b2e77 | 31 | |
2fab2e9c BM |
32 | static inline bool supports_extension(char ext) |
33 | { | |
aef59e5c BM |
34 | #ifdef CONFIG_CPU |
35 | struct udevice *dev; | |
36 | char desc[32]; | |
37 | ||
38 | uclass_find_first_device(UCLASS_CPU, &dev); | |
39 | if (!dev) { | |
40 | debug("unable to find the RISC-V cpu device\n"); | |
41 | return false; | |
42 | } | |
43 | if (!cpu_get_desc(dev, desc, sizeof(desc))) { | |
44 | /* skip the first 4 characters (rv32|rv64) */ | |
45 | if (strchr(desc + 4, ext)) | |
46 | return true; | |
47 | } | |
48 | ||
49 | return false; | |
50 | #else /* !CONFIG_CPU */ | |
fbfd92bf | 51 | #if CONFIG_IS_ENABLED(RISCV_MMODE) |
4d2583db | 52 | return csr_read(CSR_MISA) & (1 << (ext - 'a')); |
fbfd92bf | 53 | #else /* !CONFIG_IS_ENABLED(RISCV_MMODE) */ |
aef59e5c BM |
54 | #warning "There is no way to determine the available extensions in S-mode." |
55 | #warning "Please convert your board to use the RISC-V CPU driver." | |
56 | return false; | |
fbfd92bf | 57 | #endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */ |
aef59e5c | 58 | #endif /* CONFIG_CPU */ |
2fab2e9c BM |
59 | } |
60 | ||
39cad5bc BM |
61 | static int riscv_cpu_probe(void) |
62 | { | |
63 | #ifdef CONFIG_CPU | |
64 | int ret; | |
65 | ||
66 | /* probe cpus so that RISC-V timer can be bound */ | |
67 | ret = cpu_probe_all(); | |
68 | if (ret) | |
69 | return log_msg_ret("RISC-V cpus probe failed\n", ret); | |
70 | #endif | |
71 | ||
72 | return 0; | |
73 | } | |
74 | ||
75 | int arch_cpu_init_dm(void) | |
76 | { | |
485e8223 BM |
77 | int ret; |
78 | ||
79 | ret = riscv_cpu_probe(); | |
80 | if (ret) | |
81 | return ret; | |
82 | ||
83 | /* Enable FPU */ | |
84 | if (supports_extension('d') || supports_extension('f')) { | |
85 | csr_set(MODE_PREFIX(status), MSTATUS_FS); | |
4d2583db | 86 | csr_write(CSR_FCSR, 0); |
485e8223 BM |
87 | } |
88 | ||
89 | if (CONFIG_IS_ENABLED(RISCV_MMODE)) { | |
90 | /* | |
91 | * Enable perf counters for cycle, time, | |
92 | * and instret counters only | |
93 | */ | |
b8bc1209 SA |
94 | #ifdef CONFIG_RISCV_PRIV_1_9 |
95 | csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0)); | |
96 | csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0)); | |
97 | #else | |
4d2583db | 98 | csr_write(CSR_MCOUNTEREN, GENMASK(2, 0)); |
b8bc1209 | 99 | #endif |
485e8223 BM |
100 | |
101 | /* Disable paging */ | |
102 | if (supports_extension('s')) | |
b8bc1209 SA |
103 | #ifdef CONFIG_RISCV_PRIV_1_9 |
104 | csr_read_clear(CSR_MSTATUS, SR_VM); | |
105 | #else | |
4d2583db | 106 | csr_write(CSR_SATP, 0); |
b8bc1209 | 107 | #endif |
485e8223 BM |
108 | } |
109 | ||
40686c39 SA |
110 | #ifdef CONFIG_SMP |
111 | ret = riscv_init_ipi(); | |
112 | if (ret) | |
113 | return ret; | |
114 | #endif | |
115 | ||
485e8223 | 116 | return 0; |
39cad5bc BM |
117 | } |
118 | ||
119 | int arch_early_init_r(void) | |
120 | { | |
121 | return riscv_cpu_probe(); | |
122 | } |