[RFC PATCH v7 0/2] riscv: cpu: Add callback to init each core

Add a callback interface, harts_early_init() to perform proprietary or customized CRSs configuration for each hart. harts_early_init() is placed after stack of harts are initialized and before main boot hart is picked up. Several conditions should be aware of or avoided are listed:
- cannot access gd At the moment, gd hasn't initialized yet.
- all operations in harts_early_init() should only affect core itself For example, the operations for board level should be moved to mach_xxx() or board_init_xxx() functions instead.
- Common resource need protection if multicore Since all harts might enter harts_early_init() in parallel, common resource need a mechanism to handle race condition.
- A reference implementation is added in ./arch/riscv/cpu/cpu.c The implementation is declared with '__weak' and can be overridden.
Changelogs: v7 - remove M-mode check in [v6 1/2] - remove 'arch' from title of patch - add Reviewed-by v6 - revised the description in both of commit message and comment [1/2] - moved the implementation of harts_early_init() in [2/2] from board/sifive/unmatched/spl.c to arch/riscv/cpu/fu740/spl.c. and revised commit message v5 - rename riscv_hart_early_init to harts_early_init - rephrase dummy for harts_early_init() to callback but keep current comments not specific for customizing CSRs only. - Fix nit in [2/2] and add reviewed-by v4 - Revising the comments for riscv_hart_early_init() in [1/2] - Remove unnecessary braces and add reviewed-by in [2/2]
Green Wan (2): riscv: cpu: Add callback to init each core riscv: cpu: fu740: clear feature disable CSR
arch/riscv/cpu/cpu.c | 11 +++++++++++ arch/riscv/cpu/fu740/spl.c | 15 +++++++++++++++ arch/riscv/cpu/start.S | 6 ++++++ 3 files changed, 32 insertions(+)

Add a callback harts_early_init() to start.S to allow different riscv hart perform setup code for each hart as early as possible. Since all the harts enter the callback, they must be able to run the same setup.
Signed-off-by: Green Wan green.wan@sifive.com Reviewed-by: Rick Chen rick@andestech.com --- arch/riscv/cpu/cpu.c | 11 +++++++++++ arch/riscv/cpu/start.S | 6 ++++++ 2 files changed, 17 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 85592f5bee..43c086ca19 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -140,3 +140,14 @@ int arch_early_init_r(void) { return riscv_cpu_probe(); } + +/** + * harts_early_init() - A callback function called by start.S to configure + * feature settings of each hart. + * + * In a multi-core system, memory access shall be careful here, it shall + * take care race conditions. + */ +__weak void harts_early_init(void) +{ +} diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 8589509e01..bdd5517bca 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -117,6 +117,12 @@ call_board_init_f_0: mv sp, a0 #endif
+ /* + * Configure proprietary settings and customized CRSs of harts + */ +call_harts_early_init: + jal harts_early_init + #ifndef CONFIG_XIP /* * Pick hart to initialize global data and run U-Boot. The other harts

Hi Green,
On Thu, Apr 22, 2021 at 5:18 PM Green Wan green.wan@sifive.com wrote:
Add a callback harts_early_init() to start.S to allow different riscv hart perform setup code for each hart as early as possible. Since all the harts enter the callback, they must be able to run the same setup.
Signed-off-by: Green Wan green.wan@sifive.com Reviewed-by: Rick Chen rick@andestech.com
arch/riscv/cpu/cpu.c | 11 +++++++++++ arch/riscv/cpu/start.S | 6 ++++++ 2 files changed, 17 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 85592f5bee..43c086ca19 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -140,3 +140,14 @@ int arch_early_init_r(void) { return riscv_cpu_probe(); }
+/**
- harts_early_init() - A callback function called by start.S to configure
- feature settings of each hart.
- In a multi-core system, memory access shall be careful here, it shall
- take care race conditions.
nits: take care of
- */
+__weak void harts_early_init(void) +{ +} diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 8589509e01..bdd5517bca 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -117,6 +117,12 @@ call_board_init_f_0: mv sp, a0 #endif
/*
* Configure proprietary settings and customized CRSs of harts
nits: use single line comment if this does exceed 80 characters
CRSs => CSRs
*/
+call_harts_early_init:
jal harts_early_init
#ifndef CONFIG_XIP /* * Pick hart to initialize global data and run U-Boot. The other harts --
Otherwise, Reviewed-by: Bin Meng bmeng.cn@gmail.com
I think you can remove the RFC tag in the next version.
Regards, Bin

Thanks for the review. Will fix the issues and remove the RFC.
- Green
Bin Meng bmeng.cn@gmail.com於 2021年5月1日 週六,下午7:55寫道:
Hi Green,
On Thu, Apr 22, 2021 at 5:18 PM Green Wan green.wan@sifive.com wrote:
Add a callback harts_early_init() to start.S to allow different riscv hart perform setup code for each hart as early as possible. Since all the harts enter the callback, they must be able to run the same setup.
Signed-off-by: Green Wan green.wan@sifive.com Reviewed-by: Rick Chen rick@andestech.com
arch/riscv/cpu/cpu.c | 11 +++++++++++ arch/riscv/cpu/start.S | 6 ++++++ 2 files changed, 17 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 85592f5bee..43c086ca19 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -140,3 +140,14 @@ int arch_early_init_r(void) { return riscv_cpu_probe(); }
+/**
- harts_early_init() - A callback function called by start.S to
configure
- feature settings of each hart.
- In a multi-core system, memory access shall be careful here, it shall
- take care race conditions.
nits: take care of
- */
+__weak void harts_early_init(void) +{ +} diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 8589509e01..bdd5517bca 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -117,6 +117,12 @@ call_board_init_f_0: mv sp, a0 #endif
/*
* Configure proprietary settings and customized CRSs of harts
nits: use single line comment if this does exceed 80 characters
CRSs => CSRs
*/
+call_harts_early_init:
jal harts_early_init
#ifndef CONFIG_XIP /* * Pick hart to initialize global data and run U-Boot. The other
harts
--
Otherwise, Reviewed-by: Bin Meng bmeng.cn@gmail.com
I think you can remove the RFC tag in the next version.
Regards, Bin

Clear feature disable CSR to turn on all features of hart. The detail is specified at section, 'SiFive Feature Disable CSR', in user manual
https://sifive.cdn.prismic.io/sifive/aee0dd4c-d156-496e-a6c4-db0cf54bbe68_si...
Signed-off-by: Green Wan green.wan@sifive.com Reviewed-by: Sean Anderson seanga2@gmail.com Reviewed-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Rick Chen rick@andestech.com --- arch/riscv/cpu/fu740/spl.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/arch/riscv/cpu/fu740/spl.c b/arch/riscv/cpu/fu740/spl.c index ea0b2283a2..55e30346ff 100644 --- a/arch/riscv/cpu/fu740/spl.c +++ b/arch/riscv/cpu/fu740/spl.c @@ -6,6 +6,9 @@
#include <dm.h> #include <log.h> +#include <asm/csr.h> + +#define CSR_U74_FEATURE_DISABLE 0x7c1
int spl_soc_init(void) { @@ -21,3 +24,15 @@ int spl_soc_init(void)
return 0; } + +void harts_early_init(void) +{ + /* + * Feature Disable CSR + * + * Clear feature disable CSR to '0' to turn on all features for + * each core. This operation must be in M-mode. + */ + if (CONFIG_IS_ENABLED(RISCV_MMODE)) + csr_write(CSR_U74_FEATURE_DISABLE, 0); +}
participants (2)
-
Bin Meng
-
Green Wan