[PATCH 08/13] lib: utils/irqchip: Add IMSIC library
Jessica Clarke
jrtc27 at jrtc27.com
Wed Jan 19 08:12:36 PST 2022
On 19 Jan 2022, at 16:08, Xiang W <wxjstz at 126.com> wrote:
>
> 在 2022-01-04星期二的 15:43 +0530,Anup Patel写道:
>> We add simple IMSIC library which is independent of hardware
>> description
>> format (FDT or ACPI). This IMSIC library can be used by custom OpenSBI
>> platform support to setup IMSIC for external interrupts.
>>
>> Signed-off-by: Anup Patel <anup.patel at wdc.com>
>> Signed-off-by: Anup Patel <apatel at ventanamicro.com>
>> ---
>> include/sbi_utils/irqchip/imsic.h | 50 ++++++
>> lib/utils/irqchip/imsic.c | 287
>> ++++++++++++++++++++++++++++++
>> lib/utils/irqchip/objects.mk | 1 +
>> 3 files changed, 338 insertions(+)
>> create mode 100644 include/sbi_utils/irqchip/imsic.h
>> create mode 100644 lib/utils/irqchip/imsic.c
>>
>> diff --git a/include/sbi_utils/irqchip/imsic.h
>> b/include/sbi_utils/irqchip/imsic.h
>> new file mode 100644
>> index 0000000..cffcb5a
>> --- /dev/null
>> +++ b/include/sbi_utils/irqchip/imsic.h
>> @@ -0,0 +1,50 @@
>> +/*
>> + * SPDX-License-Identifier: BSD-2-Clause
>> + *
>> + * Copyright (c) 2021 Western Digital Corporation or its affiliates.
>> + * Copyright (c) 2022 Ventana Micro Systems Inc.
>> + *
>> + * Authors:
>> + * Anup Patel <anup.patel at wdc.com>
>> + */
>> +
>> +#ifndef __IRQCHIP_IMSIC_H__
>> +#define __IRQCHIP_IMSIC_H__
>> +
>> +#include <sbi/sbi_types.h>
>> +
>> +#define IMSIC_MMIO_PAGE_SHIFT 12
>> +#define IMSIC_MMIO_PAGE_SZ (1UL << IMSIC_MMIO_PAGE_SHIFT)
>> +
>> +#define IMSIC_MAX_REGS 16
>> +
>> +struct imsic_regs {
>> + unsigned long addr;
>> + unsigned long size;
>> +};
>> +
>> +struct imsic_data {
>> + bool targets_mmode;
>> + u32 guest_index_bits;
>> + u32 hart_index_bits;
>> + u32 group_index_bits;
>> + u32 group_index_shift;
>> + unsigned long num_ids;
>> + struct imsic_regs regs[IMSIC_MAX_REGS];
>> +};
>> +
>> +int imsic_map_hartid_to_data(u32 hartid, struct imsic_data *imsic,
>> int file);
>> +
>> +struct imsic_data *imsic_get_data(u32 hartid);
>> +
>> +int imsic_get_target_file(u32 hartid);
>> +
>> +void imsic_local_irqchip_init(void);
>> +
>> +int imsic_warm_irqchip_init(void);
>> +
>> +int imsic_data_check(struct imsic_data *imsic);
>> +
>> +int imsic_cold_irqchip_init(struct imsic_data *imsic);
>> +
>> +#endif
>> diff --git a/lib/utils/irqchip/imsic.c b/lib/utils/irqchip/imsic.c
>> new file mode 100644
>> index 0000000..f87321f
>> --- /dev/null
>> +++ b/lib/utils/irqchip/imsic.c
>> @@ -0,0 +1,287 @@
>> +/*
>> + * SPDX-License-Identifier: BSD-2-Clause
>> + *
>> + * Copyright (c) 2021 Western Digital Corporation or its affiliates.
>> + * Copyright (c) 2022 Ventana Micro Systems Inc.
>> + *
>> + * Authors:
>> + * Anup Patel <anup.patel at wdc.com>
>> + */
>> +
>> +#include <sbi/riscv_asm.h>
>> +#include <sbi/riscv_io.h>
>> +#include <sbi/riscv_encoding.h>
>> +#include <sbi/sbi_console.h>
>> +#include <sbi/sbi_domain.h>
>> +#include <sbi/sbi_hartmask.h>
>> +#include <sbi/sbi_ipi.h>
>> +#include <sbi/sbi_error.h>
>> +#include <sbi/sbi_trap.h>
>> +#include <sbi_utils/irqchip/imsic.h>
>> +
>> +#define IMSIC_MMIO_PAGE_LE 0x00
>> +#define IMSIC_MMIO_PAGE_BE 0x04
>> +
>> +#define IMSIC_MIN_ID 63
>> +#define IMSIC_MAX_ID 2047
>> +
>> +#define IMSIC_EIDELIVERY 0x70
>> +
>> +#define IMSIC_EITHRESHOLD 0x72
>> +
>> +#define IMSIC_TOPEI 0x76
>> +#define IMSIC_TOPEI_ID_SHIFT 16
>> +#define IMSIC_TOPEI_ID_MASK 0x7ff
>> +#define IMSIC_TOPEI_PRIO_MASK 0x7ff
>> +
>> +#define IMSIC_EIP0 0x80
>> +
>> +#define IMSIC_EIP63 0xbf
>> +
>> +#define IMSIC_EIE0 0xc0
>> +
>> +#define IMSIC_EIE63 0xff
>> +
>> +#define IMSIC_DISABLE_EIDELIVERY 0
>> +#define IMSIC_ENABLE_EIDELIVERY 1
>> +#define IMSIC_DISABLE_EITHRESHOLD 0
>> +#define IMSIC_ENABLE_EITHRESHOLD IMSIC_MAX_ID
>> +
>> +#define IMSIC_IPI_ID 1
>> +
>> +#define imsic_csr_write(__c, __v) \
>> +do { \
>> + csr_write(CSR_MISELECT, __c); \
>> + csr_write(CSR_MIREG, __v); \
>> +} while (0)
>> +
>> +#define imsic_csr_read(__c) \
>> +({ \
>> + unsigned long __v; \
>> + csr_write(CSR_MISELECT, __c); \
>> + __v = csr_read(CSR_MIREG); \
>> + __v; \
>> +})
>> +
>> +static struct imsic_data *imsic_hartid2data[SBI_HARTMASK_MAX_BITS];
>> +static int imsic_hartid2file[SBI_HARTMASK_MAX_BITS];
>> +
>> +int imsic_map_hartid_to_data(u32 hartid, struct imsic_data *imsic,
>> int file)
>> +{
>> + if (!imsic || !imsic->targets_mmode ||
>> + (SBI_HARTMASK_MAX_BITS <= hartid))
>> + return SBI_EINVAL;
>> +
>> + imsic_hartid2data[hartid] = imsic;
>> + imsic_hartid2file[hartid] = file;
>> + return 0;
>> +}
>> +
>> +struct imsic_data *imsic_get_data(u32 hartid)
>> +{
>> + if (SBI_HARTMASK_MAX_BITS <= hartid)
>> + return NULL;
>> + return imsic_hartid2data[hartid];
>> +}
>> +
>> +int imsic_get_target_file(u32 hartid)
>> +{
>> + if ((SBI_HARTMASK_MAX_BITS <= hartid) ||
>> + !imsic_hartid2data[hartid])
>> + return SBI_ENOENT;
>> + return imsic_hartid2file[hartid];
>> +}
>> +
>> +static int imsic_external_irqfn(struct sbi_trap_regs *regs)
>> +{
>> + ulong mirq;
>> +
>> + while ((mirq = csr_swap(CSR_MTOPEI, 0))) {
>> + mirq = (mirq >> IMSIC_TOPEI_ID_SHIFT);
>> +
>> + switch (mirq) {
>> + case IMSIC_IPI_ID:
>> + sbi_ipi_process();
>> + break;
> Why not add a timer interrupt?
>> + default:
>> + sbi_printf("%s: unhandled IRQ%d\n",
>> + __func__, (u32)mirq);
>> + break;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void imsic_ipi_send(u32 target_hart)
>> +{
>> + unsigned long reloff;
>> + struct imsic_regs *regs;
>> + struct imsic_data *data = imsic_hartid2data[target_hart];
>> + int file = imsic_hartid2file[target_hart];
>> +
>> + if (!data || !data->targets_mmode)
>> + return;
>> +
>> + regs = &data->regs[0];
>> + reloff = file * (1UL << data->guest_index_bits) *
>> IMSIC_MMIO_PAGE_SZ;
>> + while (regs->size && (regs->size <= reloff)) {
>> + reloff -= regs->size;
>> + regs++;
>> + }
>> +
>> + if (regs->size && (reloff < regs->size))
>> + writel(IMSIC_IPI_ID,
>> + (void *)(regs->addr + reloff +
>> IMSIC_MMIO_PAGE_LE));
> Using "void *" in arithmetic causes errors with -Werror=pointer-arith
The cast is outside the parentheses, the arithmetic happens first.
Jess
More information about the opensbi
mailing list