arch/risc-v: introduce AIA support

Advanced Interrupt Architecture (AIA) introduces flexiable interrupt
controll for RISC-V. It includes three parts: AIA CSRs, Incoming Message
Signaled Interrupt Controller (IMSIC) and  Advanced Platform-Level
Interrupt Controller (APLIC).

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
This commit is contained in:
Inochi Amaoto 2024-05-12 20:15:58 +08:00 committed by Alan Carvalho de Assis
parent 780366de62
commit 5f70307111
9 changed files with 674 additions and 0 deletions

View File

@ -553,6 +553,30 @@ config ARCH_RV_EXT_SSTC
default n default n
depends on ARCH_USE_S_MODE depends on ARCH_USE_S_MODE
config ARCH_RV_HAVE_APLIC
bool "Enable RISC-V Advanced Platform-Level Interrupt Controller support"
default n
---help---
Instead of PLIC, RISC-V also defines Advanced Platform-Level Interrupt
Controller (APLIC) to provide flexible interrupt control. This device
is not backward compatible with PLIC.
config ARCH_RV_EXT_AIA
bool "Enable RISC-V SxAIA support"
default n
---help---
Advanced Interrupt Architecture defines necessary features that
impact the ISA at a hart. This should not be selected if the
target does not support SxAIA for the operating mode of NuttX.
if ARCH_RV_EXT_AIA
config ARCH_RV_HAVE_IMSIC
bool "Enable RISC-V AIA Incoming Message Controller support"
default n
endif # ARCH_RV_EXT_AIA
choice choice
prompt "Toolchain Selection" prompt "Toolchain Selection"
default RISCV_TOOLCHAIN_GNU_RV64 default RISCV_TOOLCHAIN_GNU_RV64

View File

