[update] 整理cortex-a aarch32启动代码

1. 去除start_gcc.s中set_secondary_cpu_boot_address代码,这部分提取到qemu-vexpress-a9 bsp中。
2. 移动cpu.c中rt_hw_cpu_id函数到cp15_gcc.s,使用汇编实现,采用wake属性,方便bsp根据cpu特性获取CPU ID(多cpu集群中,不同厂家使用组合不一样).
3. 整理start_gcc.s 适应多核启动,原来的代码只考虑到双核的情况。
This commit is contained in:
zhouji 2021-05-01 16:06:02 +08:00 committed by zhouji
parent 484cda4d92
commit 42ce237dc9
5 changed files with 97 additions and 54 deletions

View File

@ -26,10 +26,16 @@ static void rt_hw_timer2_isr(int vector, void *param)
timer_clear_pending(0);
}
void set_secondary_cpu_boot_address(void)
{
extern void secondary_cpu_start(void);
uint32_t *boot_address = (uint32_t *)0x10000030;
*(boot_address + 1) = ~0ul;
*boot_address = (uint32_t )&secondary_cpu_start;
}
void rt_hw_secondary_cpu_up(void)
{
extern void set_secondary_cpu_boot_address(void);
set_secondary_cpu_boot_address();
__asm__ volatile ("dsb":::"memory");
rt_hw_ipi_send(0, 1 << 1);

View File

@ -15,8 +15,7 @@
#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);
int rt_hw_cpu_id(void);
void rt_cpu_mmu_disable(void);
void rt_cpu_mmu_enable(void);
void rt_cpu_tlb_set(volatile unsigned long*);

View File

@ -8,9 +8,11 @@
* 2013-07-05 Bernard the first version
*/
.globl rt_cpu_get_smp_id
rt_cpu_get_smp_id:
mrc p15, #0, r0, c0, c0, #5
.weak rt_hw_cpu_id
rt_hw_cpu_id:
mrc p15, #0, r0, c0, c0, #5 @ read multiprocessor affinity register
ldr r1, =0xFFFF03 @ Affinity mask off, leaving CPU ID field, [0:1]CPU ID, [8:15]Cluster ID Aff1, [16:23]Cluster ID Aff2
and r0, r0, r1
bx lr
.globl rt_cpu_vector_set_base

View File

@ -15,17 +15,6 @@
#ifdef RT_USING_SMP
int rt_hw_cpu_id(void)
{
int cpu_id;
__asm__ volatile (
"mrc p15, 0, %0, c0, c0, 5"
:"=r"(cpu_id)
);
cpu_id &= 0xf;
return cpu_id;
};
void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
{
lock->slock = 0;

View File

@ -22,20 +22,26 @@
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
#ifdef RT_USING_FPU
.equ UND_Stack_Size, 0x00000400
#else
.equ UND_Stack_Size, 0x00000000
#endif
.equ SVC_Stack_Size, 0x00000400
.equ ABT_Stack_Size, 0x00000000
.equ ABT_Stack_Size, 0x00000400
.equ RT_FIQ_STACK_PGSZ, 0x00000000
.equ RT_IRQ_STACK_PGSZ, 0x00000800
.equ USR_Stack_Size, 0x00000400
.equ SUB_UND_Stack_Size, 0x00000400
.equ SUB_SVC_Stack_Size, 0x00000400
.equ SUB_ABT_Stack_Size, 0x00000400
.equ SUB_RT_FIQ_STACK_PGSZ, 0x00000000
.equ SUB_RT_IRQ_STACK_PGSZ, 0x00000400
.equ SUB_USR_Stack_Size, 0x00000400
#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
#define SUB_ISR_Stack_Size (SUB_UND_Stack_Size + SUB_SVC_Stack_Size + SUB_ABT_Stack_Size + \
SUB_RT_FIQ_STACK_PGSZ + SUB_RT_IRQ_STACK_PGSZ)
.section .data.share.isr
/* stack */
.globl stack_start
@ -82,9 +88,40 @@ continue:
/* disable the data alignment check */
mrc p15, 0, r1, c1, c0, 0
bic r1, #(1<<1)
bic r1, #(1<<0) /* Disable MMU */
bic r1, #(1<<1) /* Disable Alignment fault checking */
bic r1, #(1<<2) /* Disable data cache */
bic r1, #(1<<11) /* Disable program flow prediction */
bic r1, #(1<<12) /* Disable instruction cache */
bic r1, #(3<<19) /* bit[20:19] must be zero */
mcr p15, 0, r1, c1, c0, 0
@ get cpu id, and subtract the offset from the stacks base address
bl rt_hw_cpu_id
mov r5, r0
cmp r5, #0 @ cpu id == 0
beq normal_setup
@ cpu id > 0, stop or wait
#ifdef RT_SMP_AUTO_BOOT
ldr r0, =secondary_cpu_entry
mov r1, #0
str r1, [r0] /* clean secondary_cpu_entry */
#endif /* RT_SMP_AUTO_BOOT */
secondary_loop:
@ cpu core 1 goes into sleep until core 0 wakeup it
wfe
#ifdef RT_SMP_AUTO_BOOT
ldr r1, =secondary_cpu_entry
ldr r0, [r1]
cmp r0, #0
blxne r0 /* if(secondary_cpu_entry) secondary_cpu_entry(); */
#endif /* RT_SMP_AUTO_BOOT */
b secondary_loop
normal_setup:
/* setup stack */
bl stack_setup
@ -105,6 +142,11 @@ bss_loop:
mcr p15, 0, r1, c1, c0, 1 //enable smp
#endif
/* enable branch prediction */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<11)
mcr p15, 0, r0, c1, c0, 0
/* initialize the mmu table and enable mmu */
ldr r0, =platform_mem_desc
ldr r1, =platform_mem_desc_size
@ -137,6 +179,7 @@ stack_setup:
@ Set the startup stack for svc
mov sp, r0
sub r0, r0, #SVC_Stack_Size
@ Enter Undefined Instruction Mode and set its Stack Pointer
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
@ -378,16 +421,6 @@ vector_resv:
b .
#ifdef RT_USING_SMP
.global set_secondary_cpu_boot_address
set_secondary_cpu_boot_address:
ldr r0, =secondary_cpu_start
mvn r1, #0 //0xffffffff
ldr r2, =0x10000034
str r1, [r2]
str r0, [r2, #-4]
mov pc, lr
.global secondary_cpu_start
secondary_cpu_start:
@ -405,38 +438,52 @@ secondary_cpu_start:
bic r0, #(1<<13)
mcr p15, 0, r0, c1, c0, 0
#ifdef RT_USING_FPU
cps #Mode_UND
ldr sp, =und_stack_2_limit
#endif
/* enable branch prediction */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<11)
mcr p15, 0, r0, c1, c0, 0
cps #Mode_IRQ
ldr sp, =irq_stack_2_limit
@ get cpu id, and subtract the offset from the stacks base address
bl rt_hw_cpu_id
sub r5, r0, #1
cps #Mode_FIQ
ldr sp, =irq_stack_2_limit
ldr r0, =SUB_ISR_Stack_Size
mul r0, r0, r5 @r0 = SUB_ISR_Stack_Size * (cpuid - 1)
ldr r1, =sub_stack_top
sub r0, r1, r0 @r0 = sub_stack_top - (SUB_ISR_Stack_Size * (cpuid - 1))
cps #Mode_SVC
mov sp, r0
sub r0, r0, #SUB_SVC_Stack_Size
cps #Mode_UND
mov sp, r0
sub r0, r0, #SUB_UND_Stack_Size
cps #Mode_ABT
mov sp, r0
sub r0, r0, #SUB_ABT_Stack_Size
cps #Mode_FIQ
mov sp, r0
sub r0, r0, #SUB_RT_FIQ_STACK_PGSZ
cps #Mode_IRQ
mov sp, r0
sub r0, r0, #SUB_RT_IRQ_STACK_PGSZ
cps #Mode_SVC
ldr sp, =svc_stack_2_limit
/* initialize the mmu table and enable mmu */
bl rt_hw_mmu_init
b secondary_cpu_c_start
#endif
.bss
.align 2 //align to 2~2=4
svc_stack_2:
.space (1 << 10)
svc_stack_2_limit:
irq_stack_2:
.space (1 << 10)
irq_stack_2_limit:
sub_stack_start:
.space (SUB_ISR_Stack_Size * (RT_CPUS_NR-1))
sub_stack_top:
#ifdef RT_USING_FPU
und_stack_2:
.space (1 << 10)
und_stack_2_limit:
#endif