Selaa lähdekoodia

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

* update smp 4
zhangyan 1 vuosi sitten
vanhempi
commit
81df7bcdde

+ 2 - 1
bsp/phytium/board/board.c

@@ -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();
 

+ 1 - 45
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
@@ -33,7 +30,6 @@
 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:
@@ -52,9 +48,6 @@ int phytium_cpu_id_mapping(int cpu_id)
 #else
     return (int)cpu_id;
 #endif
-#else
-    return (int)cpu_id;
-#endif
 }
 
 int rt_hw_cpu_id(void)
@@ -70,44 +63,7 @@ int rt_hw_cpu_id(void)
     return phytium_cpu_id_mapping(cpu_id);
 }
 
-#else
-
-int phytium_cpu_id_mapping(int cpu_id)
-{
-#if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)
-    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
-}
-
-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);
-}
+#if defined(TARGET_ARMV8_AARCH32)
 
 rt_uint64_t get_main_cpu_affval(void)
 {

+ 1 - 8
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 // !

+ 3 - 3
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<<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);

+ 150 - 0
bsp/phytium/libraries/common/phytium_interrupt.c

@@ -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

+ 17 - 0
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

+ 1 - 2
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*/

+ 2 - 4
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 */

+ 12 - 4
bsp/phytium/libraries/drivers/drv_i2c.c

@@ -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");

+ 10 - 11
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;
 }

+ 1 - 2
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);
 

+ 1 - 2
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);

+ 1 - 2
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);

+ 10 - 16
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);
+}

+ 5 - 115
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();

+ 115 - 0
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);