@ -390,6 +390,31 @@
#define MISELECT_CLICINTIE 0x1400 /* MIREG2 */ #define MISELECT_CLICINTIE 0x1400 /* MIREG2 */
#define MISELECT_CLICINTTRIG 0x1480 /* MIREG */ #define MISELECT_CLICINTTRIG 0x1480 /* MIREG */
/* AIA Machine-Level CSRs */
#define CSR_MTOPEI 0x35c /* Machine top external interrupt */
#define CSR_MTOPI 0xfb0 /* Machine top interrupt */
#define CSR_MVIEN 0x308 /* Machine virtual interrupt enables */
#define CSR_MVIP 0x309 /* Machine virtual interrupt-pending bits */
/* AIA Machine-Level CSRs (High-Half) */
#define CSR_MIDELEGH 0x313
#define CSR_MIEH 0x314
#define CSR_MVIENH 0x318
#define CSR_MVIPH 0x319
#define CSR_MIPH 0x354
/* AIA Supervisor-Level CSRs */
#define CSR_STOPEI 0x15c /* Supervisor top external interrupt */
#define CSR_STOPI 0xdb0 /* Supervisor top interrupt */
/* AIA Supervisor-Level CSRs (High-Half) */
#define CSR_SIEH 0x114
#define CSR_SIPH 0x154
/* In mstatus register */ /* In mstatus register */
#define MSTATUS_UIE (0x1 << 0) /* User Interrupt Enable */ #define MSTATUS_UIE (0x1 << 0) /* User Interrupt Enable */
@ -554,6 +579,161 @@
#define COUNTEREN_HPM30 (0x1 << 30) #define COUNTEREN_HPM30 (0x1 << 30)
#define COUNTEREN_HPM31 (0x1 << 31) #define COUNTEREN_HPM31 (0x1 << 31)
/* In topi/topei register */
#define TOPI_IID_SHIFT 16
#define TOPI_IPRIO_BITS 8
#define TOPEI_ID_SHIFT 16
/* In iselect register (AIA) */
#define ISELECT_IPRIO0 0x30
#define ISELECT_IPRIO1 0x31
#define ISELECT_IPRIO2 0x32
#define ISELECT_IPRIO3 0x33
#define ISELECT_IPRIO4 0x34
#define ISELECT_IPRIO5 0x35
#define ISELECT_IPRIO6 0x36
#define ISELECT_IPRIO7 0x37
#define ISELECT_IPRIO8 0x38
#define ISELECT_IPRIO9 0x39
#define ISELECT_IPRIO10 0x3a
#define ISELECT_IPRIO11 0x3b
#define ISELECT_IPRIO12 0x3c
#define ISELECT_IPRIO13 0x3d
#define ISELECT_IPRIO14 0x3e
#define ISELECT_IPRIO15 0x3f
#define ISELECT_EIDELIVERY 0x70
#define ISELECT_EITHRESHOLD 0x72
#define ISELECT_EIP0 0x80
#define ISELECT_EIP1 0x81
#define ISELECT_EIP2 0x82
#define ISELECT_EIP3 0x83
#define ISELECT_EIP4 0x84
#define ISELECT_EIP5 0x85
#define ISELECT_EIP6 0x86
#define ISELECT_EIP7 0x87
#define ISELECT_EIP8 0x88
#define ISELECT_EIP9 0x89
#define ISELECT_EIP10 0x8a
#define ISELECT_EIP11 0x8b
#define ISELECT_EIP12 0x8c
#define ISELECT_EIP13 0x8d
#define ISELECT_EIP14 0x8e
#define ISELECT_EIP15 0x8f
#define ISELECT_EIP16 0x90
#define ISELECT_EIP17 0x91
#define ISELECT_EIP18 0x92
#define ISELECT_EIP19 0x93
#define ISELECT_EIP20 0x94
#define ISELECT_EIP21 0x95
#define ISELECT_EIP22 0x96
#define ISELECT_EIP23 0x97
#define ISELECT_EIP24 0x98
#define ISELECT_EIP25 0x99
#define ISELECT_EIP26 0x9a
#define ISELECT_EIP27 0x9b
#define ISELECT_EIP28 0x9c
#define ISELECT_EIP29 0x9d
#define ISELECT_EIP30 0x9e
#define ISELECT_EIP31 0x9f
#define ISELECT_EIP32 0xa0
#define ISELECT_EIP33 0xa1
#define ISELECT_EIP34 0xa2
#define ISELECT_EIP35 0xa3
#define ISELECT_EIP36 0xa4
#define ISELECT_EIP37 0xa5
#define ISELECT_EIP38 0xa6
#define ISELECT_EIP39 0xa7
#define ISELECT_EIP40 0xa8
#define ISELECT_EIP41 0xa9
#define ISELECT_EIP42 0xaa
#define ISELECT_EIP43 0xab
#define ISELECT_EIP44 0xac
#define ISELECT_EIP45 0xad
#define ISELECT_EIP46 0xae
#define ISELECT_EIP47 0xaf
#define ISELECT_EIP48 0xb0
#define ISELECT_EIP49 0xb1
#define ISELECT_EIP50 0xb2
#define ISELECT_EIP51 0xb3
#define ISELECT_EIP52 0xb4
#define ISELECT_EIP53 0xb5
#define ISELECT_EIP54 0xb6
#define ISELECT_EIP55 0xb7
#define ISELECT_EIP56 0xb8
#define ISELECT_EIP57 0xb9
#define ISELECT_EIP58 0xba
#define ISELECT_EIP59 0xbb
#define ISELECT_EIP60 0xbc
#define ISELECT_EIP61 0xbd
#define ISELECT_EIP62 0xbe
#define ISELECT_EIP63 0xbf
#define ISELECT_EIE0 0xc0
#define ISELECT_EIE1 0xc1
#define ISELECT_EIE2 0xc2
#define ISELECT_EIE3 0xc3
#define ISELECT_EIE4 0xc4
#define ISELECT_EIE5 0xc5
#define ISELECT_EIE6 0xc6
#define ISELECT_EIE7 0xc7
#define ISELECT_EIE8 0xc8
#define ISELECT_EIE9 0xc9
#define ISELECT_EIE10 0xca
#define ISELECT_EIE11 0xcb
#define ISELECT_EIE12 0xcc
#define ISELECT_EIE13 0xcd
#define ISELECT_EIE14 0xce
#define ISELECT_EIE15 0xcf
#define ISELECT_EIE16 0xd0
#define ISELECT_EIE17 0xd1
#define ISELECT_EIE18 0xd2
#define ISELECT_EIE19 0xd3
#define ISELECT_EIE20 0xd4
#define ISELECT_EIE21 0xd5
#define ISELECT_EIE22 0xd6
#define ISELECT_EIE23 0xd7
#define ISELECT_EIE24 0xd8
#define ISELECT_EIE25 0xd9
#define ISELECT_EIE26 0xda
#define ISELECT_EIE27 0xdb
#define ISELECT_EIE28 0xdc
#define ISELECT_EIE29 0xdd
#define ISELECT_EIE30 0xde
#define ISELECT_EIE31 0xdf
#define ISELECT_EIE32 0xe0
#define ISELECT_EIE33 0xe1
#define ISELECT_EIE34 0xe2
#define ISELECT_EIE35 0xe3
#define ISELECT_EIE36 0xe4
#define ISELECT_EIE37 0xe5
#define ISELECT_EIE38 0xe6
#define ISELECT_EIE39 0xe7
#define ISELECT_EIE40 0xe8
#define ISELECT_EIE41 0xe9
#define ISELECT_EIE42 0xea
#define ISELECT_EIE43 0xeb
#define ISELECT_EIE44 0xec
#define ISELECT_EIE45 0xed
#define ISELECT_EIE46 0xee
#define ISELECT_EIE47 0xef
#define ISELECT_EIE48 0xf0
#define ISELECT_EIE49 0xf1
#define ISELECT_EIE50 0xf2
#define ISELECT_EIE51 0xf3
#define ISELECT_EIE52 0xf4
#define ISELECT_EIE53 0xf5
#define ISELECT_EIE54 0xf6
#define ISELECT_EIE55 0xf7
#define ISELECT_EIE56 0xf8
#define ISELECT_EIE57 0xf9
#define ISELECT_EIE58 0xfa
#define ISELECT_EIE59 0xfb
#define ISELECT_EIE60 0xfc
#define ISELECT_EIE61 0xfd
#define ISELECT_EIE62 0xfe
#define ISELECT_EIE63 0xff
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/

