From 81df7bcddee8b36709b4520bf8432a95d64daea8 Mon Sep 17 00:00:00 2001 From: zhangyan <103986797+messigogogo@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:09:17 +0800 Subject: [PATCH] =?UTF-8?q?[bsp/phytium]=E4=B8=AD=E6=96=AD=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BF=AE=E6=94=B9=20(#8742)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update smp 4 --- bsp/phytium/board/board.c | 3 +- bsp/phytium/board/phytium_cpu.c | 48 +----- bsp/phytium/board/phytium_cpu.h | 9 +- bsp/phytium/board/secondary_cpu.c | 6 +- .../libraries/common/phytium_interrupt.c | 150 ++++++++++++++++++ .../libraries/common/phytium_interrupt.h | 17 ++ bsp/phytium/libraries/drivers/drv_can.c | 3 +- bsp/phytium/libraries/drivers/drv_gpio.c | 6 +- bsp/phytium/libraries/drivers/drv_i2c.c | 16 +- bsp/phytium/libraries/drivers/drv_qspi.c | 21 ++- bsp/phytium/libraries/drivers/drv_sdif.c | 3 +- bsp/phytium/libraries/drivers/drv_spi.c | 3 +- bsp/phytium/libraries/drivers/drv_xmac.c | 3 +- .../port/fdriver_port/fdrivers_port.c | 26 ++- libcpu/aarch64/common/gicv3.c | 120 +------------- libcpu/aarch64/common/gicv3.h | 115 ++++++++++++++ 16 files changed, 333 insertions(+), 216 deletions(-) create mode 100644 bsp/phytium/libraries/common/phytium_interrupt.c create mode 100644 bsp/phytium/libraries/common/phytium_interrupt.h diff --git a/bsp/phytium/board/board.c b/bsp/phytium/board/board.c index 44f252d633..132c71d86b 100644 --- a/bsp/phytium/board/board.c +++ b/bsp/phytium/board/board.c @@ -21,6 +21,7 @@ #include #include /* TODO: why need application space when RT_SMART off */ #include +#include "phytium_interrupt.h" #ifdef RT_USING_SMART #include @@ -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(); diff --git a/bsp/phytium/board/phytium_cpu.c b/bsp/phytium/board/phytium_cpu.c index e7655b7e44..cd9fcbabfd 100644 --- a/bsp/phytium/board/phytium_cpu.c +++ b/bsp/phytium/board/phytium_cpu.c @@ -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) diff --git a/bsp/phytium/board/phytium_cpu.h b/bsp/phytium/board/phytium_cpu.h index 65fd20f664..15b9e40f51 100644 --- a/bsp/phytium/board/phytium_cpu.h +++ b/bsp/phytium/board/phytium_cpu.h @@ -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 // ! diff --git a/bsp/phytium/board/secondary_cpu.c b/bsp/phytium/board/secondary_cpu.c index 1a9d03cac4..75e1eed168 100644 --- a/bsp/phytium/board/secondary_cpu.c +++ b/bsp/phytium/board/secondary_cpu.c @@ -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< +#include +#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 diff --git a/bsp/phytium/libraries/common/phytium_interrupt.h b/bsp/phytium/libraries/common/phytium_interrupt.h new file mode 100644 index 0000000000..33cc0c3b1f --- /dev/null +++ b/bsp/phytium/libraries/common/phytium_interrupt.h @@ -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 \ No newline at end of file diff --git a/bsp/phytium/libraries/drivers/drv_can.c b/bsp/phytium/libraries/drivers/drv_can.c index ca2bafa443..f03f5214be 100644 --- a/bsp/phytium/libraries/drivers/drv_can.c +++ b/bsp/phytium/libraries/drivers/drv_can.c @@ -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*/ diff --git a/bsp/phytium/libraries/drivers/drv_gpio.c b/bsp/phytium/libraries/drivers/drv_gpio.c index 2de4b8b1f3..8798485891 100644 --- a/bsp/phytium/libraries/drivers/drv_gpio.c +++ b/bsp/phytium/libraries/drivers/drv_gpio.c @@ -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 */ diff --git a/bsp/phytium/libraries/drivers/drv_i2c.c b/bsp/phytium/libraries/drivers/drv_i2c.c index 8f83e86a74..6ed2ff04c6 100644 --- a/bsp/phytium/libraries/drivers/drv_i2c.c +++ b/bsp/phytium/libraries/drivers/drv_i2c.c @@ -26,6 +26,10 @@ #include #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 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"); diff --git a/bsp/phytium/libraries/drivers/drv_qspi.c b/bsp/phytium/libraries/drivers/drv_qspi.c index 1aad45d600..db3e14c895 100644 --- a/bsp/phytium/libraries/drivers/drv_qspi.c +++ b/bsp/phytium/libraries/drivers/drv_qspi.c @@ -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; } diff --git a/bsp/phytium/libraries/drivers/drv_sdif.c b/bsp/phytium/libraries/drivers/drv_sdif.c index 63a750881b..8292d6230b 100644 --- a/bsp/phytium/libraries/drivers/drv_sdif.c +++ b/bsp/phytium/libraries/drivers/drv_sdif.c @@ -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); diff --git a/bsp/phytium/libraries/drivers/drv_spi.c b/bsp/phytium/libraries/drivers/drv_spi.c index a10b2419e9..5c59358a3f 100644 --- a/bsp/phytium/libraries/drivers/drv_spi.c +++ b/bsp/phytium/libraries/drivers/drv_spi.c @@ -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); diff --git a/bsp/phytium/libraries/drivers/drv_xmac.c b/bsp/phytium/libraries/drivers/drv_xmac.c index 07e599c724..37cdc98cf2 100644 --- a/bsp/phytium/libraries/drivers/drv_xmac.c +++ b/bsp/phytium/libraries/drivers/drv_xmac.c @@ -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); diff --git a/bsp/phytium/libraries/port/fdriver_port/fdrivers_port.c b/bsp/phytium/libraries/port/fdriver_port/fdrivers_port.c index f80f6a0475..fb767d6092 100644 --- a/bsp/phytium/libraries/port/fdriver_port/fdrivers_port.c +++ b/bsp/phytium/libraries/port/fdriver_port/fdrivers_port.c @@ -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); +} diff --git a/libcpu/aarch64/common/gicv3.c b/libcpu/aarch64/common/gicv3.c index ba602b2258..6dbd572a22 100644 --- a/libcpu/aarch64/common/gicv3.c +++ b/libcpu/aarch64/common/gicv3.c @@ -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(); diff --git a/libcpu/aarch64/common/gicv3.h b/libcpu/aarch64/common/gicv3.h index ff821c4219..d449774c5f 100644 --- a/libcpu/aarch64/common/gicv3.h +++ b/libcpu/aarch64/common/gicv3.h @@ -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);