All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yu Chien Peter Lin <peterlin@andestech.com>
To: opensbi@lists.infradead.org
Subject: [PATCH v3 01/15] lib: ipi: Adjust Andes PLICSW to single-bit-per-hart scheme
Date: Wed, 22 Nov 2023 15:36:03 +0800	[thread overview]
Message-ID: <20231122073617.379441-2-peterlin@andestech.com> (raw)
In-Reply-To: <20231122073617.379441-1-peterlin@andestech.com>

From: Leo Yu-Chi Liang <ycliang@andestech.com>

The old scheme doesn't allow sending hart0 self-IPI as the
corresponding bit on pending register is hardwired to 0, this
could lead to unhandle IPIs on SMP systems, esp. on single-core.

Furthermore, the limitation of old scheme is 8-core, instead of
reserving source hart information, we assign bit (x + 1) as the
enable and pending bit of hartx, this also expands the bootable
hart number.

The following diagram shows the enable bits of the new scheme
on 32-core Andes platform.

   Pending regs: 0x1000  x---0---0---0---0------0---0
Pending hart ID:             0   1   2   3 ... 30  31
   Interrupt ID:         0   1   2   3   4 ... 31  32
                         |   |   |   |   |      |   |
    Enable regs: 0x2000  x---1---0---0---0-...--0---0---> hart0
                         |   |   |   |   |      |   |
                 0x2080  x---0---1---0---0-...--0---0---> hart1
                         |   |   |   |   |      |   |
                 0x2100  x---0---0---1---0-...--0---0---> hart2
                         |   |   |   |   |      |   |
                 0x2180  x---0---0---0---1-...--0---0---> hart3
                         .   .   .   .   .      .   .
                         .   .   .   .   .      .   .
                         .   .   .   .   .      .   .
                 0x2f00  x---0---0---0---0-...--1---0---> hart30
                         |   |   |   |   |      |   |
                 0x2f80  x---0---0---0---0-...--0---1---> hart31
                         <-------- word 0 -------><--- word 1 --->

To send IPI to hart0, for example, another hart (including hart0
itself) will set bit 1 of first word on the pending register.

We also fix indentation in andes_plicsw.h along with this patch.

Fixes: ce7c490719ed ("lib: utils/ipi: Add Andes fdt ipi driver support")
Signed-off-by: Leo Yu-Chi Liang <ycliang@andestech.com>
Reviewed-by: Yu Chien Peter Lin <peterlin@andestech.com>
Reviewed-by: Randolph <randolph@andestech.com>
Reported-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Link: https://lists.infradead.org/pipermail/opensbi/2023-October/005665.html
---
Changes v2 -> v3:
  - New patch
---
 include/sbi_utils/ipi/andes_plicsw.h |  23 +++---
 lib/utils/ipi/andes_plicsw.c         | 104 ++++++++++-----------------
 2 files changed, 46 insertions(+), 81 deletions(-)

diff --git a/include/sbi_utils/ipi/andes_plicsw.h b/include/sbi_utils/ipi/andes_plicsw.h
index e93cda0..0d18444 100644
--- a/include/sbi_utils/ipi/andes_plicsw.h
+++ b/include/sbi_utils/ipi/andes_plicsw.h
@@ -13,30 +13,23 @@
 #ifndef _IPI_ANDES_PLICSW_H_
 #define _IPI_ANDES_PLICSW_H_
 
-#define PLICSW_PRIORITY_BASE 0x4
+#define PLICSW_PRIORITY_BASE	0x4
 
-#define PLICSW_PENDING_BASE 0x1000
-#define PLICSW_PENDING_STRIDE 0x8
+#define PLICSW_PENDING_BASE	0x1000
 
-#define PLICSW_ENABLE_BASE 0x2000
-#define PLICSW_ENABLE_STRIDE 0x80
+#define PLICSW_ENABLE_BASE	0x2000
+#define PLICSW_ENABLE_STRIDE	0x80
 
-#define PLICSW_CONTEXT_BASE 0x200000
-#define PLICSW_CONTEXT_STRIDE 0x1000
-#define PLICSW_CONTEXT_CLAIM 0x4
+#define PLICSW_CONTEXT_BASE	0x200000
+#define PLICSW_CONTEXT_STRIDE	0x1000
+#define PLICSW_CONTEXT_CLAIM	0x4
 
-#define PLICSW_HART_MASK 0x01010101
-
-#define PLICSW_HART_MAX_NR 8
-
-#define PLICSW_REGION_ALIGN 0x1000
+#define PLICSW_REGION_ALIGN	0x1000
 
 struct plicsw_data {
 	unsigned long addr;
 	unsigned long size;
 	uint32_t hart_count;
-	/* hart id to source id table */
-	uint32_t source_id[PLICSW_HART_MAX_NR];
 };
 
 int plicsw_warm_ipi_init(void);