View File

@ -45,6 +45,12 @@
# define CSR_TVAL CSR_STVAL /* Trap value register */ # define CSR_TVAL CSR_STVAL /* Trap value register */
# define CSR_TVEC CSR_STVEC /* Trap vector base addr register */ # define CSR_TVEC CSR_STVEC /* Trap vector base addr register */
# define CSR_ENVCFG CSR_SENVCFG /* Env configuration register */ # define CSR_ENVCFG CSR_SENVCFG /* Env configuration register */
# define CSR_IEH CSR_SIEH
# define CSR_ISELECT CSR_SISELECT /* Indirect select register */
# define CSR_IREG CSR_SIREG /* Indirect alias register */
# define CSR_IPH CSR_SIPH
# define CSR_TOPEI CSR_STOPEI /* Top external interrupt register */
# define CSR_TOPI CSR_STOPI /* Top interrupt register */
/* In status register */ /* In status register */
@ -88,6 +94,12 @@
# define CSR_TVAL CSR_MTVAL /* Trap value register */ # define CSR_TVAL CSR_MTVAL /* Trap value register */
# define CSR_TVEC CSR_MTVEC /* Trap vector base addr register */ # define CSR_TVEC CSR_MTVEC /* Trap vector base addr register */
# define CSR_ENVCFG CSR_MENVCFG /* Env configuration register */ # define CSR_ENVCFG CSR_MENVCFG /* Env configuration register */
# define CSR_IEH CSR_MIEH
# define CSR_ISELECT CSR_MISELECT /* Indirect select register */
# define CSR_IREG CSR_MIREG /* Indirect alias register */
# define CSR_IPH CSR_MIPH
# define CSR_TOPEI CSR_MTOPEI /* Top external interrupt register */
# define CSR_TOPI CSR_MTOPI /* Top interrupt register */
/* In status register */ /* In status register */

