[bsp/phytium]中断相关修改 (#8742)

* update smp 4
This commit is contained in:
zhangyan 2024-04-11 00:09:17 +08:00 committed by GitHub
parent b14e0c08e1
commit 81df7bcdde
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 333 additions and 216 deletions

View File

@ -21,6 +21,7 @@
#include <mmu.h>
#include <mm_aspace.h> /* TODO: why need application space when RT_SMART off */
#include <mm_page.h>
#include "phytium_interrupt.h"
#ifdef RT_USING_SMART
#include <page.h>
@ -157,7 +158,7 @@ void rt_hw_board_aarch64_init(void)
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
rt_hw_interrupt_init();
phytium_interrupt_init();
rt_hw_gtimer_init();

View File

@ -20,9 +20,6 @@
#include "phytium_cpu.h"
#if defined(TARGET_ARMV8_AARCH64)
/**
@name: phytium_cpu_id_mapping
@msg: Map Phytium CPU ID
@ -30,48 +27,6 @@
@param {int} cpu_id Input CPU ID
@return {int} Mapped CPU ID
*/
int phytium_cpu_id_mapping(int cpu_id)
{
#if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)
#if RT_CPUS_NR <= 2
switch (cpu_id)
{
case 0:
return 2;
case 1:
return 3;
case 2:
return 0;
case 3:
return 1;
default:
RT_ASSERT(0);
return 0;
break;
}
#else
return (int)cpu_id;
#endif
#else
return (int)cpu_id;
#endif
}
int rt_hw_cpu_id(void)
{
FError ret;
u32 cpu_id;
ret = GetCpuId(&cpu_id);
if (ret != ERR_SUCCESS)
{
RT_ASSERT(0);
}
return phytium_cpu_id_mapping(cpu_id);
}
#else
int phytium_cpu_id_mapping(int cpu_id)
{
#if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)
@ -105,10 +60,11 @@ int rt_hw_cpu_id(void)
{
RT_ASSERT(0);
}
return phytium_cpu_id_mapping(cpu_id);
}
#if defined(TARGET_ARMV8_AARCH32)
rt_uint64_t get_main_cpu_affval(void)
{
#if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)

View File

@ -48,17 +48,12 @@ rt_inline rt_uint32_t platform_get_gic_dist_base(void)
/* the basic constants and interfaces needed by gic */
rt_inline rt_uint32_t platform_get_gic_redist_base(void)
{
#if RT_CPUS_NR <= 2
return GICV3_RD_BASE_ADDR + 2 * GICV3_RD_OFFSET;
#else
return GICV3_RD_BASE_ADDR;
#endif
return 0;
}
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
{
return 0U; /* unused in gicv3 */
return 0; /* unused in gicv3 */
}
#endif
@ -66,6 +61,4 @@ rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
int phytium_cpu_id_mapping(int cpu_id);
#endif // !

View File

@ -40,6 +40,7 @@
rt_uint64_t rt_cpu_mpidr_early[] =
{
#if defined(TARGET_E2000D)
[0] = 0x80000200,
[1] = 0x80000201,
@ -78,7 +79,7 @@ void rt_hw_secondary_cpu_up(void)
{
continue;
}
cpu_mask = 1 << phytium_cpu_id_mapping(i);
cpu_mask = 1<<phytium_cpu_id_mapping(i);
#if defined(TARGET_ARMV8_AARCH64)
/* code */
@ -103,7 +104,6 @@ void rt_hw_secondary_cpu_up(void)
*/
extern size_t MMUTable[];
void rt_hw_secondary_cpu_bsp_start(void)
{
/* spin lock init */
@ -125,7 +125,7 @@ void rt_hw_secondary_cpu_bsp_start(void)
#if defined(TARGET_ARMV8_AARCH64)
arm_gic_cpu_init(0, 0);
arm_gic_redist_init(0, 0);
phytium_aarch64_arm_gic_redist_init();
rt_kprintf("arm_gic_redist_init is over rt_hw_cpu_id() is %d \r\n", rt_hw_cpu_id());
#else
arm_gic_cpu_init(0);

View File

@ -0,0 +1,150 @@
#include "rtconfig.h"
#if defined(TARGET_ARMV8_AARCH64)
#include <rthw.h>
#include <rtthread.h>
#include "interrupt.h"
#include "gic.h"
#include "gicv3.h"
#include "ioremap.h"
#include "phytium_cpu.h"
#include "ftypes.h"
#include "fparameters.h"
struct arm_gic *phytium_gic_table;
extern struct rt_irq_desc isr_table[MAX_HANDLERS];
int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id)
{
RT_ASSERT(index < ARM_GIC_MAX_NR);
if (cpu_id == 0)
{
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, &cpu_id, sizeof(cpu_id));
}
phytium_gic_table[index].redist_hw_base[cpu_id] = redist_addr;
return 0;
}
static int arm_gicv3_wait_rwp(rt_uint64_t index, rt_uint64_t irq)
{
rt_uint64_t rwp_bit;
rt_uint64_t base;
RT_ASSERT(index < ARM_GIC_MAX_NR);
if (irq < 32)
{
rt_int32_t cpu_id = rt_hw_cpu_id();
base = phytium_gic_table[index].redist_hw_base[cpu_id];
rwp_bit = GICR_CTLR_RWP;
}
else
{
base = phytium_gic_table[index].dist_hw_base;
rwp_bit = GICD_CTLR_RWP;
}
while (HWREG32(base) & rwp_bit)
{
}
return 0;
}
int phytium_aarch64_arm_gic_redist_init()
{
rt_uint64_t cpu_id = rt_hw_cpu_id();
rt_uint64_t redist_base = phytium_gic_table[0].redist_hw_base[cpu_id];
/* redistributor enable */
GIC_RDIST_WAKER(redist_base) &= ~(1 << 1);
while (GIC_RDIST_WAKER(redist_base) & (1 << 2))
{
}
/* Disable all sgi and ppi interrupt */
GIC_RDISTSGI_ICENABLER0(redist_base) = 0xffffffff;
arm_gicv3_wait_rwp(0, 0);
/* Clear all inetrrupt pending */
GIC_RDISTSGI_ICPENDR0(redist_base) = 0xffffffff;
/* the corresponding interrupt is Group 1 or Non-secure Group 1. */
GIC_RDISTSGI_IGROUPR0(redist_base, 0) = 0xffffffff;
GIC_RDISTSGI_IGRPMODR0(redist_base, 0) = 0xffffffff;
/* Configure default priorities for SGI 0:15 and PPI 16:31. */
for (int i = 0; i < 32; i += 4)
{
GIC_RDISTSGI_IPRIORITYR(redist_base, i) = 0xa0a0a0a0U;
}
/* Trigger level for PPI interrupts*/
GIC_RDISTSGI_ICFGR1(redist_base) = 0;
return 0;
}
void phytium_interrupt_init(void)
{
rt_uint64_t gic_cpu_base;
rt_uint64_t gic_dist_base;
rt_uint64_t gic_irq_start;
rt_uint64_t redist_addr;
phytium_gic_table = (struct arm_gic *)arm_gic_get_gic_table_addr();
/* initialize vector table */
rt_hw_vector_init();
/* initialize exceptions table */
rt_memset(isr_table, 0x00, sizeof(isr_table));
#if defined(RT_USING_SMART)
gic_dist_base = (rt_uint64_t)rt_ioremap((void *)platform_get_gic_dist_base(), 0x40000);
gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
redist_addr = (rt_uint64_t)rt_ioremap(GICV3_RD_BASE_ADDR, 4 * GICV3_RD_OFFSET);
#else
gic_dist_base = platform_get_gic_dist_base();
gic_cpu_base = platform_get_gic_cpu_base();
redist_addr = GICV3_RD_BASE_ADDR;
#endif
gic_irq_start = 0;
arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
arm_gic_cpu_init(0, gic_cpu_base);
arm_gic_redist_address_set(0, redist_addr + 2 * GICV3_RD_OFFSET, 0);
#if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)
#if RT_CPUS_NR == 2
arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
#elif RT_CPUS_NR == 3
arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
arm_gic_redist_address_set(0, redist_addr, 2);
#elif RT_CPUS_NR == 4
arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
arm_gic_redist_address_set(0, redist_addr, 2);
arm_gic_redist_address_set(0, redist_addr + GICV3_RD_OFFSET, 3);
#endif
#else
#if defined(TARGET_E2000D)
rt_uint32_t cpu_offset = 2;
#endif
#if RT_CPUS_NR == 2
arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
#elif RT_CPUS_NR == 3
arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
arm_gic_redist_address_set(0, redist_addr + (2 + cpu_offset) * GICV3_RD_OFFSET, 2);
#elif RT_CPUS_NR == 4
arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
arm_gic_redist_address_set(0, redist_addr + (2 + cpu_offset) * GICV3_RD_OFFSET, 2);
arm_gic_redist_address_set(0, redist_addr + (3 + cpu_offset) * GICV3_RD_OFFSET, 3);
#endif
#endif
phytium_aarch64_arm_gic_redist_init();
}
#endif

View File

@ -0,0 +1,17 @@
#ifndef PHYTIUM_INTERRUPT_H
#define PHYTIUM_INTERRUPT_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "rtconfig.h"
#if defined(TARGET_ARMV8_AARCH64)
void phytium_interrupt_init(void);
int phytium_aarch64_arm_gic_redist_init(void);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -166,7 +166,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
struct phytium_can *drv_can;
drv_can = (struct phytium_can *)can->parent.user_data;
RT_ASSERT(drv_can != RT_NULL);
rt_uint32_t cpu_id;
rt_uint32_t cpu_id = rt_hw_cpu_id();
FCanIntrEventConfig intr_event;
FError status = FT_SUCCESS;
@ -177,7 +177,6 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg)
switch (cmd)
{
case RT_DEVICE_CTRL_SET_INT:
GetCpuId(&cpu_id);
rt_hw_interrupt_set_target_cpus(drv_can->can_handle.config.irq_num, cpu_id);
argval = (rt_uint32_t) arg;
/*Open different interrupts*/

View File

@ -63,10 +63,9 @@ extern FIOPadCtrl iopad_ctrl;
/*******************************Api Functions*********************************/
static void FGpioOpsSetupCtrlIRQ(FGpio *ctrl)
{
u32 cpu_id;
rt_uint32_t cpu_id = rt_hw_cpu_id();
u32 irq_num = ctrl->config.irq_num[0];
GetCpuId(&cpu_id);
LOG_D("In FGpioOpsSetupCtrlIRQ() -> cpu_id %d, irq_num %d\r\n", cpu_id, irq_num);
rt_hw_interrupt_set_target_cpus(irq_num, cpu_id);
rt_hw_interrupt_set_priority(irq_num, ctrl->config.irq_priority); /* setup interrupt */
@ -78,10 +77,9 @@ static void FGpioOpsSetupCtrlIRQ(FGpio *ctrl)
/* setup gpio pin interrupt */
static void FGpioOpsSetupPinIRQ(FGpio *ctrl, FGpioPin *const pin, FGpioOpsPinConfig *config)
{
u32 cpu_id;
rt_uint32_t cpu_id = rt_hw_cpu_id();
u32 irq_num = ctrl->config.irq_num[pin->index.pin];
GetCpuId(&cpu_id);
LOG_D("in FGpioOpsSetupPinIRQ() -> cpu_id %d, irq_num %d", cpu_id, irq_num);
rt_hw_interrupt_set_target_cpus(irq_num, cpu_id);
rt_hw_interrupt_set_priority(irq_num, ctrl->config.irq_priority); /* setup interrupt */

View File

@ -26,6 +26,10 @@
#include <ioremap.h>
#endif
/*Please define the length of the mem_addr of the device*/
#ifndef FI2C_DEVICE_MEMADDR_LEN
#define FI2C_DEVICE_MEMADDR_LEN 1
#endif
#define FI2C_DEFAULT_ID 0
#define I2C_USE_MIO
#if defined(I2C_USE_MIO)
@ -167,15 +171,19 @@ static rt_ssize_t i2c_master_xfer(struct rt_i2c_bus_device *device, struct rt_i2
struct rt_i2c_msg *pmsg;
struct phytium_i2c_bus *i2c_bus;
i2c_bus = (struct phytium_i2c_bus *)(device);
u8 mem_addr = msgs->buf[0];
u32 mem_addr;
for (int i = 0; i < num; i++)
{
pmsg = i2c_bus->msg = &msgs[i];
pmsg = &msgs[i];
for (u32 j = 0; j <FI2C_DEVICE_MEMADDR_LEN; j++)
{
mem_addr |= msgs[i].buf[j] << (8 * (FI2C_DEVICE_MEMADDR_LEN - 1 - j));
}
i2c_bus->i2c_handle.config.slave_addr = pmsg->addr;
if (pmsg->flags & RT_I2C_RD)
{
ret = FI2cMasterReadPoll(&i2c_bus->i2c_handle, mem_addr, 1, &pmsg->buf[0], sizeof(pmsg->buf));
ret = FI2cMasterReadPoll(&i2c_bus->i2c_handle, mem_addr, FI2C_DEVICE_MEMADDR_LEN, &pmsg->buf[0], pmsg->len);
if (ret != FI2C_SUCCESS)
{
LOG_E("I2C master read failed!\n");
@ -184,7 +192,7 @@ static rt_ssize_t i2c_master_xfer(struct rt_i2c_bus_device *device, struct rt_i2
}
else
{
ret = FI2cMasterWritePoll(&i2c_bus->i2c_handle, mem_addr, 1, &pmsg->buf[1], sizeof(pmsg->buf) - 1);
ret = FI2cMasterWritePoll(&i2c_bus->i2c_handle, mem_addr, FI2C_DEVICE_MEMADDR_LEN, &pmsg->buf[FI2C_DEVICE_MEMADDR_LEN], pmsg->len);
if (ret != FI2C_SUCCESS)
{
LOG_E("I2C master write failed!\n");

View File

@ -320,14 +320,16 @@ static rt_ssize_t phytium_qspi_xfer(struct rt_spi_device *device, struct rt_spi_
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(message != RT_NULL);
FError ret = FT_SUCCESS;
phytium_qspi_bus *qspi_bus;
struct rt_qspi_message *qspi_message = (struct rt_qspi_message *)message;
rt_uint32_t cmd = qspi_message->instruction.content;
rt_uint32_t flash_addr = qspi_message->address.content;
rt_uint32_t len = message->length;
const void *rcvb = message->recv_buf;
const void *sndb = message->send_buf;
FError ret = FT_SUCCESS;
qspi_bus = (phytium_qspi_bus *)(struct phytium_qspi_bus *) device->bus->parent.user_data;
@ -345,8 +347,6 @@ static rt_ssize_t phytium_qspi_xfer(struct rt_spi_device *device, struct rt_spi_
/*Distinguish the write mode according to different commands*/
if (cmd == FQSPI_FLASH_CMD_PP || cmd == FQSPI_FLASH_CMD_QPP || cmd == FQSPI_FLASH_CMD_4PP || cmd == FQSPI_FLASH_CMD_4QPP)
{
rt_uint8_t len = message->length;
rt_memcpy(&wr_buf, (char *)message->send_buf, len);
ret = FQspiFlashErase(&(qspi_bus->fqspi), FQSPI_FLASH_CMD_SE, flash_addr);
if (FT_SUCCESS != ret)
@ -381,22 +381,20 @@ static rt_ssize_t phytium_qspi_xfer(struct rt_spi_device *device, struct rt_spi_
return -RT_ERROR;
}
/* read norflash data */
size_t read_len = QspiFlashReadData(&(qspi_bus->fqspi), addr, (u8 *)&rd_buf, DAT_LENGTH);
message->length = read_len;
if (read_len != DAT_LENGTH)
size_t read_len = QspiFlashReadData(&(qspi_bus->fqspi), addr, (u8 *)&rd_buf, len);
if (read_len != len)
{
rt_kprintf("Failed to read mem, read len = %d.\r\n", read_len);
return -RT_ERROR;
}
else
{
rt_kprintf("Read successfully!!!\r\n");
rt_kprintf("Read successfully!!!, read_len = %d\r\n", read_len);
message->recv_buf = &rd_buf;
}
FtDumpHexByte(message->recv_buf, read_len);
return RT_EOK;
return read_len;
}
if (rcvb)
@ -411,7 +409,7 @@ static rt_ssize_t phytium_qspi_xfer(struct rt_spi_device *device, struct rt_spi_
}
}
return RT_EOK;
return 1;
}
if (sndb)
@ -430,8 +428,9 @@ static rt_ssize_t phytium_qspi_xfer(struct rt_spi_device *device, struct rt_spi_
return -RT_ERROR;
}
return RT_EOK;
return 1;
}
rt_kprintf("cmd not found!!!\r\n");
return ret;
}

View File

@ -129,9 +129,8 @@ static void fsdif_ctrl_setup_interrupt(struct rt_mmcsd_host *host)
fsdif_info_t *private_data = (fsdif_info_t *)host->private_data;
FSdif *mmcsd_instance = private_data->mmcsd_instance;
FSdifConfig *config_p = &mmcsd_instance->config;
rt_uint32_t cpu_id = 0;
rt_uint32_t cpu_id = rt_hw_cpu_id();
GetCpuId((u32 *)&cpu_id);
rt_hw_interrupt_set_target_cpus(config_p->irq_num, cpu_id);
rt_hw_interrupt_set_priority(config_p->irq_num, 0xd0);

View File

@ -54,9 +54,8 @@ static FError FSpimSetupInterrupt(FSpim *instance_p)
FASSERT(instance_p);
FSpimConfig *config_p = &instance_p->config;
uintptr base_addr = config_p->base_addr;
u32 cpu_id = 0;
rt_uint32_t cpu_id = rt_hw_cpu_id();
GetCpuId(&cpu_id);
LOG_D("cpu_id is %d, irq_num is %d\n", cpu_id, config_p->irq_num);
config_p->irq_prority = 0xd0;
rt_hw_interrupt_set_target_cpus(config_p->irq_num, cpu_id);

View File

@ -1001,8 +1001,7 @@ static void FxmacOsIntrHandler(s32 vector, void *args)
static void FXmacSetupIsr(FXmacOs *instance_p)
{
u32 cpu_id;
GetCpuId(&cpu_id);
rt_uint32_t cpu_id = rt_hw_cpu_id();
/* Setup callbacks */
FXmacSetHandler(&instance_p->instance, FXMAC_HANDLER_DMARECV, FXmacRecvSemaphoreHandler, instance_p);

View File

@ -29,12 +29,12 @@
/* cache */
void FDriverDCacheRangeFlush(uintptr_t adr, size_t len)
{
__asm_flush_dcache_range(adr, len);
__asm_flush_dcache_range((void *)adr, len);
}
void FDriverDCacheRangeInvalidate(uintptr_t adr, size_t len)
{
rt_hw_cpu_dcache_invalidate(adr, len);
rt_hw_cpu_dcache_invalidate((void *)adr, len);
}
void FDriverICacheRangeInvalidate(uintptr_t adr, size_t len)
@ -42,37 +42,26 @@ void FDriverICacheRangeInvalidate(uintptr_t adr, size_t len)
__asm_invalidate_icache_all();
}
void FDriverMdelay(u32 msec)
{
for(rt_uint32_t wait = 0; wait < 10000000; wait ++);
}
#else
#include "rthw.h"
/* cache */
void FDriverDCacheRangeFlush(uintptr_t adr, size_t len)
{
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, adr, len);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, (void *)adr, len);
}
void FDriverDCacheRangeInvalidate(uintptr_t adr, size_t len)
{
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, adr, len);
rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, (void *)adr, len);
}
void FDriverICacheRangeInvalidate(uintptr_t adr, size_t len)
{
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, adr, len);
}
void FDriverMdelay(u32 msec)
{
rt_thread_mdelay(msec);
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, (void *)adr, len);
}
#endif
/* time delay */
void FDriverUdelay(u32 usec)
@ -85,3 +74,8 @@ void FDriverSdelay(u32 sec)
u32 msec = sec * 1000;
rt_thread_mdelay(msec);
}
void FDriverMdelay(u32 msec)
{
rt_thread_mdelay(msec);
}

View File

@ -41,125 +41,10 @@
extern rt_uint64_t rt_cpu_mpidr_early[];
#endif /* RT_USING_SMP */
struct arm_gic
{
rt_uint64_t offset; /* the first interrupt index in the vector table */
rt_uint64_t redist_hw_base[ARM_GIC_CPU_NUM]; /* the pointer of the gic redistributor */
rt_uint64_t dist_hw_base; /* the base address of the gic distributor */
rt_uint64_t cpu_hw_base[ARM_GIC_CPU_NUM]; /* the base address of the gic cpu interface */
};
/* 'ARM_GIC_MAX_NR' is the number of cores */
static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
static unsigned int _gic_max_irq;
#define GET_GICV3_REG(reg, out) __asm__ volatile ("mrs %0, " reg:"=r"(out)::"memory");
#define SET_GICV3_REG(reg, in) __asm__ volatile ("msr " reg ", %0"::"r"(in):"memory");
/* AArch64 System register interface to GICv3 */
#define ICC_IAR0_EL1 "S3_0_C12_C8_0"
#define ICC_IAR1_EL1 "S3_0_C12_C12_0"
#define ICC_EOIR0_EL1 "S3_0_C12_C8_1"
#define ICC_EOIR1_EL1 "S3_0_C12_C12_1"
#define ICC_HPPIR0_EL1 "S3_0_C12_C8_2"
#define ICC_HPPIR1_EL1 "S3_0_C12_C12_2"
#define ICC_BPR0_EL1 "S3_0_C12_C8_3"
#define ICC_BPR1_EL1 "S3_0_C12_C12_3"
#define ICC_DIR_EL1 "S3_0_C12_C11_1"
#define ICC_PMR_EL1 "S3_0_C4_C6_0"
#define ICC_RPR_EL1 "S3_0_C12_C11_3"
#define ICC_CTLR_EL1 "S3_0_C12_C12_4"
#define ICC_CTLR_EL3 "S3_6_C12_C12_4"
#define ICC_SRE_EL1 "S3_0_C12_C12_5"
#define ICC_SRE_EL2 "S3_4_C12_C9_5"
#define ICC_SRE_EL3 "S3_6_C12_C12_5"
#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6"
#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7"
#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7"
#define ICC_SGI0R_EL1 "S3_0_C12_C11_7"
#define ICC_SGI1R_EL1 "S3_0_C12_C11_5"
#define ICC_ASGI1R_EL1 "S3_0_C12_C11_6"
/* Macro to access the Distributor Control Register (GICD_CTLR) */
#define GICD_CTLR_RWP (1U << 31)
#define GICD_CTLR_E1NWF (1U << 7)
#define GICD_CTLR_DS (1U << 6)
#define GICD_CTLR_ARE_NS (1U << 5)
#define GICD_CTLR_ARE_S (1U << 4)
#define GICD_CTLR_ENGRP1S (1U << 2)
#define GICD_CTLR_ENGRP1NS (1U << 1)
#define GICD_CTLR_ENGRP0 (1U << 0)
/* Macro to access the Redistributor Control Register (GICR_CTLR) */
#define GICR_CTLR_UWP (1U << 31)
#define GICR_CTLR_DPG1S (1U << 26)
#define GICR_CTLR_DPG1NS (1U << 25)
#define GICR_CTLR_DPG0 (1U << 24)
#define GICR_CTLR_RWP (1U << 3)
#define GICR_CTLR_IR (1U << 2)
#define GICR_CTLR_CES (1U << 1)
#define GICR_CTLR_EnableLPI (1U << 0)
/* Macro to access the Generic Interrupt Controller Interface (GICC) */
#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U)
#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U)
#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U)
#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU)
#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U)
#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U)
#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U)
#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU)
/* Macro to access the Generic Interrupt Controller Distributor (GICD) */
#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U)
#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U)
#define GIC_DIST_IIDR(hw_base) HWREG32((hw_base) + 0x008U)
#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n) / 32U) * 4U)
#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n) / 32U) * 4U)
#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n) / 32U) * 4U)
#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n) / 32U) * 4U)
#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n) / 32U) * 4U)
#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n) / 32U) * 4U)
#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n) / 32U) * 4U)
#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n) / 4U) * 4U)
#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n) / 4U) * 4U)
#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n) / 16U) * 4U)
#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U)
#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n) / 4U) * 4U)
#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n) / 4U) * 4U)
#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U)
#define GIC_DIST_IROUTER(hw_base, n) HWREG64((hw_base) + 0x6000U + (n) * 8U)
/* SGI base address is at 64K offset from Redistributor base address */
#define GIC_RSGI_OFFSET 0x10000
/* Macro to access the Generic Interrupt Controller Redistributor (GICR) */
#define GIC_RDIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U)
#define GIC_RDIST_IIDR(hw_base) HWREG32((hw_base) + 0x004U)
#define GIC_RDIST_TYPER(hw_base) HWREG64((hw_base) + 0x008U)
#define GIC_RDIST_TSTATUSR(hw_base) HWREG32((hw_base) + 0x010U)
#define GIC_RDIST_WAKER(hw_base) HWREG32((hw_base) + 0x014U)
#define GIC_RDIST_SETLPIR(hw_base) HWREG32((hw_base) + 0x040U)
#define GIC_RDIST_CLRLPIR(hw_base) HWREG32((hw_base) + 0x048U)
#define GIC_RDIST_PROPBASER(hw_base) HWREG32((hw_base) + 0x070U)
#define GIC_RDIST_PENDBASER(hw_base) HWREG32((hw_base) + 0x078U)
#define GIC_RDIST_INVLPIR(hw_base) HWREG32((hw_base) + 0x0A0U)
#define GIC_RDIST_INVALLR(hw_base) HWREG32((hw_base) + 0x0B0U)
#define GIC_RDIST_SYNCR(hw_base) HWREG32((hw_base) + 0x0C0U)
#define GIC_RDISTSGI_IGROUPR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n) * 4U)
#define GIC_RDISTSGI_ISENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x100U)
#define GIC_RDISTSGI_ICENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x180U)
#define GIC_RDISTSGI_ISPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x200U)
#define GIC_RDISTSGI_ICPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x280U)
#define GIC_RDISTSGI_ISACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x300U)
#define GIC_RDISTSGI_ICACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x380U)
#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U)
#define GIC_RDISTSGI_ICFGR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U)
#define GIC_RDISTSGI_ICFGR1(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U)
#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n) * 4)
#define GIC_RDISTSGI_NSACR(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U)
int arm_gic_get_active_irq(rt_uint64_t index)
{
rt_base_t irq;
@ -939,6 +824,11 @@ static void arm_gic_bind_dump(void)
#endif /* BSP_USING_GICV3 */
}
rt_uint64_t *arm_gic_get_gic_table_addr(void)
{
return (rt_uint64_t *)&_gic_table[0];
}
static void arm_gic_sgi_dump(rt_uint64_t index)
{
rt_int32_t cpu_id = rt_hw_cpu_id();

View File

@ -25,6 +25,120 @@
#define GICV3_ROUTED_TO_ALL 1UL
#define GICV3_ROUTED_TO_SPEC 0UL
#define GET_GICV3_REG(reg, out) __asm__ volatile ("mrs %0, " reg:"=r"(out)::"memory");
#define SET_GICV3_REG(reg, in) __asm__ volatile ("msr " reg ", %0"::"r"(in):"memory");
/* AArch64 System register interface to GICv3 */
#define ICC_IAR0_EL1 "S3_0_C12_C8_0"
#define ICC_IAR1_EL1 "S3_0_C12_C12_0"
#define ICC_EOIR0_EL1 "S3_0_C12_C8_1"
#define ICC_EOIR1_EL1 "S3_0_C12_C12_1"
#define ICC_HPPIR0_EL1 "S3_0_C12_C8_2"
#define ICC_HPPIR1_EL1 "S3_0_C12_C12_2"
#define ICC_BPR0_EL1 "S3_0_C12_C8_3"
#define ICC_BPR1_EL1 "S3_0_C12_C12_3"
#define ICC_DIR_EL1 "S3_0_C12_C11_1"
#define ICC_PMR_EL1 "S3_0_C4_C6_0"
#define ICC_RPR_EL1 "S3_0_C12_C11_3"
#define ICC_CTLR_EL1 "S3_0_C12_C12_4"
#define ICC_CTLR_EL3 "S3_6_C12_C12_4"
#define ICC_SRE_EL1 "S3_0_C12_C12_5"
#define ICC_SRE_EL2 "S3_4_C12_C9_5"
#define ICC_SRE_EL3 "S3_6_C12_C12_5"
#define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6"
#define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7"
#define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7"
#define ICC_SGI0R_EL1 "S3_0_C12_C11_7"
#define ICC_SGI1R_EL1 "S3_0_C12_C11_5"
#define ICC_ASGI1R_EL1 "S3_0_C12_C11_6"
/* Macro to access the Distributor Control Register (GICD_CTLR) */
#define GICD_CTLR_RWP (1U << 31)
#define GICD_CTLR_E1NWF (1U << 7)
#define GICD_CTLR_DS (1U << 6)
#define GICD_CTLR_ARE_NS (1U << 5)
#define GICD_CTLR_ARE_S (1U << 4)
#define GICD_CTLR_ENGRP1S (1U << 2)
#define GICD_CTLR_ENGRP1NS (1U << 1)
#define GICD_CTLR_ENGRP0 (1U << 0)
/* Macro to access the Redistributor Control Register (GICR_CTLR) */
#define GICR_CTLR_UWP (1U << 31)
#define GICR_CTLR_DPG1S (1U << 26)
#define GICR_CTLR_DPG1NS (1U << 25)
#define GICR_CTLR_DPG0 (1U << 24)
#define GICR_CTLR_RWP (1U << 3)
#define GICR_CTLR_IR (1U << 2)
#define GICR_CTLR_CES (1U << 1)
#define GICR_CTLR_EnableLPI (1U << 0)
/* Macro to access the Generic Interrupt Controller Interface (GICC) */
#define GIC_CPU_CTRL(hw_base) HWREG32((hw_base) + 0x00U)
#define GIC_CPU_PRIMASK(hw_base) HWREG32((hw_base) + 0x04U)
#define GIC_CPU_BINPOINT(hw_base) HWREG32((hw_base) + 0x08U)
#define GIC_CPU_INTACK(hw_base) HWREG32((hw_base) + 0x0cU)
#define GIC_CPU_EOI(hw_base) HWREG32((hw_base) + 0x10U)
#define GIC_CPU_RUNNINGPRI(hw_base) HWREG32((hw_base) + 0x14U)
#define GIC_CPU_HIGHPRI(hw_base) HWREG32((hw_base) + 0x18U)
#define GIC_CPU_IIDR(hw_base) HWREG32((hw_base) + 0xFCU)
/* Macro to access the Generic Interrupt Controller Distributor (GICD) */
#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U)
#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U)
#define GIC_DIST_IIDR(hw_base) HWREG32((hw_base) + 0x008U)
#define GIC_DIST_IGROUP(hw_base, n) HWREG32((hw_base) + 0x080U + ((n) / 32U) * 4U)
#define GIC_DIST_ENABLE_SET(hw_base, n) HWREG32((hw_base) + 0x100U + ((n) / 32U) * 4U)
#define GIC_DIST_ENABLE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x180U + ((n) / 32U) * 4U)
#define GIC_DIST_PENDING_SET(hw_base, n) HWREG32((hw_base) + 0x200U + ((n) / 32U) * 4U)
#define GIC_DIST_PENDING_CLEAR(hw_base, n) HWREG32((hw_base) + 0x280U + ((n) / 32U) * 4U)
#define GIC_DIST_ACTIVE_SET(hw_base, n) HWREG32((hw_base) + 0x300U + ((n) / 32U) * 4U)
#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) HWREG32((hw_base) + 0x380U + ((n) / 32U) * 4U)
#define GIC_DIST_PRI(hw_base, n) HWREG32((hw_base) + 0x400U + ((n) / 4U) * 4U)
#define GIC_DIST_TARGET(hw_base, n) HWREG32((hw_base) + 0x800U + ((n) / 4U) * 4U)
#define GIC_DIST_CONFIG(hw_base, n) HWREG32((hw_base) + 0xc00U + ((n) / 16U) * 4U)
#define GIC_DIST_SOFTINT(hw_base) HWREG32((hw_base) + 0xf00U)
#define GIC_DIST_CPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf10U + ((n) / 4U) * 4U)
#define GIC_DIST_SPENDSGI(hw_base, n) HWREG32((hw_base) + 0xf20U + ((n) / 4U) * 4U)
#define GIC_DIST_ICPIDR2(hw_base) HWREG32((hw_base) + 0xfe8U)
#define GIC_DIST_IROUTER(hw_base, n) HWREG64((hw_base) + 0x6000U + (n) * 8U)
/* SGI base address is at 64K offset from Redistributor base address */
#define GIC_RSGI_OFFSET 0x10000
/* Macro to access the Generic Interrupt Controller Redistributor (GICR) */
#define GIC_RDIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U)
#define GIC_RDIST_IIDR(hw_base) HWREG32((hw_base) + 0x004U)
#define GIC_RDIST_TYPER(hw_base) HWREG64((hw_base) + 0x008U)
#define GIC_RDIST_TSTATUSR(hw_base) HWREG32((hw_base) + 0x010U)
#define GIC_RDIST_WAKER(hw_base) HWREG32((hw_base) + 0x014U)
#define GIC_RDIST_SETLPIR(hw_base) HWREG32((hw_base) + 0x040U)
#define GIC_RDIST_CLRLPIR(hw_base) HWREG32((hw_base) + 0x048U)
#define GIC_RDIST_PROPBASER(hw_base) HWREG32((hw_base) + 0x070U)
#define GIC_RDIST_PENDBASER(hw_base) HWREG32((hw_base) + 0x078U)
#define GIC_RDIST_INVLPIR(hw_base) HWREG32((hw_base) + 0x0A0U)
#define GIC_RDIST_INVALLR(hw_base) HWREG32((hw_base) + 0x0B0U)
#define GIC_RDIST_SYNCR(hw_base) HWREG32((hw_base) + 0x0C0U)
#define GIC_RDISTSGI_IGROUPR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x080U + (n) * 4U)
#define GIC_RDISTSGI_ISENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x100U)
#define GIC_RDISTSGI_ICENABLER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x180U)
#define GIC_RDISTSGI_ISPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x200U)
#define GIC_RDISTSGI_ICPENDR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x280U)
#define GIC_RDISTSGI_ISACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x300U)
#define GIC_RDISTSGI_ICACTIVER0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x380U)
#define GIC_RDISTSGI_IPRIORITYR(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0x400U + ((n) / 4U) * 4U)
#define GIC_RDISTSGI_ICFGR0(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC00U)
#define GIC_RDISTSGI_ICFGR1(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xC04U)
#define GIC_RDISTSGI_IGRPMODR0(hw_base, n) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xD00U + (n) * 4)
#define GIC_RDISTSGI_NSACR(hw_base) HWREG32((hw_base) + GIC_RSGI_OFFSET + 0xE00U)
struct arm_gic
{
rt_uint64_t offset; /* the first interrupt index in the vector table */
rt_uint64_t redist_hw_base[ARM_GIC_CPU_NUM]; /* the pointer of the gic redistributor */
rt_uint64_t dist_hw_base; /* the base address of the gic distributor */
rt_uint64_t cpu_hw_base[ARM_GIC_CPU_NUM]; /* the base address of the gic cpu interface */
};
int arm_gic_get_active_irq(rt_uint64_t index);
void arm_gic_ack(rt_uint64_t index, int irq);
@ -74,6 +188,7 @@ int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start);
int arm_gic_redist_init(rt_uint64_t index, rt_uint64_t redist_base);
int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base);
rt_uint64_t *arm_gic_get_gic_table_addr(void);
void arm_gic_dump_type(rt_uint64_t index);
void arm_gic_dump(rt_uint64_t index);