diff --git a/lib/utils/ipi/andes_plicsw.c b/lib/utils/ipi/andes_plicsw.c
index 5693efb..413ac20 100644
--- a/lib/utils/ipi/andes_plicsw.c
+++ b/lib/utils/ipi/andes_plicsw.c
@@ -18,77 +18,45 @@
 
 struct plicsw_data plicsw;
 
-static inline void plicsw_claim(void)
+static void plicsw_ipi_send(u32 hart_index)
 {
-	u32 hartid = current_hartid();
+	ulong pending_reg;
+	u32 interrupt_id, word_index, pending_bit;
+	u32 target_hart = sbi_hartindex_to_hartid(hart_index);
 
-	if (plicsw.hart_count <= hartid)
+	if (plicsw.hart_count <= target_hart)
 		ebreak();
 
-	plicsw.source_id[hartid] =
-		readl((void *)plicsw.addr + PLICSW_CONTEXT_BASE +
-		      PLICSW_CONTEXT_CLAIM + PLICSW_CONTEXT_STRIDE * hartid);
-}
-
-static inline void plicsw_complete(void)
-{
-	u32 hartid = current_hartid();
-	u32 source = plicsw.source_id[hartid];
-
-	writel(source, (void *)plicsw.addr + PLICSW_CONTEXT_BASE +
-			       PLICSW_CONTEXT_CLAIM +
-			       PLICSW_CONTEXT_STRIDE * hartid);
-}
-
-static inline void plic_sw_pending(u32 target_hart)
-{
 	/*
-	 * The pending array registers are w1s type.
-	 * IPI pending array mapping as following:
-	 *
-	 * Pending array start address: base + 0x1000
-	 * ---------------------------------
-	 * | hart3 | hart2 | hart1 | hart0 |
-	 * ---------------------------------
-	 * Each hartX can send IPI to another hart by setting the
-	 * bitY to its own region (see the below).
-	 *
-	 * In each hartX region:
-	 * <---------- PICSW_PENDING_STRIDE -------->
-	 * | bit7 | ... | bit3 | bit2 | bit1 | bit0 |
-	 * ------------------------------------------
-	 * The bitY of hartX region indicates that hartX sends an
-	 * IPI to hartY.
+	 * We assign a single bit for each hart.
+	 * Bit 0 is hardwired to 0, thus unavailable.
+	 * Bit(X+1) indicates that IPI is sent to hartX.
 	 */
-	u32 hartid	    = current_hartid();
-	u32 word_index	    = hartid / 4;
-	u32 per_hart_offset = PLICSW_PENDING_STRIDE * hartid;
-	u32 val		    = 1 << target_hart << per_hart_offset;
+	interrupt_id = target_hart + 1;
+	word_index   = interrupt_id / 32;
+	pending_bit  = interrupt_id % 32;
+	pending_reg  = plicsw.addr + PLICSW_PENDING_BASE + word_index * 4;
 
-	writel(val, (void *)plicsw.addr + PLICSW_PENDING_BASE + word_index * 4);
+	/* Set target hart's mip.MSIP */
+	writel_relaxed(BIT(pending_bit), (void *)pending_reg);
 }
 
-static void plicsw_ipi_send(u32 hart_index)
+static void plicsw_ipi_clear(u32 hart_index)
 {
 	u32 target_hart = sbi_hartindex_to_hartid(hart_index);
+	ulong reg = plicsw.addr + PLICSW_CONTEXT_BASE + PLICSW_CONTEXT_CLAIM +
+		    PLICSW_CONTEXT_STRIDE * target_hart;
 
 	if (plicsw.hart_count <= target_hart)
 		ebreak();
 
-	/* Set PLICSW IPI */
-	plic_sw_pending(target_hart);
-}
+	/* Claim */
+	u32 source = readl((void *)reg);
 
