diff mbox series

[RFC,v3,1/2] arch: riscv: cpu: Add callback to init each core

Message ID 20210327021830.121266-2-green.wan@sifive.com
State Superseded
Delegated to: Andes
Headers show
Series arch: riscv: cpu: Add callback to init each core | expand

Commit Message

Green Wan March 27, 2021, 2:18 a.m. UTC
Add a callback riscv_hart_early_init() to ./arch/riscv/cpu/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>
---
 arch/riscv/cpu/cpu.c   | 15 +++++++++++++++
 arch/riscv/cpu/start.S | 14 ++++++++++++++
 2 files changed, 29 insertions(+)

Comments

Sean Anderson March 29, 2021, 2:26 a.m. UTC | #1
On 3/26/21 10:18 PM, Green Wan wrote:
> Add a callback riscv_hart_early_init() to ./arch/riscv/cpu/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>
> ---
>   arch/riscv/cpu/cpu.c   | 15 +++++++++++++++
>   arch/riscv/cpu/start.S | 14 ++++++++++++++
>   2 files changed, 29 insertions(+)
> 
> diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
> index 85592f5bee..c779a477c7 100644
> --- a/arch/riscv/cpu/cpu.c
> +++ b/arch/riscv/cpu/cpu.c
> @@ -140,3 +140,18 @@ int arch_early_init_r(void)
>   {
>   	return riscv_cpu_probe();
>   }
> +
> +/**
> + * riscv_hart_early_init() - A dummy function called by
> + * ./arch/riscv/cpu/start.S to allow to disable/enable features of each core.
> + * For example, to turn on or clear chicken bits.

What's a chicken bit?

> + *
> + * This function is executed by each core after stack is initialized and not
> + * expect to access gd since gd is not initialized. All operations in this
> + * function should affect core itself only. In multi-core system, any access
> + * to common resource or registers outside core should be avoided or need a
> + * protection for multicore.

Perhaps just

In a multi-core system, this function must not access shared resources.

Any access to such resources would probably be better done with
available_harts_lock held. However, I doubt that any such access will be
necessary.

--Sean

> + */
> +__weak void riscv_hart_early_init(void)
> +{
> +}
> diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
> index 8589509e01..ab73008f23 100644
> --- a/arch/riscv/cpu/start.S
> +++ b/arch/riscv/cpu/start.S
> @@ -117,6 +117,20 @@ call_board_init_f_0:
>   	mv	sp, a0
>   #endif
>   
> +#if CONFIG_IS_ENABLED(RISCV_MMODE)
> +	/*
> +	 * Jump to riscv_hart_early_init() to perform init for each core. Not
> +	 * expect to access gd since gd is not initialized. All operations in the
> +	 * function should affect core itself only. In multi-core system, any access
> +	 * to common resource or registers outside core should be avoided or need a
> +	 * protection for multicore.
> +	 *
> +	 * A dummy implementation is provided in ./arch/riscv/cpu/cpu.c.
> +	 */
> +call_riscv_hart_early_init:
> +	jal	riscv_hart_early_init
> +#endif
> +
>   #ifndef CONFIG_XIP
>   	/*
>   	 * Pick hart to initialize global data and run U-Boot. The other harts
>
Green Wan March 29, 2021, 3:04 a.m. UTC | #2
On Mon, Mar 29, 2021 at 10:26 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 3/26/21 10:18 PM, Green Wan wrote:
> > Add a callback riscv_hart_early_init() to ./arch/riscv/cpu/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>
> > ---
> >   arch/riscv/cpu/cpu.c   | 15 +++++++++++++++
> >   arch/riscv/cpu/start.S | 14 ++++++++++++++
> >   2 files changed, 29 insertions(+)
> >
> > diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
> > index 85592f5bee..c779a477c7 100644
> > --- a/arch/riscv/cpu/cpu.c
> > +++ b/arch/riscv/cpu/cpu.c
> > @@ -140,3 +140,18 @@ int arch_early_init_r(void)
> >   {
> >       return riscv_cpu_probe();
> >   }
> > +
> > +/**
> > + * riscv_hart_early_init() - A dummy function called by
> > + * ./arch/riscv/cpu/start.S to allow to disable/enable features of each core.
> > + * For example, to turn on or clear chicken bits.
>
> What's a chicken bit?

Perhaps I can rephrase to
"For example, turn on or off the functional block of CPU harts."

Chicken bits are the bit to control the functional blocks of a chip.

>
> > + *
> > + * This function is executed by each core after stack is initialized and not
> > + * expect to access gd since gd is not initialized. All operations in this
> > + * function should affect core itself only. In multi-core system, any access
> > + * to common resource or registers outside core should be avoided or need a
> > + * protection for multicore.
>
> Perhaps just
>
> In a multi-core system, this function must not access shared resources.
>
> Any access to such resources would probably be better done with
> available_harts_lock held. However, I doubt that any such access will be
> necessary.

okay, thanks for revising. will replace it.

>
> --Sean
>
> > + */
> > +__weak void riscv_hart_early_init(void)
> > +{
> > +}
> > diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
> > index 8589509e01..ab73008f23 100644
> > --- a/arch/riscv/cpu/start.S
> > +++ b/arch/riscv/cpu/start.S
> > @@ -117,6 +117,20 @@ call_board_init_f_0:
> >       mv      sp, a0
> >   #endif
> >
> > +#if CONFIG_IS_ENABLED(RISCV_MMODE)
> > +     /*
> > +      * Jump to riscv_hart_early_init() to perform init for each core. Not
> > +      * expect to access gd since gd is not initialized. All operations in the
> > +      * function should affect core itself only. In multi-core system, any access
> > +      * to common resource or registers outside core should be avoided or need a
> > +      * protection for multicore.
> > +      *
> > +      * A dummy implementation is provided in ./arch/riscv/cpu/cpu.c.
> > +      */
> > +call_riscv_hart_early_init:
> > +     jal     riscv_hart_early_init
> > +#endif
> > +
> >   #ifndef CONFIG_XIP
> >       /*
> >        * Pick hart to initialize global data and run U-Boot. The other harts
> >
>
diff mbox series

Patch

diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index 85592f5bee..c779a477c7 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -140,3 +140,18 @@  int arch_early_init_r(void)
 {
 	return riscv_cpu_probe();
 }
+
+/**
+ * riscv_hart_early_init() - A dummy function called by
+ * ./arch/riscv/cpu/start.S to allow to disable/enable features of each core.
+ * For example, to turn on or clear chicken bits.
+ *
+ * This function is executed by each core after stack is initialized and not
+ * expect to access gd since gd is not initialized. All operations in this
+ * function should affect core itself only. In multi-core system, any access
+ * to common resource or registers outside core should be avoided or need a
+ * protection for multicore.
+ */
+__weak void riscv_hart_early_init(void)
+{
+}
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 8589509e01..ab73008f23 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -117,6 +117,20 @@  call_board_init_f_0:
 	mv	sp, a0
 #endif
 
+#if CONFIG_IS_ENABLED(RISCV_MMODE)
+	/*
+	 * Jump to riscv_hart_early_init() to perform init for each core. Not
+	 * expect to access gd since gd is not initialized. All operations in the
+	 * function should affect core itself only. In multi-core system, any access
+	 * to common resource or registers outside core should be avoided or need a
+	 * protection for multicore.
+	 *
+	 * A dummy implementation is provided in ./arch/riscv/cpu/cpu.c.
+	 */
+call_riscv_hart_early_init:
+	jal	riscv_hart_early_init
+#endif
+
 #ifndef CONFIG_XIP
 	/*
 	 * Pick hart to initialize global data and run U-Boot. The other harts