[libcpu/aarch64] add gicv3 support and bsp/rockchip/rk3568 (#5722)

* [libcpu/aarch64] add smp support

* [libcpu/aarch64] rt_hw_trap_irq get irq instead of iar when using gicv2

* [libcpu/aarch64] disable irq/fiq when switch thread

* [libcpu/aarch64] add gtimer frq set and stack align

* [libcpu/aarch64] add gicv3 support and bsp/rockchip/rk3568
This commit is contained in:
GUI
2022-03-29 11:08:25 +08:00
committed by GitHub
parent d23493d05d
commit f587a55bc2
57 changed files with 4108 additions and 921 deletions
-4
View File
@@ -6,10 +6,6 @@ Import('rtconfig')
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
if not GetDepend('BSP_USING_GIC'):
SrcRemove(src, 'gic.c')
CPPPATH = [cwd]
group = DefineGroup('common', src, depend = [''], CPPPATH = CPPPATH)
+40 -28
View File
@@ -9,20 +9,25 @@
* 2014-04-03 Grissiom many enhancements
* 2018-11-22 Jesven add rt_hw_ipi_send()
* add rt_hw_ipi_handler_install()
* 2022-03-08 GuEe-GUI add BSP bind SPI CPU self support
*/
#include <rthw.h>
#include <rtthread.h>
#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2)
#include <gic.h>
#include <cpuport.h>
#include <board.h>
struct arm_gic
{
rt_uint64_t offset; /* the first interrupt index in the vector table */
rt_uint64_t dist_hw_base; /* the base address of the gic distributor */
rt_uint64_t cpu_hw_base; /* the base addrees of the gic cpu interface */
rt_uint64_t cpu_hw_base; /* the base address of the gic cpu interface */
};
/* 'ARM_GIC_MAX_NR' is the number of cores */
@@ -30,33 +35,33 @@ static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
/** 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)
#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) __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)
#define GIC_DIST_CTRL(hw_base) HWREG32((hw_base) + 0x000U)
#define GIC_DIST_TYPE(hw_base) HWREG32((hw_base) + 0x004U)
#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)
static unsigned int _gic_max_irq;
@@ -179,7 +184,7 @@ void arm_gic_clear_pending_irq(rt_uint64_t index, int irq)
}
}
void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config)
void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config)
{
rt_uint64_t icfgr;
rt_uint64_t shift;
@@ -323,6 +328,8 @@ void arm_gic_send_sgi(rt_uint64_t index, int irq, rt_uint64_t target_list, rt_ui
GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) =
((filter_list & 0x3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (irq & 0x0FUL);
__DSB();
}
rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index)
@@ -341,8 +348,8 @@ rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index)
void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group)
{
uint32_t igroupr;
uint32_t shift;
rt_uint32_t igroupr;
rt_uint32_t shift;
RT_ASSERT(index < ARM_GIC_MAX_NR);
RT_ASSERT(group <= 1U);
@@ -373,6 +380,10 @@ int arm_gic_dist_init(rt_uint64_t index, rt_uint64_t dist_base, int irq_start)
unsigned int gic_type, i;
rt_uint64_t cpumask = 1U << 0U;
#ifdef ARM_SPI_BIND_CPU_ID
cpumask = 1U << ARM_SPI_BIND_CPU_ID;
#endif
RT_ASSERT(index < ARM_GIC_MAX_NR);
_gic_table[index].dist_hw_base = dist_base;
@@ -502,3 +513,4 @@ long gic_dump(void)
}
MSH_CMD_EXPORT(gic_dump, show gic status);
#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) */
+6 -4
View File
@@ -11,9 +11,9 @@
#ifndef __GIC_H__
#define __GIC_H__
#include <rthw.h>
#include <stdint.h>
#include <board.h>
#include <rtdef.h>
#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV2)
int arm_gic_get_active_irq(rt_uint64_t index);
void arm_gic_ack(rt_uint64_t index, int irq);
@@ -25,7 +25,7 @@ rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq);
void arm_gic_set_pending_irq(rt_uint64_t index, int irq);
void arm_gic_clear_pending_irq(rt_uint64_t index, int irq);
void arm_gic_set_configuration(rt_uint64_t index, int irq, uint32_t config);
void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config);
rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq);
void arm_gic_clear_active(rt_uint64_t index, int irq);
@@ -59,5 +59,7 @@ int arm_gic_cpu_init(rt_uint64_t index, rt_uint64_t cpu_base);
void arm_gic_dump_type(rt_uint64_t index);
void arm_gic_dump(rt_uint64_t index);
#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV2) */
#endif
File diff suppressed because it is too large Load Diff
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2013-07-20 Bernard first version
* 2014-04-03 Grissiom many enhancements
* 2018-11-22 Jesven add rt_hw_ipi_send()
* add rt_hw_ipi_handler_install()
*/
#ifndef __GICV3_H__
#define __GICV3_H__
#include <rtdef.h>
#if defined(BSP_USING_GIC) && defined(BSP_USING_GICV3)
#define GICV3_ROUTED_TO_ALL 1UL
#define GICV3_ROUTED_TO_SPEC 0UL
int arm_gic_get_active_irq(rt_uint64_t index);
void arm_gic_ack(rt_uint64_t index, int irq);
void arm_gic_mask(rt_uint64_t index, int irq);
void arm_gic_umask(rt_uint64_t index, int irq);
rt_uint64_t arm_gic_get_pending_irq(rt_uint64_t index, int irq);
void arm_gic_set_pending_irq(rt_uint64_t index, int irq);
void arm_gic_clear_pending_irq(rt_uint64_t index, int irq);
void arm_gic_set_configuration(rt_uint64_t index, int irq, rt_uint32_t config);
rt_uint64_t arm_gic_get_configuration(rt_uint64_t index, int irq);
void arm_gic_clear_active(rt_uint64_t index, int irq);
void arm_gic_set_cpu(rt_uint64_t index, int irq, unsigned int cpumask);
rt_uint64_t arm_gic_get_target_cpu(rt_uint64_t index, int irq);
void arm_gic_set_priority(rt_uint64_t index, int irq, rt_uint64_t priority);
rt_uint64_t arm_gic_get_priority(rt_uint64_t index, int irq);
void arm_gic_set_interface_prior_mask(rt_uint64_t index, rt_uint64_t priority);
rt_uint64_t arm_gic_get_interface_prior_mask(rt_uint64_t index);
void arm_gic_set_binary_point(rt_uint64_t index, rt_uint64_t binary_point);
rt_uint64_t arm_gic_get_binary_point(rt_uint64_t index);
rt_uint64_t arm_gic_get_irq_status(rt_uint64_t index, int irq);
#ifdef RT_USING_SMP
void arm_gic_send_affinity_sgi(rt_uint64_t index, int irq, rt_uint64_t cpu_masks[], rt_uint64_t routing_mode);
#endif
rt_uint64_t arm_gic_get_high_pending_irq(rt_uint64_t index);
rt_uint64_t arm_gic_get_interface_id(rt_uint64_t index);
void arm_gic_set_group(rt_uint64_t index, int irq, rt_uint64_t group);
rt_uint64_t arm_gic_get_group(rt_uint64_t index, int irq);
int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id);
int arm_gic_cpu_interface_address_set(rt_uint64_t index, rt_uint64_t interface_addr, int cpu_id);
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);
void arm_gic_dump_type(rt_uint64_t index);
void arm_gic_dump(rt_uint64_t index);
#endif /* defined(BSP_USING_GIC) && defined(BSP_USING_GICV3) */
#endif
+10 -1
View File
@@ -13,6 +13,7 @@
#include <rtthread.h>
#include "interrupt.h"
#include "gic.h"
#include "gicv3.h"
#include "armv8.h"
#include "mmu.h"
#include "cpuport.h"
@@ -52,6 +53,9 @@ void rt_hw_interrupt_init(void)
/* initialize ARM GIC */
arm_gic_dist_init(0, platform_get_gic_dist_base(), GIC_IRQ_START);
arm_gic_cpu_init(0, platform_get_gic_cpu_base());
#ifdef BSP_USING_GICV3
arm_gic_redist_init(0, platform_get_gic_redist_base());
#endif
#endif
}
@@ -346,7 +350,11 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
{
#ifdef BSP_USING_GIC
#ifdef BSP_USING_GICV2
arm_gic_send_sgi(0, ipi_vector, cpu_mask, 0);
#else
arm_gic_send_affinity_sgi(0, ipi_vector, (rt_uint64_t *)&cpu_mask, GICV3_ROUTED_TO_SPEC);
#endif
#else
int i;
@@ -359,8 +367,9 @@ void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
IPI_MAILBOX_SET(i) = 1 << ipi_vector;
}
}
#endif
__DSB();
#endif
}
void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
+11 -3
View File
@@ -29,11 +29,19 @@ static psci_call_handle psci_call = psci_smc_call;
static uint64_t shutdown_args[3] = {0, 0, 0};
static uint64_t reboot_args[3] = {0, 0, 0};
void arm_psci_init(uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args)
void arm_psci_init(uint64_t method, uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args)
{
if (rt_hw_get_current_el() < 2)
switch (method)
{
psci_call = psci_hvc_call;
case PSCI_METHOD_SMC:
psci_call = psci_smc_call;
break;
case PSCI_METHOD_HVC:
if (rt_hw_get_current_el() < 2)
{
psci_call = psci_hvc_call;
}
break;
}
if (platform_shutdown_args != RT_NULL)
+4 -1
View File
@@ -18,6 +18,9 @@
*/
#define PSCI_VER_0_2 0x00000002
#define PSCI_METHOD_SMC 3
#define PSCI_METHOD_HVC 2
/* PSCI 0.2 interface */
#define PSCI_0_2_FN_BASE 0x84000000
#define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n))
@@ -114,7 +117,7 @@
#define PSCI_RET_DISABLED (-8)
#define PSCI_RET_INVALID_ADDRESS (-9)
void arm_psci_init(uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args);
void arm_psci_init(uint64_t method, uint64_t *platform_shutdown_args, uint64_t *platform_reboot_args);
uint32_t arm_psci_get_version();
uint32_t arm_psci_get_affinity_info(uint64_t target_affinity, uint64_t lowest_affinity_level);
+27 -14
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -11,19 +11,28 @@
*/
#include "rtconfig.h"
.section ".text.entrypoint","ax"
#define SECONDARY_STACK_SIZE 4096
.section ".text.entrypoint","ax"
.globl _start
.globl secondary_cpu_start
_start:
#ifdef RT_USING_SMP
mrs x1, mpidr_el1
and x1, x1, #0xff
cbnz x1, cpu_idle /* If cpu id > 0, stop slave cores */
adr x4, .boot_cpu_mpidr
str x1, [x4]
dsb sy
#endif
bl __asm_flush_dcache_all /* The kernel and data must flush to DDR */
secondary_cpu_start:
#ifdef RT_USING_SMP
adr x4, .boot_cpu_mpidr
ldr x4, [x4]
dsb sy
/* Read cpu mpidr_el1 */
mrs x1, mpidr_el1
@@ -34,6 +43,7 @@ secondary_cpu_start:
cpu_id_confirm:
add x2, x2, #1 /* Next cpu id inc */
ldr x3, [x0], #8
dsb sy
cmp x3, #0
beq cpu_idle /* Mean that `rt_cpu_mpidr_early' table is end */
cmp x3, x1
@@ -42,7 +52,8 @@ cpu_id_confirm:
/* Get cpu id success */
sub x0, x2, #1
msr tpidr_el1, x0 /* Save cpu id global */
cbz x0, cpu_setup /* Only go to cpu_setup when cpu id = 0 */
cmp x3, x4 /* If it is boot cpu */
beq boot_cpu_setup
/* Set current cpu's stack top */
sub x0, x0, #1
@@ -53,14 +64,9 @@ cpu_id_confirm:
b cpu_check_el
#else
msr tpidr_el1, xzr
b cpu_setup
#endif /* RT_USING_SMP */
cpu_idle:
wfe
b cpu_idle
cpu_setup:
boot_cpu_setup:
ldr x1, =_start
cpu_check_el:
@@ -75,7 +81,7 @@ cpu_check_el:
mov x2, #(1 << 0) /* EL0 and EL1 are in Non-Secure state */
orr x2, x2, #(1 << 4) /* RES1 */
orr x2, x2, #(1 << 5) /* RES1 */
orr x2, x2, #(1 << 7) /* SMC instructions are undefined at EL1 and above */
bic x2, x2, #(1 << 7) /* SMC instructions are enabled at EL1 and above */
orr x2, x2, #(1 << 8) /* HVC instructions are enabled at EL1 and above */
orr x2, x2, #(1 << 10) /* The next lower level is AArch64 */
msr scr_el3, x2
@@ -91,7 +97,7 @@ cpu_check_el:
eret
cpu_not_in_el3: /* Running at EL2 or EL1 */
cmp x0, #4 /* EL1 = 0100 */
cmp x0, #4 /* EL1 = 0100 */
beq cpu_in_el1
cpu_in_el2:
@@ -159,9 +165,16 @@ clean_bss_check:
jump_to_entry:
b rtthread_startup
b cpu_idle /* For failsafe, halt this core too */
cpu_idle:
wfe
b cpu_idle
#ifdef RT_USING_SMP
.align 3
.boot_cpu_mpidr:
.quad 0x0
.align 12
.secondary_cpu_stack:
.space (SECONDARY_STACK_SIZE * (RT_CPUS_NR - 1))