summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnup Patel <apatel@ventanamicro.com>2022-06-16 14:58:56 +0300
committerAnup Patel <anup@brainfault.org>2022-06-21 06:14:45 +0300
commitc6530012d46ed9c9655c426450bfa3aabcc0eadd (patch)
treed43a104f4e2d5151ec7c49a118b046aa6d4c8390 /lib
parenta07402ac9cea19b3af70ed6469bb6d937132a18f (diff)
downloadopensbi-c6530012d46ed9c9655c426450bfa3aabcc0eadd.tar.xz
lib: utils: Remove CSRs that set/clear an IMSIC interrupt file bits
Based on architecture review committee feedback, the [m|s|vs]seteienum, [m|s|vs]clreienum, [m|s|vs]seteipnum, and [m|s|vs]clreipnum CSRs are removed in the latest AIA draft v0.3.0 specification. (Refer, https://github.com/riscv/riscv-aia/releases/tag/0.3.0-draft.31) These CSRs were mostly for software convenience and software can always use [m|s|vs]iselect and [m|s|vs]ireg CSRs to update the IMSIC interrupt file bits. We update the IMSIC programming as-per above to match the latest AIA draft specification. Signed-off-by: Anup Patel <apatel@ventanamicro.com> Reviewed-by: Atish Patra <atishp@rivosinc.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/utils/irqchip/imsic.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/lib/utils/irqchip/imsic.c b/lib/utils/irqchip/imsic.c
index b29a1e9..98f2cb6 100644
--- a/lib/utils/irqchip/imsic.c
+++ b/lib/utils/irqchip/imsic.c
@@ -38,10 +38,14 @@
#define IMSIC_EIP63 0xbf
+#define IMSIC_EIPx_BITS 32
+
#define IMSIC_EIE0 0xc0
#define IMSIC_EIE63 0xff
+#define IMSIC_EIEx_BITS 32
+
#define IMSIC_DISABLE_EIDELIVERY 0
#define IMSIC_ENABLE_EIDELIVERY 1
#define IMSIC_DISABLE_EITHRESHOLD 1
@@ -63,6 +67,18 @@ do { \
__v; \
})
+#define imsic_csr_set(__c, __v) \
+do { \
+ csr_write(CSR_MISELECT, __c); \
+ csr_set(CSR_MIREG, __v); \
+} while (0)
+
+#define imsic_csr_clear(__c, __v) \
+do { \
+ csr_write(CSR_MISELECT, __c); \
+ csr_clear(CSR_MIREG, __v); \
+} while (0)
+
static struct imsic_data *imsic_hartid2data[SBI_HARTMASK_MAX_BITS];
static int imsic_hartid2file[SBI_HARTMASK_MAX_BITS];
@@ -140,6 +156,31 @@ static struct sbi_ipi_device imsic_ipi_device = {
.ipi_send = imsic_ipi_send
};
+static void imsic_local_eix_update(unsigned long base_id,
+ unsigned long num_id, bool pend, bool val)
+{
+ unsigned long i, isel, ireg;
+ unsigned long id = base_id, last_id = base_id + num_id;
+
+ while (id < last_id) {
+ isel = id / __riscv_xlen;
+ isel *= __riscv_xlen / IMSIC_EIPx_BITS;
+ isel += (pend) ? IMSIC_EIP0 : IMSIC_EIE0;
+
+ ireg = 0;
+ for (i = id & (__riscv_xlen - 1);
+ (id < last_id) && (i < __riscv_xlen); i++) {
+ ireg |= BIT(i);
+ id++;
+ }
+
+ if (val)
+ imsic_csr_set(isel, ireg);
+ else
+ imsic_csr_clear(isel, ireg);
+ }
+}
+
void imsic_local_irqchip_init(void)
{
/*
@@ -158,12 +199,11 @@ void imsic_local_irqchip_init(void)
imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVERY);
/* Enable IPI */
- csr_write(CSR_MSETEIENUM, IMSIC_IPI_ID);
+ imsic_local_eix_update(IMSIC_IPI_ID, 1, false, true);
}
int imsic_warm_irqchip_init(void)
{
- unsigned long i;
struct imsic_data *imsic = imsic_hartid2data[current_hartid()];
/* Sanity checks */
@@ -171,11 +211,10 @@ int imsic_warm_irqchip_init(void)
return SBI_EINVAL;
/* Disable all interrupts */
- for (i = 1; i <= imsic->num_ids; i++)
- csr_write(CSR_MCLREIENUM, i);
+ imsic_local_eix_update(1, imsic->num_ids, false, false);
- /* Clear IPI */
- csr_write(CSR_MCLREIPNUM, IMSIC_IPI_ID);
+ /* Clear IPI pending */
+ imsic_local_eix_update(IMSIC_IPI_ID, 1, true, false);
/* Local IMSIC initialization */
imsic_local_irqchip_init();