Hi Lukas > From: Lukas Auer [mailto:lukas.a...@aisec.fraunhofer.de] > Sent: Wednesday, December 04, 2019 5:40 AM > To: u-boot@lists.denx.de > Cc: Rick Jian-Zhi Chen(陳建志); Anup Patel; Bin Meng; Lukas Auer; Anup Patel; > Atish Patra > Subject: [PATCH 2/4] riscv: add functions for reading the IPI status > > Add the function riscv_get_ipi() for reading the pending status of IPIs. > The supported controllers are Andes' Platform Level Interrupt Controller > (PLIC), the Supervisor Binary Interface (SBI), and SiFive's Core Local > Interruptor (CLINT). > > Signed-off-by: Lukas Auer <lukas.a...@aisec.fraunhofer.de> > --- > I do not have access to the datasheet of the Andes PLIC. The > riscv_clear_ipi() implementation seems to read the IPI status from the claim > register before writing back the results to clear them. Based on this, I also > used the claim register. Rick, please let me know if that is ok or if I > should use the pending register instead.
Yes. Please use pending register instead of claim register. Thanks Rick > > arch/riscv/lib/andes_plic.c | 9 +++++++++ > arch/riscv/lib/sbi_ipi.c | 11 +++++++++++ > arch/riscv/lib/sifive_clint.c | 9 +++++++++ > arch/riscv/lib/smp.c | 12 ++++++++++++ > 4 files changed, 41 insertions(+) > > diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c index > 28568e4e2b..731ac3a148 100644 > --- a/arch/riscv/lib/andes_plic.c > +++ b/arch/riscv/lib/andes_plic.c > @@ -114,6 +114,15 @@ int riscv_clear_ipi(int hart) > return 0; > } > > +int riscv_get_ipi(int hart, int *pending) { > + PLIC_BASE_GET(); > + > + *pending = !!readl((void __iomem *)CLAIM_REG(gd->arch.plic, hart)); > + > + return 0; > +} > + > static const struct udevice_id andes_plic_ids[] = { > { .compatible = "riscv,plic1", .data = RISCV_SYSCON_PLIC }, > { } > diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c index > 170346da68..9a698ce74e 100644 > --- a/arch/riscv/lib/sbi_ipi.c > +++ b/arch/riscv/lib/sbi_ipi.c > @@ -23,3 +23,14 @@ int riscv_clear_ipi(int hart) > > return 0; > } > + > +int riscv_get_ipi(int hart, int *pending) { > + /* > + * The SBI does not support reading the IPI status. We always return 0 > + * to indicate that no IPI is pending. > + */ > + *pending = 0; > + > + return 0; > +} > diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c > index d24e0d585b..d7899d16d7 100644 > --- a/arch/riscv/lib/sifive_clint.c > +++ b/arch/riscv/lib/sifive_clint.c > @@ -71,6 +71,15 @@ int riscv_clear_ipi(int hart) > return 0; > } > > +int riscv_get_ipi(int hart, int *pending) { > + CLINT_BASE_GET(); > + > + *pending = readl((void __iomem *)MSIP_REG(gd->arch.clint, hart)); > + > + return 0; > +} > + > static const struct udevice_id sifive_clint_ids[] = { > { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT }, > { } > diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index > cc66f15567..6ff0de4b74 100644 > --- a/arch/riscv/lib/smp.c > +++ b/arch/riscv/lib/smp.c > @@ -31,6 +31,18 @@ extern int riscv_send_ipi(int hart); > */ > extern int riscv_clear_ipi(int hart); > > +/** > + * riscv_get_ipi() - Get status of inter-processor interrupt (IPI) > + * > + * Platform code must provide this function. > + * > + * @hart: Hart ID of hart to be checked > + * @pending: Pointer to variable with result of the check, > + * 1 if IPI is pending, 0 otherwise > + * @return 0 if OK, -ve on error > + */ > +extern int riscv_get_ipi(int hart, int *pending); > + > static int send_ipi_many(struct ipi_data *ipi) { > ofnode node, cpus; > -- > 2.21.0 >