View File

@ -88,6 +88,14 @@ if(CONFIG_ARCH_RV_ISA_A)
list(APPEND SRCS riscv_testset.S) list(APPEND SRCS riscv_testset.S)
endif() endif()
if(CONFIG_ARCH_RV_HAVE_APLIC)
list(APPEND SRCS riscv_aplic.c)
endif()
if(CONFIG_ARCH_RV_HAVE_IMSIC)
list(APPEND SRCS riscv_imsic.c)
endif()
if(CONFIG_RISCV_SEMIHOSTING_HOSTFS) if(CONFIG_RISCV_SEMIHOSTING_HOSTFS)
list(APPEND SRCS riscv_semihost.S riscv_hostfs.c) list(APPEND SRCS riscv_semihost.S riscv_hostfs.c)
endif() endif()

View File

@ -91,6 +91,10 @@ ifeq ($(CONFIG_ARCH_RV_ISA_A),y)
CMN_ASRCS += riscv_testset.S CMN_ASRCS += riscv_testset.S
endif endif
ifeq ($(CONFIG_ARCH_RV_HAVE_APLIC),y)
CMN_CSRCS += riscv_aia.c
endif
ifeq ($(CONFIG_RISCV_SEMIHOSTING_HOSTFS),y) ifeq ($(CONFIG_RISCV_SEMIHOSTING_HOSTFS),y)
CMN_ASRCS += riscv_semihost.S CMN_ASRCS += riscv_semihost.S
CMN_CSRCS += riscv_hostfs.c CMN_CSRCS += riscv_hostfs.c

View File

