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:
parent
780366de62
commit
5f70307111
@ -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
|
||||||
|
@ -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
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
290
arch/risc-v/src/common/riscv_aia.h
Normal file
290
arch/risc-v/src/common/riscv_aia.h
Normal 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 */
|
61
arch/risc-v/src/common/riscv_aplic.c
Normal file
61
arch/risc-v/src/common/riscv_aplic.c
Normal 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);
|
||||||
|
}
|
63
arch/risc-v/src/common/riscv_imsic.c
Normal file
63
arch/risc-v/src/common/riscv_imsic.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user