-static void plicsw_ipi_clear(u32 hart_index)
-{
-	u32 target_hart = sbi_hartindex_to_hartid(hart_index);
-
-	if (plicsw.hart_count <= target_hart)
-		ebreak();
+	/* A successful claim will clear mip.MSIP */
 
-	/* Clear PLICSW IPI */
-	plicsw_claim();
-	plicsw_complete();
+	/* Complete */
+	writel(source, (void *)reg);
 }
 
 static struct sbi_ipi_device plicsw_ipi = {
@@ -110,22 +78,26 @@ int plicsw_warm_ipi_init(void)
 int plicsw_cold_ipi_init(struct plicsw_data *plicsw)
 {
 	int rc;
+	u32 interrupt_id, word_index, enable_bit;
+	ulong enable_reg, priority_reg;
 
 	/* Setup source priority */
-	uint32_t *priority = (void *)plicsw->addr + PLICSW_PRIORITY_BASE;
-
-	for (int i = 0; i < plicsw->hart_count; i++)
-		writel(1, &priority[i]);
-
-	/* Setup target enable */
-	uint32_t enable_mask = PLICSW_HART_MASK;
+	for (int i = 0; i < plicsw->hart_count; i++) {
+		priority_reg = plicsw->addr + PLICSW_PRIORITY_BASE + i * 4;
+		writel(1, (void *)priority_reg);
+	}
 
+	/*
+	 * Setup enable for each hart, skip non-existent interrupt ID 0
+	 * which is hardwired to 0.
+	 */
 	for (int i = 0; i < plicsw->hart_count; i++) {
-		uint32_t *enable = (void *)plicsw->addr + PLICSW_ENABLE_BASE +
-				   PLICSW_ENABLE_STRIDE * i;
-		writel(enable_mask, enable);
-		writel(enable_mask, enable + 1);
-		enable_mask <<= 1;
+		interrupt_id = i + 1;
+		word_index   = interrupt_id / 32;
+		enable_bit   = interrupt_id % 32;
+		enable_reg   = plicsw->addr + PLICSW_ENABLE_BASE +
+			       PLICSW_ENABLE_STRIDE * i + 4 * word_index;
+		writel(BIT(enable_bit), (void *)enable_reg);
 	}
 
 	/* Add PLICSW region to the root domain */
-- 
2.34.1



  reply	other threads:[~2023-11-22  7:36 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-22  7:36 [PATCH v3 00/15] Add Andes PMU extension support Yu Chien Peter Lin
2023-11-22  7:36 ` Yu Chien Peter Lin [this message]
2023-11-24 14:43   ` [PATCH v3 01/15] lib: ipi: Adjust Andes PLICSW to single-bit-per-hart scheme Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 02/15] sbi: sbi_pmu: Improve sbi_pmu_init() error handling Yu Chien Peter Lin
2023-11-22 23:47   ` Atish Patra
2023-11-28  5:33     ` Yu-Chien Peter Lin
2023-11-24 14:45   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 03/15] lib: sbi: Add Xandespmu in hart extensions Yu Chien Peter Lin
2023-11-23  0:02   ` Atish Patra
2023-11-24 14:45   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 04/15] sbi: sbi_pmu: Add hw_counter_filter_mode() to pmu device Yu Chien Peter Lin
2023-11-23  0:24   ` Atish Patra
2023-11-28  6:10     ` Yu-Chien Peter Lin
2023-11-22  7:36 ` [PATCH v3 05/15] platform: include: andes45: Add PMU related CSR defines Yu Chien Peter Lin
2023-11-23 16:53   ` Atish Patra
2023-11-24 14:47   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 06/15] platform: generic: Introduce pmu_init() platform override Yu Chien Peter Lin
2023-11-23  0:25   ` Atish Patra
2023-11-24 14:49   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 07/15] platform: andes: Add Andes custom PMU support Yu Chien Peter Lin
2023-11-23  2:24   ` Samuel Holland
2023-11-28 11:02     ` Yu-Chien Peter Lin
2023-11-22  7:36 ` [PATCH v3 08/15] platform: andes: Enable Andes PMU for AE350 Yu Chien Peter Lin
2023-11-23 16:55   ` Atish Patra
2023-11-24 14:52   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 09/15] platform: rzfive: Enable Andes PMU for RZ/Five Yu Chien Peter Lin
2023-11-23 16:56   ` Atish Patra
2023-11-24 14:53   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 10/15] lib: utils: fdt_fixup: Allow preserving PMU properties Yu Chien Peter Lin
2023-11-22 23:41   ` Atish Patra
2023-11-24 14:54   ` Lad, Prabhakar
2023-11-25  4:42   ` Anup Patel
2023-11-28  9:57     ` Yu-Chien Peter Lin
2023-11-22  7:36 ` [PATCH v3 11/15] platform: andes: Factor out is_andes() helper Yu Chien Peter Lin
2023-11-22  7:36 ` [PATCH v3 12/15] lib: utils: fdt_pmu: Make the fdt_pmu_evt_select table global variable Yu Chien Peter Lin
2023-11-22  7:36 ` [PATCH v3 13/15] lib: utils: fdt_pmu: Do not iterate over the fdt_pmu_evt_select table Yu Chien Peter Lin
2023-11-22  7:36 ` [PATCH v3 14/15] platform: andes: Add Andes default PMU mapping support Yu Chien Peter Lin
2023-11-24 14:55   ` Lad, Prabhakar
2023-11-22  7:36 ` [PATCH v3 15/15] docs: pmu: Add Andes PMU node example Yu Chien Peter Lin
2023-11-24 14:56   ` Lad, Prabhakar
2023-11-23  0:07 ` [PATCH v3 00/15] Add Andes PMU extension support Atish Patra
2023-11-23  0:27   ` Atish Patra
2023-11-28  5:23     ` Yu-Chien Peter Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231122073617.379441-2-peterlin@andestech.com \
    --to=peterlin@andestech.com \
    --cc=opensbi@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.