@ -0,0 +1,290 @@
/****************************************************************************
* arch/risc-v/src/common/riscv_aia.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_COMMON_RISCV_AIA_H
#define __ARCH_RISCV_SRC_COMMON_RISCV_AIA_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/bits.h>
#include <arch/csr.h>
#include "riscv_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* AIA IMSIC */
#define RISCV_IMSIC_MAX_REGS 16
#define RISCV_IMSIC_MMIO_PAGE_LE 0x00
#define RISCV_IMSIC_MMIO_PAGE_BE 0x04
#define RISCV_IMSIC_MMIO_PAGE_BIT 12
#define RISCV_IMSIC_TOPEI_ID_BIT 16
#define RISCV_IMSIC_EIP_BITS 32
#define RISCV_IMSIC_EIE_BITS 32
#define RISCV_IMSIC_DISABLE_EIDELIVERY 0
#define RISCV_IMSIC_ENABLE_EIDELIVERY 1
#define RISCV_IMSIC_DISABLE_EITHRESHOLD 1
#define RISCV_IMSIC_ENABLE_EITHRESHOLD 0
#define RISCV_IMSIC_IPI_ID 1
/* AIA APLIC */
#define RISCV_APLIC_MAX_DELEGATE 16
#define RISCV_APLIC_MAX_IDC (1UL << 14)
#define RISCV_APLIC_MAX_SOURCE 1024
#define RISCV_APLIC_DOMAINCFG 0x0000
#define RISCV_APLIC_DOMAINCFG_IE (1 << 8)
#define RISCV_APLIC_DOMAINCFG_DM (1 << 2)
#define RISCV_APLIC_DOMAINCFG_BE (1 << 0)
#define RISCV_APLIC_SOURCECFG_BASE 0x0004
#define RISCV_APLIC_SOURCECFG_D (1 << 10)
#define RISCV_APLIC_SOURCECFG_CHILDIDX_MASK 0x000003ff
#define RISCV_APLIC_SOURCECFG_SM_MASK 0x00000007
#define RISCV_APLIC_SOURCECFG_SM_INACTIVE 0x0
#define RISCV_APLIC_SOURCECFG_SM_DETACH 0x1
#define RISCV_APLIC_SOURCECFG_SM_EDGE_RISE 0x4
#define RISCV_APLIC_SOURCECFG_SM_EDGE_FALL 0x5
#define RISCV_APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6
#define RISCV_APLIC_SOURCECFG_SM_LEVEL_LOW 0x7
#define RISCV_APLIC_MMSICFGADDR 0x1bc0
#define RISCV_APLIC_MMSICFGADDRH 0x1bc4
#define RISCV_APLIC_SMSICFGADDR 0x1bc8
#define RISCV_APLIC_SMSICFGADDRH 0x1bcc
#define RISCV_APLIC_MSICFGADDRH_L (1UL << 31)
#define RISCV_APLIC_MSICFGADDRH_HHXS_SHIFT 24
#define RISCV_APLIC_MSICFGADDRH_LHXS_SHIFT 20
#define RISCV_APLIC_MSICFGADDRH_HHXW_SHIFT 16
#define RISCV_APLIC_MSICFGADDRH_LHXW_SHIFT 12
#define RISCV_APLIC_MSICFGADDR_PPN_SHIFT 12
#define RISCV_APLIC_SETIP_BASE 0x1c00
#define RISCV_APLIC_SETIPNUM 0x1cdc
#define RISCV_APLIC_CLRIP_BASE 0x1d00
#define RISCV_APLIC_CLRIPNUM 0x1ddc
#define RISCV_APLIC_SETIE_BASE 0x1e00
#define RISCV_APLIC_SETIENUM 0x1edc
#define RISCV_APLIC_CLRIE_BASE 0x1f00
#define RISCV_APLIC_CLRIENUM 0x1fdc
#define RISCV_APLIC_SETIPNUM_LE 0x2000
#define RISCV_APLIC_SETIPNUM_BE 0x2004
#define RISCV_APLIC_TARGET_BASE 0x3004
#define RISCV_APLIC_TARGET_HART_IDX_SHIFT 18
#define RISCV_APLIC_TARGET_GUEST_IDX_SHIFT 12
#define RISCV_APLIC_IDC_BASE 0x4000
#define RISCV_APLIC_IDC_SIZE 32
#define RISCV_APLIC_IDC_IDELIVERY 0x00
#define RISCV_APLIC_IDC_IFORCE 0x04
#define RISCV_APLIC_IDC_ITHRESHOLD 0x08
#define RISCV_APLIC_IDC_TOPI 0x18
#define RISCV_APLIC_IDC_TOPI_ID_SHIFT 16
#define RISCV_APLIC_IDC_CLAIMI 0x1c
#define RISCV_APLIC_DEFAULT_PRIORITY 1
#define RISCV_APLIC_DISABLE_IDELIVERY 0
#define RISCV_APLIC_ENABLE_IDELIVERY 1
#define RISCV_APLIC_DISABLE_ITHRESHOLD 1
#define RISCV_APLIC_ENABLE_ITHRESHOLD 0
#define RISCV_APLIC_IDC(base, i) \
((base) + RISCV_APLIC_IDC_BASE + RISCV_APLIC_IDC_SIZE * (i))
/****************************************************************************
* Public Types
****************************************************************************/
union aplic_mode_arg_u
{
struct
{
uint32_t idelivery;
uint32_t ithreshold;
} direct;
struct
{
uint64_t imsic_ppn;
uint32_t lhxs;
uint32_t lhxw;
uint32_t hhxs;
uint32_t hhxw;
} msi;
};
/****************************************************************************
* Public Function
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* IMSIC */
#define riscv_imsic_csr_write(reg, val) WRITE_INDIRECT_CSR_REG0(reg, val)
#define riscv_imsic_csr_read(reg, val) READ_INDIRECT_CSR_REG0(reg, val)
#define riscv_imsic_csr_set(reg, val) SET_INDIRECT_CSR_REG0(reg, val)
#define riscv_imsic_csr_clear(reg, val) CLEAR_INDIRECT_CSR_REG0(reg, val)
void riscv_imsic_local_eix_update(unsigned long base_id,
unsigned long num_id,
bool pend, bool val);
static inline void riscv_imsic_local_eie_update(unsigned long base_id,
unsigned long num_id, bool val)
{
return riscv_imsic_local_eix_update(base_id, num_id, false, val);
}
static inline void riscv_imsic_local_eip_update(unsigned long base_id,
unsigned long num_id, bool val)
{
return riscv_imsic_local_eix_update(base_id, num_id, true, val);
}
static inline void riscv_imsic_local_eie_enable(unsigned long base_id)
{
return riscv_imsic_local_eie_update(base_id, 1, true);
}
static inline void riscv_imsic_local_eie_disable(unsigned long base_id)
{
return riscv_imsic_local_eie_update(base_id, 1, false);
}
void riscv_imsic_send_ipi(int cpu);
/* APLIC */
static inline int riscv_aplic_set_delegate(uintptr_t base,
uint32_t first_irq,
uint32_t last_irq,
uint32_t child_id)
{
uint32_t j;
uintptr_t sourcecfg_base = base + RISCV_APLIC_SOURCECFG_BASE;
if (!first_irq || !last_irq)
return 0;
if (RISCV_APLIC_SOURCECFG_CHILDIDX_MASK < child_id)
return -EINVAL;
for (j = first_irq; j <= last_irq; j++)
{
putreg32(RISCV_APLIC_SOURCECFG_D | child_id,
sourcecfg_base + (j - 1) * sizeof(uint32_t));
}
return 0;
}
static inline void riscv_aplic_enable_irq(uintptr_t base, uint32_t irq)
{
putreg32(irq, base + RISCV_APLIC_SETIENUM);
}
static inline void riscv_aplic_disable_irq(uintptr_t base, uint32_t irq)
{
putreg32(irq, base + RISCV_APLIC_CLRIENUM);
}
static inline void riscv_aplic_configure_irq(uintptr_t base, uint32_t irq,
uint32_t mode, uint32_t hartid)
{
uint32_t val = (hartid << RISCV_APLIC_TARGET_HART_IDX_SHIFT) | irq;
putreg32(mode, base + RISCV_APLIC_SOURCECFG_BASE
+ (irq - 1) * sizeof(uint32_t));
putreg32(val, base + RISCV_APLIC_TARGET_BASE
+ (irq - 1) * sizeof(uint32_t));
}
static inline void riscv_aplic_disable_irqs(uintptr_t base,
uint32_t num_source)
{
uint32_t i;
putreg32(0, base + RISCV_APLIC_DOMAINCFG);
/* Disable all interrupts */
for (i = 0; i < num_source; i += 32)
{
putreg32(-1U, base + RISCV_APLIC_CLRIE_BASE
+ (i / 32) * sizeof(uint32_t));
}
}
/****************************************************************************
* Name: riscv_aplic_init
*
* Description:
* Init APLIC to direct mode
*
****************************************************************************/
void riscv_aplic_init(uintptr_t base,
uint32_t idelivery, uint32_t ithreshold);
/****************************************************************************
* Name: riscv_aplic_init
*
* Description:
* Init APLIC to msi mode
*
****************************************************************************/
void riscv_aplic_init_msi(uintptr_t base, uint64_t imsic_addr,
uint32_t lhxs, uint32_t lhxw,
uint32_t hhxs, uint32_t hhxw);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __ARCH_RISCV_SRC_COMMON_RISCV_AIA_H */

