[U-Boot] [PATCH 1/7] riscv: add infrastructure for calling functions on other harts

Anup Patel anup at brainfault.org
Mon Feb 18 04:58:52 UTC 2019


On Tue, Feb 12, 2019 at 3:44 AM Lukas Auer
<lukas.auer at aisec.fraunhofer.de> wrote:
>
> Harts on RISC-V boot independently and U-Boot is responsible for
> managing them. Functions are called on other harts with
> smp_call_function(), which sends inter-processor interrupts (IPIs) to
> all other harts. Functions are specified with their address and two
> function arguments (argument 2 and 3). The first function argument is
> always the hart ID of the hart calling the function. On the other harts,
> the IPI interrupt handler handle_ipi() must be called on software
> interrupts to handle the request and call the specified function.
>
> Functions are stored in the ipi_data data structure. Every hart has its
> own data structure in global data. While this is not required at the
> moment (all harts are expected to boot Linux), this does allow future
> expansion, where other harts may be used for monitoring or other tasks.
>
> Signed-off-by: Lukas Auer <lukas.auer at aisec.fraunhofer.de>
> ---
>
>  arch/riscv/Kconfig                   |  19 +++++
>  arch/riscv/include/asm/global_data.h |   5 ++
>  arch/riscv/include/asm/smp.h         |  53 +++++++++++++
>  arch/riscv/lib/Makefile              |   1 +
>  arch/riscv/lib/smp.c                 | 110 +++++++++++++++++++++++++++
>  5 files changed, 188 insertions(+)
>  create mode 100644 arch/riscv/include/asm/smp.h
>  create mode 100644 arch/riscv/lib/smp.c
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index c45e4d73a8..c0842178dd 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -116,4 +116,23 @@ config RISCV_RDTIME
>  config SYS_MALLOC_F_LEN
>         default 0x1000
>
> +config SMP
> +       bool "Symmetric Multi-Processing"
> +       help
> +         This enables support for systems with more than one CPU. If
> +         you say N here, U-Boot will run on single and multiprocessor
> +         machines, but will use only one CPU of a multiprocessor
> +         machine. If you say Y here, U-Boot will run on many, but not
> +         all, single processor machines.
> +
> +config NR_CPUS
> +       int "Maximum number of CPUs (2-32)"
> +       range 2 32
> +       depends on SMP
> +       default "8"
> +       help
> +         On multiprocessor machines, U-Boot sets up a stack for each CPU.
> +         Stack memory is pre-allocated. U-Boot must therefore know the
> +         maximum number of CPUs that may be present.
> +
>  endmenu
> diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
> index a3a342c6e1..23a5f35af5 100644
> --- a/arch/riscv/include/asm/global_data.h
> +++ b/arch/riscv/include/asm/global_data.h
> @@ -10,12 +10,17 @@
>  #ifndef        __ASM_GBL_DATA_H
>  #define __ASM_GBL_DATA_H
>
> +#include <asm/smp.h>
> +
>  /* Architecture-specific global data */
>  struct arch_global_data {
>         long boot_hart;         /* boot hart id */
>  #ifdef CONFIG_SIFIVE_CLINT
>         void __iomem *clint;    /* clint base address */
>  #endif
> +#ifdef CONFIG_SMP
> +       struct ipi_data ipi[CONFIG_NR_CPUS];

The data passed by "main HART" via global data to other HARTs
is not visible reliably and randomly few HARTs fail to enter Linux
kernel on my board. I am suspecting per-HART "ipi" data in global
data not being cache-line aligned as the cause of behavior but there
could be other issue too.

I have a hack which works reliable for me. As-per this hack, we add
"mdelay(10)" just before calling riscv_send_ipi() in send_ipi_many().
This hack helped me conclude that there is some sync issue in per-HART
"ipi" data.

The above issue is not seen on QEMU so we are fine there.

I would suggest to make per-HART "ipi" data cache-line aligned
(just like Linux kernel).

Regards,
Anup


More information about the U-Boot mailing list