From 56f8527fdeaf4910b1eb5f01e6236793a68c0295 Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Sat, 10 Apr 2021 10:30:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=98=BE=E7=A4=BApage=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=94=B9=E5=90=8D=E4=B8=BA:=20list=5Fpage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/arm/cortex-a/page.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcpu/arm/cortex-a/page.c b/libcpu/arm/cortex-a/page.c index 5154f8a92b..f7e4ca2135 100644 --- a/libcpu/arm/cortex-a/page.c +++ b/libcpu/arm/cortex-a/page.c @@ -287,7 +287,7 @@ int rt_pages_free(void *addr, uint32_t size_bits) return real_free; } -void rt_pageinfo_dump(void) +void list_page(void) { int i; size_t total = 0; @@ -313,7 +313,7 @@ void rt_pageinfo_dump(void) rt_kprintf("free pages is %08x\n", total); rt_kprintf("-------------------------------\n"); } -MSH_CMD_EXPORT(rt_pageinfo_dump, show page info); +MSH_CMD_EXPORT(list_page, show page info); void rt_page_get_info(size_t *total_nr, size_t *free_nr) { -- Gitee From 773a85a54cb96b839ba1343039a2cfdd11fb9a8a Mon Sep 17 00:00:00 2001 From: shaojinchun Date: Sat, 10 Apr 2021 10:24:35 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=90=8C=E6=AD=A5master=E5=88=86=E6=94=AFc?= =?UTF-8?q?ortex-a=20gic=E5=92=8Cgtimer=E5=8A=9F=E8=83=BD=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libcpu/arm/cortex-a/cp15.h | 148 +--------- libcpu/arm/cortex-a/gic.c | 471 +++++++++++++++++++++++--------- libcpu/arm/cortex-a/gic.h | 43 ++- libcpu/arm/cortex-a/gtimer.c | 171 ++++++++++++ libcpu/arm/cortex-a/gtimer.h | 26 ++ libcpu/arm/cortex-a/interrupt.c | 160 ++++++++++- libcpu/arm/cortex-a/interrupt.h | 30 +- 7 files changed, 770 insertions(+), 279 deletions(-) create mode 100644 libcpu/arm/cortex-a/gtimer.c create mode 100644 libcpu/arm/cortex-a/gtimer.h diff --git a/libcpu/arm/cortex-a/cp15.h b/libcpu/arm/cortex-a/cp15.h index 1bbf76d3b1..dc77ec74c3 100644 --- a/libcpu/arm/cortex-a/cp15.h +++ b/libcpu/arm/cortex-a/cp15.h @@ -10,6 +10,15 @@ #ifndef __CP15_H__ #define __CP15_H__ +#define __get_cp(cp, op1, Rt, CRn, CRm, op2) \ + __asm__ volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_cp(cp, op1, Rt, CRn, CRm, op2) \ + __asm__ volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_cp64(cp, op1, Rt, CRm) \ + __asm__ volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_cp64(cp, op1, Rt, CRm) \ + __asm__ volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + unsigned long rt_cpu_get_smp_id(void); void rt_cpu_mmu_disable(void); @@ -21,143 +30,4 @@ void rt_cpu_icache_flush(void); void rt_cpu_vector_set_base(unsigned int addr); -#ifdef SOC_BCM283x - -#ifndef __STATIC_FORCEINLINE -#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline -#endif - -#define __WFI() __asm__ volatile ("wfi":::"memory") - -#define __WFE() __asm__ volatile ("wfe":::"memory") - -#define __SEV() __asm__ volatile ("sev") - -__STATIC_FORCEINLINE void __ISB(void) -{ - __asm__ volatile ("isb 0xF":::"memory"); -} - - -/** - \brief Data Synchronization Barrier - \details Acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__STATIC_FORCEINLINE void __DSB(void) -{ - __asm__ volatile ("dsb 0xF":::"memory"); -} - -/** - \brief Data Memory Barrier - \details Ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ - -__STATIC_FORCEINLINE void __DMB(void) -{ - __asm__ volatile ("dmb 0xF":::"memory"); -} - -static inline void send_ipi_msg(int cpu, int ipi_vector) -{ - IPI_MAILBOX_SET(cpu) = 1 << ipi_vector; -} - -static inline void setup_bootstrap_addr(int cpu, int addr) -{ - CORE_MAILBOX3_SET(cpu) = addr; -} - -static inline void enable_cpu_ipi_intr(int cpu) -{ - COREMB_INTCTL(cpu) = IPI_MAILBOX_INT_MASK; -} - -static inline void enable_cpu_timer_intr(int cpu) -{ - CORETIMER_INTCTL(cpu) = 0x8; -} - -static inline void enable_cntv(void) -{ - rt_uint32_t cntv_ctl; - cntv_ctl = 1; - asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL -} - -static inline void disable_cntv(void) -{ - rt_uint32_t cntv_ctl; - cntv_ctl = 0; - asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL -} - -static inline void mask_cntv(void) -{ - rt_uint32_t cntv_ctl; - cntv_ctl = 2; - asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL -} - -static inline void unmask_cntv(void) -{ - rt_uint32_t cntv_ctl; - cntv_ctl = 1; - asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL -} - -static inline rt_uint64_t read_cntvct(void) -{ - rt_uint32_t val,val1; - asm volatile ("mrrc p15, 1, %0, %1, c14" : "=r" (val),"=r" (val1)); - return (val); -} - -static inline rt_uint64_t read_cntvoff(void) -{ - - rt_uint64_t val; - asm volatile ("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val)); - return (val); -} - -static inline rt_uint32_t read_cntv_tval(void) -{ - rt_uint32_t val; - asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val)); - return val; -} - - -static inline void write_cntv_tval(rt_uint32_t val) -{ - asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val)); - return; -} - -static inline rt_uint32_t read_cntfrq(void) -{ - rt_uint32_t val; - asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val)); - return val; -} - - -static inline rt_uint32_t read_cntctrl(void) -{ - rt_uint32_t val; - asm volatile ("mrc p15, 0, %0, c14, c1, 0" : "=r"(val)); - return val; -} - -static inline uint32_t write_cntctrl(uint32_t val) -{ - - asm volatile ("mcr p15, 0, %0, c14, c1, 0" : :"r"(val)); - return val; -} -#endif - #endif diff --git a/libcpu/arm/cortex-a/gic.c b/libcpu/arm/cortex-a/gic.c index fac822a2db..00beebb138 100644 --- a/libcpu/arm/cortex-a/gic.c +++ b/libcpu/arm/cortex-a/gic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -28,29 +28,35 @@ struct arm_gic /* 'ARM_GIC_MAX_NR' is the number of cores */ static struct arm_gic _gic_table[ARM_GIC_MAX_NR]; -#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00) -#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04) -#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08) -#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0c) -#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10) -#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14) -#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18) - -#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000) -#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004) -#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080 + ((n)/32) * 4) -#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4) -#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4) -#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200 + ((n)/32) * 4) -#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + ((n)/32) * 4) -#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300 + ((n)/32) * 4) -#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380 + ((n)/32) * 4) -#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + ((n)/4) * 4) -#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + ((n)/4) * 4) -#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00 + ((n)/16) * 4) -#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00) -#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10 + ((n)/4) * 4) -#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8) +/** Macro to access the Generic Interrupt Controller Interface (GICC) +*/ +#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00U) +#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04U) +#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08U) +#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0cU) +#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10U) +#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14U) +#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18U) +#define GIC_CPU_IIDR(hw_base) __REG32((hw_base) + 0xFCU) + +/** Macro to access the Generic Interrupt Controller Distributor (GICD) +*/ +#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000U) +#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004U) +#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100U + ((n)/32U) * 4U) +#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200U + ((n)/32U) * 4U) +#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300U + ((n)/32U) * 4U) +#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380U + ((n)/32U) * 4U) +#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400U + ((n)/4U) * 4U) +#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800U + ((n)/4U) * 4U) +#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00U + ((n)/16U) * 4U) +#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00U) +#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10U + ((n)/4U) * 4U) +#define GIC_DIST_SPENDSGI(hw_base, n) __REG32((hw_base) + 0xf20U + ((n)/4U) * 4U) +#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8U) static unsigned int _gic_max_irq; @@ -67,12 +73,12 @@ int arm_gic_get_active_irq(rt_uint32_t index) void arm_gic_ack(rt_uint32_t index, int irq) { - rt_uint32_t mask = 1 << (irq % 32); + rt_uint32_t mask = 1U << (irq % 32U); RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); + RT_ASSERT(irq >= 0U); GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq; @@ -80,36 +86,136 @@ void arm_gic_ack(rt_uint32_t index, int irq) void arm_gic_mask(rt_uint32_t index, int irq) { - rt_uint32_t mask = 1 << (irq % 32); + rt_uint32_t mask = 1U << (irq % 32U); RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); + RT_ASSERT(irq >= 0U); GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; } -void arm_gic_clear_pending(rt_uint32_t index, int irq) +void arm_gic_umask(rt_uint32_t index, int irq) { - rt_uint32_t mask = 1 << (irq % 32); + rt_uint32_t mask = 1U << (irq % 32U); RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); + RT_ASSERT(irq >= 0U); - GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; +} + +rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq) +{ + rt_uint32_t pend; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; + /* No CPU identification offered */ + if (pend != 0U) + { + pend = 1U; + } + else + { + pend = 0U; + } + } + + return (pend); +} + +void arm_gic_set_pending_irq(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U); + } + else + { + /* INTID 0-15 Software Generated Interrupt */ + /* Forward the interrupt to the CPU interface that requested it */ + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U); + } +} + +void arm_gic_clear_pending_irq(rt_uint32_t index, int irq) +{ + rt_uint32_t mask; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + if (irq >= 16U) + { + mask = 1U << (irq % 32U); + GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; + } + else + { + mask = 1U << ((irq % 4U) * 8U); + GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask; + } +} + +void arm_gic_set_configuration(rt_uint32_t index, int irq, uint32_t config) +{ + rt_uint32_t icfgr; + rt_uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq); + shift = (irq % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= (config << shift); + + GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr; +} + +rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> ((irq % 16U) >> 1U)); } void arm_gic_clear_active(rt_uint32_t index, int irq) { - rt_uint32_t mask = 1 << (irq % 32); + rt_uint32_t mask = 1U << (irq % 32U); RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); + RT_ASSERT(irq >= 0U); GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask; } @@ -122,79 +228,150 @@ void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask) RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); + RT_ASSERT(irq >= 0U); old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq); - old_tgt &= ~(0x0FFUL << ((irq % 4)*8)); - old_tgt |= cpumask << ((irq % 4)*8); + old_tgt &= ~(0x0FFUL << ((irq % 4U)*8U)); + old_tgt |= cpumask << ((irq % 4U)*8U); GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt; } -void arm_gic_umask(rt_uint32_t index, int irq) +rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; +} + +void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority) { - rt_uint32_t mask = 1 << (irq % 32); + rt_uint32_t mask; RT_ASSERT(index < ARM_GIC_MAX_NR); irq = irq - _gic_table[index].offset; - RT_ASSERT(irq >= 0); + RT_ASSERT(irq >= 0U); - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask; + mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq); + mask &= ~(0xFFUL << ((irq % 4U) * 8U)); + mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U)); + GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask; } -void arm_gic_dump_type(rt_uint32_t index) +rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq) { - unsigned int gic_type; + RT_ASSERT(index < ARM_GIC_MAX_NR); - gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); - rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", - (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf, - _gic_table[index].dist_hw_base, - _gic_max_irq, - gic_type & (1 << 10) ? "has" : "no", - gic_type); + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL; } -void arm_gic_dump(rt_uint32_t index) +void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority) { - unsigned int i, k; + RT_ASSERT(index < ARM_GIC_MAX_NR); - k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); - rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); - rt_kprintf("--- hw mask ---\n"); - for (i = 0; i < _gic_max_irq / 32; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, - i * 32)); - } - rt_kprintf("\n--- hw pending ---\n"); - for (i = 0; i < _gic_max_irq / 32; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, - i * 32)); - } - rt_kprintf("\n--- hw active ---\n"); - for (i = 0; i < _gic_max_irq / 32; i++) - { - rt_kprintf("0x%08x, ", - GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, - i * 32)); - } - rt_kprintf("\n"); + /* set priority mask */ + GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base) = priority & 0xFFUL; +} + +rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base); +} + +void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point) +{ + GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base) = binary_point & 0x7U; +} + +rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index) +{ + return GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base); +} + +rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq) +{ + rt_uint32_t pending; + rt_uint32_t active; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; + + return ((active << 1U) | pending); +} + +void arm_gic_send_sgi(rt_uint32_t index, int irq, rt_uint32_t target_list, rt_uint32_t filter_list) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = + ((filter_list & 0x3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (irq & 0x0FUL); +} + +rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); +} + +rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base); +} + +void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group) +{ + uint32_t igroupr; + uint32_t shift; + + RT_ASSERT(index < ARM_GIC_MAX_NR); + RT_ASSERT(group <= 1U); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq); + shift = (irq % 32U); + igroupr &= (~(1U << shift)); + igroupr |= ((group & 0x1U) << shift); + + GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr; +} + +rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq) +{ + RT_ASSERT(index < ARM_GIC_MAX_NR); + + irq = irq - _gic_table[index].offset; + RT_ASSERT(irq >= 0U); + + return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL; } -#ifdef RT_USING_FINSH -#include -FINSH_FUNCTION_EXPORT_ALIAS(arm_gic_dump, gic, show gic status); -#endif int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) { unsigned int gic_type, i; - rt_uint32_t cpumask = 1 << 0; + rt_uint32_t cpumask = 1U << 0U; RT_ASSERT(index < ARM_GIC_MAX_NR); @@ -203,50 +380,66 @@ int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start) /* Find out how many interrupts are supported. */ gic_type = GIC_DIST_TYPE(dist_base); - _gic_max_irq = ((gic_type & 0x1f) + 1) * 32; + _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U; /* * The GIC only supports up to 1020 interrupt sources. * Limit this to either the architected maximum, or the * platform maximum. */ - if (_gic_max_irq > 1020) - _gic_max_irq = 1020; + if (_gic_max_irq > 1020U) + { + _gic_max_irq = 1020U; + } if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */ + { _gic_max_irq = ARM_GIC_NR_IRQS; + } - cpumask |= cpumask << 8; - cpumask |= cpumask << 16; - cpumask |= cpumask << 24; + cpumask |= cpumask << 8U; + cpumask |= cpumask << 16U; + cpumask |= cpumask << 24U; - GIC_DIST_CTRL(dist_base) = 0x0; + GIC_DIST_CTRL(dist_base) = 0x0U; /* Set all global interrupts to be level triggered, active low. */ - for (i = 32; i < _gic_max_irq; i += 16) - GIC_DIST_CONFIG(dist_base, i) = 0x0; + for (i = 32U; i < _gic_max_irq; i += 16U) + { + GIC_DIST_CONFIG(dist_base, i) = 0x0U; + } /* Set all global interrupts to this CPU only. */ - for (i = 32; i < _gic_max_irq; i += 4) + for (i = 32U; i < _gic_max_irq; i += 4U) + { GIC_DIST_TARGET(dist_base, i) = cpumask; + } /* Set priority on all interrupts. */ - for (i = 0; i < _gic_max_irq; i += 4) - GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0; + for (i = 0U; i < _gic_max_irq; i += 4U) + { + GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0U; + } /* Disable all interrupts. */ - for (i = 0; i < _gic_max_irq; i += 32) - GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff; + for (i = 0U; i < _gic_max_irq; i += 32U) + { + GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffffU; + } -#if 0 /* All interrupts defaults to IGROUP1(IRQ). */ + /* for (i = 0; i < _gic_max_irq; i += 32) - GIC_DIST_IGROUP(dist_base, i) = 0xffffffff; -#endif - for (i = 0; i < _gic_max_irq; i += 32) - GIC_DIST_IGROUP(dist_base, i) = 0; + { + GIC_DIST_IGROUP(dist_base, i) = 0xffffffffU; + } + */ + for (i = 0U; i < _gic_max_irq; i += 32U) + { + GIC_DIST_IGROUP(dist_base, i) = 0U; + } /* Enable group0 and group1 interrupt forwarding. */ - GIC_DIST_CTRL(dist_base) = 0x01; + GIC_DIST_CTRL(dist_base) = 0x01U; return 0; } @@ -255,47 +448,69 @@ int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base) { RT_ASSERT(index < ARM_GIC_MAX_NR); - if (_gic_table[index].cpu_hw_base == 0) + if (!_gic_table[index].cpu_hw_base) + { _gic_table[index].cpu_hw_base = cpu_base; + } + cpu_base = _gic_table[index].cpu_hw_base; - GIC_CPU_PRIMASK(_gic_table[index].cpu_hw_base) = 0xf0; - GIC_CPU_BINPOINT(_gic_table[index].cpu_hw_base) = 0x7; + GIC_CPU_PRIMASK(cpu_base) = 0xf0U; + GIC_CPU_BINPOINT(cpu_base) = 0x7U; /* Enable CPU interrupt */ - GIC_CPU_CTRL(_gic_table[index].cpu_hw_base) = 0x01; + GIC_CPU_CTRL(cpu_base) = 0x01U; return 0; } -void arm_gic_set_group(rt_uint32_t index, int vector, int group) +void arm_gic_dump_type(rt_uint32_t index) +{ + unsigned int gic_type; + + gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base); + rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n", + (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4U) & 0xfUL, + _gic_table[index].dist_hw_base, + _gic_max_irq, + gic_type & (1U << 10U) ? "has" : "no", + gic_type); +} + +void arm_gic_dump(rt_uint32_t index) { - /* As for GICv2, there are only group0 and group1. */ - RT_ASSERT(group <= 1); - RT_ASSERT(vector < _gic_max_irq); + unsigned int i, k; - if (group == 0) + k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base); + rt_kprintf("--- high pending priority: %d(%08x)\n", k, k); + rt_kprintf("--- hw mask ---\n"); + for (i = 0U; i < _gic_max_irq / 32U; i++) { - GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, - vector) &= ~(1 << (vector % 32)); + rt_kprintf("0x%08x, ", + GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, + i * 32U)); } - else if (group == 1) + rt_kprintf("\n--- hw pending ---\n"); + for (i = 0U; i < _gic_max_irq / 32U; i++) { - GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, - vector) |= (1 << (vector % 32)); + rt_kprintf("0x%08x, ", + GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, + i * 32U)); } + rt_kprintf("\n--- hw active ---\n"); + for (i = 0U; i < _gic_max_irq / 32U; i++) + { + rt_kprintf("0x%08x, ", + GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, + i * 32U)); + } + rt_kprintf("\n"); } -#ifdef RT_USING_SMP -void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) - { - /* note: ipi_vector maybe different with irq_vector */ - GIC_DIST_SOFTINT(_gic_table[0].dist_hw_base) = (cpu_mask << 16) | ipi_vector; -} -#endif - -#ifdef RT_USING_SMP -void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) +long gic_dump(void) { - /* note: ipi_vector maybe different with irq_vector */ - rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); + arm_gic_dump_type(0); + arm_gic_dump(0); + + return 0; } -#endif +MSH_CMD_EXPORT(gic_dump, show gic status); + diff --git a/libcpu/arm/cortex-a/gic.h b/libcpu/arm/cortex-a/gic.h index f90bc0dae2..e74b760f45 100644 --- a/libcpu/arm/cortex-a/gic.h +++ b/libcpu/arm/cortex-a/gic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2020, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -14,19 +14,46 @@ #include #include -int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); -int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base); +int arm_gic_get_active_irq(rt_uint32_t index); +void arm_gic_ack(rt_uint32_t index, int irq); void arm_gic_mask(rt_uint32_t index, int irq); void arm_gic_umask(rt_uint32_t index, int irq); -void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); -void arm_gic_set_group(rt_uint32_t index, int vector, int group); -int arm_gic_get_active_irq(rt_uint32_t index); -void arm_gic_ack(rt_uint32_t index, int irq); +rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq); +void arm_gic_set_pending_irq(rt_uint32_t index, int irq); +void arm_gic_clear_pending_irq(rt_uint32_t index, int irq); + +void arm_gic_set_configuration(rt_uint32_t index, int irq, uint32_t config); +rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq); void arm_gic_clear_active(rt_uint32_t index, int irq); -void arm_gic_clear_pending(rt_uint32_t index, int irq); + +void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask); +rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq); + +void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority); +rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq); + +void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority); +rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index); + +void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point); +rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index); + +rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq); + +void arm_gic_send_sgi(rt_uint32_t index, int irq, rt_uint32_t target_list, rt_uint32_t filter_list); + +rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index); + +rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index); + +void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group); +rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq); + +int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start); +int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base); void arm_gic_dump_type(rt_uint32_t index); void arm_gic_dump(rt_uint32_t index); diff --git a/libcpu/arm/cortex-a/gtimer.c b/libcpu/arm/cortex-a/gtimer.c new file mode 100644 index 0000000000..b193a1593d --- /dev/null +++ b/libcpu/arm/cortex-a/gtimer.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-03-30 huijie.feng first version + */ + +#include "cp15.h" +#include + +/** Set CNTFRQ + * This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ). + * @param value: CNTFRQ Register value to set + */ +static inline void __set_cntfrq(rt_uint32_t value) +{ + __set_cp(15, 0, value, 14, 0, 0); +} + +/** Get CNTFRQ + * This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ). + * return CNTFRQ Register value + */ +static inline rt_uint32_t __get_cntfrq(void) +{ + rt_uint32_t result; + __get_cp(15, 0, result, 14, 0 , 0); + return result; +} + +/** Set CNTP_TVAL + * This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + * param value: CNTP_TVAL Register value to set + */ +static inline void __set_cntp_tval(rt_uint32_t value) +{ + __set_cp(15, 0, value, 14, 2, 0); +} + +/** Get CNTP_TVAL + * This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + * return CNTP_TVAL Register value + */ +static inline rt_uint32_t __get_cntp_tval(void) +{ + rt_uint32_t result; + __get_cp(15, 0, result, 14, 2, 0); + return result; +} + +/** Get CNTPCT + * This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT). + * return CNTPCT Register value + */ +static inline rt_uint64_t __get_cntpct(void) +{ + rt_uint64_t result; + __get_cp64(15, 0, result, 14); + return result; +} + +/** Set CNTP_CVAL + * This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + * param value: CNTP_CVAL Register value to set +*/ +static inline void __set_cntp_cval(rt_uint64_t value) +{ + __set_cp64(15, 2, value, 14); +} + +/** Get CNTP_CVAL + * This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + * return CNTP_CVAL Register value + */ +static inline rt_uint64_t __get_cntp_cval(void) +{ + rt_uint64_t result; + __get_cp64(15, 2, result, 14); + return result; +} + +/** Set CNTP_CTL + * This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + * param value: CNTP_CTL Register value to set + */ +static inline void __set_cntp_ctl(uint32_t value) +{ + __set_cp(15, 0, value, 14, 2, 1); +} + +/** Get CNTP_CTL register + * return CNTP_CTL Register value + */ +static inline rt_uint32_t __get_cntp_ctl(void) +{ + rt_uint32_t result; + __get_cp(15, 0, result, 14, 2, 1); + return result; +} + +/** Configures the frequency the timer shall run at. + * param value The timer frequency in Hz. + */ +void gtimer_set_counter_frequency(rt_uint32_t value) +{ + __set_cntfrq(value); + __asm__ volatile ("isb 0xF":::"memory"); +} + +/** Sets the reset value of the timer. + * param value: The value the timer is loaded with. + */ +void gtimer_set_load_value(rt_uint32_t value) +{ + __set_cntp_tval(value); + __asm__ volatile ("isb 0xF":::"memory"); +} + +/** Get the current counter value. + * return Current counter value. + */ +rt_uint32_t gtimer_get_current_value(void) +{ + return(__get_cntp_tval()); +} + +/** Get the current physical counter value. + * return Current physical counter value. + */ +rt_uint64_t gtimer_get_current_physical_value(void) +{ + return(__get_cntpct()); +} + +/** Set the physical compare value. + * param value: New physical timer compare value. + */ +void gtimer_set_physical_compare_value(rt_uint64_t value) +{ + __set_cntp_cval(value); + __asm__ volatile ("isb 0xF":::"memory"); +} + +/** Get the physical compare value. + * return Physical compare value. + */ +rt_uint64_t gtimer_get_physical_compare_value(void) +{ + return(__get_cntp_cval()); +} + +/** Configure the timer by setting the control value. + * param value: New timer control value. + */ +void gtimer_set_control(rt_uint32_t value) +{ + __set_cntp_ctl(value); + __asm__ volatile ("isb 0xF":::"memory"); +} + +/** Get the control value. + * return Control value. + */ +rt_uint32_t gtimer_get_control(void) +{ + return(__get_cntp_ctl()); +} + diff --git a/libcpu/arm/cortex-a/gtimer.h b/libcpu/arm/cortex-a/gtimer.h new file mode 100644 index 0000000000..160d0cefde --- /dev/null +++ b/libcpu/arm/cortex-a/gtimer.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-03-30 huijie.feng first version + */ + +#ifndef __GTIMER_H__ +#define __GTIMER_H__ + +#include + +void gtimer_set_counter_frequency(rt_uint32_t value); +void gtimer_set_load_value(rt_uint32_t value); +rt_uint32_t gtimer_get_current_value(void); +rt_uint64_t gtimer_get_current_physical_value(void); +void gtimer_set_physical_compare_value(rt_uint64_t value); +rt_uint64_t gtimer_get_physical_compare_value(void); +void gtimer_set_control(rt_uint32_t value); +rt_uint32_t gtimer_get_control(void); + +#endif + diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c index 85cf1de23e..a93d816d21 100644 --- a/libcpu/arm/cortex-a/interrupt.c +++ b/libcpu/arm/cortex-a/interrupt.c @@ -11,7 +11,6 @@ #include #include -#include #include "interrupt.h" #include "gic.h" @@ -169,7 +168,7 @@ if (vector < 32) int rt_hw_interrupt_get_irq(void) { #ifndef SOC_BCM283x - return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK; + return arm_gic_get_active_irq(0); #else return 0; #endif @@ -186,6 +185,149 @@ void rt_hw_interrupt_ack(int vector) #endif } +/** + * This function set interrupt CPU targets. + * @param vector: the interrupt number + * cpu_mask: target cpus mask, one bit for one core + */ +void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask) +{ + arm_gic_set_cpu(0, vector, cpu_mask); +} + +/** + * This function get interrupt CPU targets. + * @param vector: the interrupt number + * @return target cpus mask, one bit for one core + */ +unsigned int rt_hw_interrupt_get_target_cpus(int vector) +{ + return arm_gic_get_target_cpu(0, vector); +} + +/** + * This function set interrupt triger mode. + * @param vector: the interrupt number + * mode: interrupt triger mode; 0: level triger, 1: edge triger + */ +void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode) +{ + arm_gic_set_configuration(0, vector, mode); +} + +/** + * This function get interrupt triger mode. + * @param vector: the interrupt number + * @return interrupt triger mode; 0: level triger, 1: edge triger + */ +unsigned int rt_hw_interrupt_get_triger_mode(int vector) +{ + return arm_gic_get_configuration(0, vector); +} + +/** + * This function set interrupt pending flag. + * @param vector: the interrupt number + */ +void rt_hw_interrupt_set_pending(int vector) +{ + arm_gic_set_pending_irq(0, vector); +} + +/** + * This function get interrupt pending flag. + * @param vector: the interrupt number + * @return interrupt pending flag, 0: not pending; 1: pending + */ +unsigned int rt_hw_interrupt_get_pending(int vector) +{ + return arm_gic_get_pending_irq(0, vector); +} + +/** + * This function clear interrupt pending flag. + * @param vector: the interrupt number + */ +void rt_hw_interrupt_clear_pending(int vector) +{ + arm_gic_clear_pending_irq(0, vector); +} + +/** + * This function set interrupt priority value. + * @param vector: the interrupt number + * priority: the priority of interrupt to set + */ +void rt_hw_interrupt_set_priority(int vector, unsigned int priority) +{ + arm_gic_set_priority(0, vector, priority); +} + +/** + * This function get interrupt priority. + * @param vector: the interrupt number + * @return interrupt priority value + */ +unsigned int rt_hw_interrupt_get_priority(int vector) +{ + return arm_gic_get_priority(0, vector); +} + +/** + * This function set priority masking threshold. + * @param priority: priority masking threshold + */ +void rt_hw_interrupt_set_priority_mask(unsigned int priority) +{ + arm_gic_set_interface_prior_mask(0, priority); +} + +/** + * This function get priority masking threshold. + * @param none + * @return priority masking threshold + */ +unsigned int rt_hw_interrupt_get_priority_mask(void) +{ + return arm_gic_get_interface_prior_mask(0); +} + +/** + * This function set priority grouping field split point. + * @param bits: priority grouping field split point + * @return 0: success; -1: failed + */ +int rt_hw_interrupt_set_prior_group_bits(unsigned int bits) +{ + int status; + + if (bits < 8) + { + arm_gic_set_binary_point(0, (7 - bits)); + status = 0; + } + else + { + status = -1; + } + + return (status); +} + +/** + * This function get priority grouping field split point. + * @param none + * @return priority grouping field split point + */ +unsigned int rt_hw_interrupt_get_prior_group_bits(void) +{ + unsigned int bp; + + bp = arm_gic_get_binary_point(0) & 0x07; + + return (7 - bp); +} + /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number @@ -213,3 +355,17 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, return old_handler; } + +#ifdef RT_USING_SMP +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) +{ + arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0); +} + +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler) +{ + /* note: ipi_vector maybe different with irq_vector */ + rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER"); +} +#endif + diff --git a/libcpu/arm/cortex-a/interrupt.h b/libcpu/arm/cortex-a/interrupt.h index 442187edee..1c4199c61b 100644 --- a/libcpu/arm/cortex-a/interrupt.h +++ b/libcpu/arm/cortex-a/interrupt.h @@ -17,9 +17,10 @@ #define INT_IRQ 0x00 #define INT_FIQ 0x01 -void rt_hw_vector_init(void); +#define IRQ_MODE_TRIG_LEVEL (0x00) /* Trigger: level triggered interrupt */ +#define IRQ_MODE_TRIG_EDGE (0x01) /* Trigger: edge triggered interrupt */ -void rt_hw_interrupt_control(int vector, int priority, int route); +void rt_hw_vector_init(void); void rt_hw_interrupt_init(void); void rt_hw_interrupt_mask(int vector); @@ -28,7 +29,32 @@ void rt_hw_interrupt_umask(int vector); int rt_hw_interrupt_get_irq(void); void rt_hw_interrupt_ack(int vector); +void rt_hw_interrupt_set_target_cpus(int vector, unsigned int cpu_mask); +unsigned int rt_hw_interrupt_get_target_cpus(int vector); + +void rt_hw_interrupt_set_triger_mode(int vector, unsigned int mode); +unsigned int rt_hw_interrupt_get_triger_mode(int vector); + +void rt_hw_interrupt_set_pending(int vector); +unsigned int rt_hw_interrupt_get_pending(int vector); +void rt_hw_interrupt_clear_pending(int vector); + +void rt_hw_interrupt_set_priority(int vector, unsigned int priority); +unsigned int rt_hw_interrupt_get_priority(int vector); + +void rt_hw_interrupt_set_priority_mask(unsigned int priority); +unsigned int rt_hw_interrupt_get_priority_mask(void); + +int rt_hw_interrupt_set_prior_group_bits(unsigned int bits); +unsigned int rt_hw_interrupt_get_prior_group_bits(void); + rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name); +#ifdef RT_USING_SMP +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask); +void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler); #endif + +#endif + -- Gitee