View File

@ -0,0 +1,61 @@
/****************************************************************************
* arch/risc-v/src/common/riscv_aplic.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "riscv_internal.h"
#include "riscv_aia.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void riscv_aplic_init(uintptr_t base,
uint32_t idelivery, uint32_t ithreshold)
{
int i;
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
{
uintptr_t idc_base = RISCV_APLIC_IDC(base, i);
putreg32(idelivery, idc_base + RISCV_APLIC_IDC_IDELIVERY);
putreg32(0, idc_base + RISCV_APLIC_IDC_IFORCE);
putreg32(ithreshold, idc_base + RISCV_APLIC_IDC_ITHRESHOLD);
}
}
void riscv_aplic_init_msi(uintptr_t base, uint64_t imsic_addr,
uint32_t lhxs, uint32_t lhxw,
uint32_t hhxs, uint32_t hhxw)
{
uint32_t tmp;
tmp = imsic_addr >> RISCV_IMSIC_MMIO_PAGE_BIT;
putreg32(tmp, base + RISCV_APLIC_MMSICFGADDR);
tmp = (uint32_t)(imsic_addr >> 32) |
(lhxw << RISCV_APLIC_MSICFGADDRH_LHXW_SHIFT) |
(lhxs << RISCV_APLIC_MSICFGADDRH_LHXS_SHIFT) |
(hhxw << RISCV_APLIC_MSICFGADDRH_HHXW_SHIFT) |
(hhxs << RISCV_APLIC_MSICFGADDRH_HHXS_SHIFT);
putreg32(tmp, base + RISCV_APLIC_MMSICFGADDRH);
}

View File

@ -0,0 +1,63 @@
/****************************************************************************
* arch/risc-v/src/common/riscv_imsic.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "riscv_internal.h"
#include "riscv_aia.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void riscv_imsic_local_eix_update(unsigned long base_id,
unsigned long num_id,
bool pend, bool val)
{
uintptr_t i, isel, ireg;
unsigned long id = base_id;
unsigned long last_id = base_id + num_id;
while (id < last_id)
{
isel = id / __riscv_xlen;
isel *= __riscv_xlen / RISCV_IMSIC_EIP_BITS;
isel += (pend) ? ISELECT_EIP0 : ISELECT_EIE0;
ireg = 0;
for (i = id & (__riscv_xlen - 1);
(id < last_id) && (i < __riscv_xlen); i++)
{
ireg |= BIT(i);
id++;
}
if (val)
{
riscv_imsic_csr_set(isel, ireg);
}
else
{
riscv_imsic_csr_clear(isel, ireg);
}
}
}

View File

@ -197,6 +197,38 @@ static inline void putreg64(uint64_t v, const volatile uintreg_t a)
__asm__ __volatile__("csrc " __STR(reg) ", %0" :: "rK"(bits)); \ __asm__ __volatile__("csrc " __STR(reg) ", %0" :: "rK"(bits)); \
}) })
#define SWAP_CSR(reg, val) \
({ \
uintptr_t regval; \
__asm__ __volatile__("csrrw %0, " __STR(reg) ", %1" : "=r"(regval) \
: "rK"(val)); \
regval; \
})
#define WRITE_INDIRECT_CSR_REG0(reg, val) \
({ \
WRITE_CSR(CSR_ISELECT, reg); \
WRITE_CSR(CSR_IREG, val); \
})
#define READ_INDIRECT_CSR_REG0(reg, val) \
({ \
WRITE_CSR(CSR_ISELECT, reg); \
READ_CSR(CSR_IREG, val); \
})
#define SET_INDIRECT_CSR_REG0(reg, val) \
({ \
WRITE_CSR(CSR_ISELECT, reg); \
SET_CSR(CSR_IREG, val); \
})
#define CLEAR_INDIRECT_CSR_REG0(reg, val) \
({ \
WRITE_CSR(CSR_ISELECT, reg); \
CLEAR_CSR(CSR_IREG, val); \
})
#define riscv_append_pmp_region(a, b, s) \ #define riscv_append_pmp_region(a, b, s) \
riscv_config_pmp_region(riscv_next_free_pmp_region(), a, b, s) riscv_config_pmp_region(riscv_next_free_pmp_region(), a, b, s)