add raspi3-32 in bsp
This commit is contained in:
parent
2fbe05d7fc
commit
08f55d9fda
|
@ -8,7 +8,7 @@ config BSP_DIR
|
||||||
config RTT_DIR
|
config RTT_DIR
|
||||||
string
|
string
|
||||||
option env="RTT_ROOT"
|
option env="RTT_ROOT"
|
||||||
default "../.."
|
default "../../.."
|
||||||
|
|
||||||
config PKGS_DIR
|
config PKGS_DIR
|
||||||
string
|
string
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
from building import *
|
|
||||||
|
|
||||||
cwd = GetCurrentDir()
|
|
||||||
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
|
|
||||||
CPPPATH = [cwd]
|
|
||||||
|
|
||||||
group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
|
|
||||||
|
|
||||||
Return('group')
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-09-15 Bernard first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __ARMV7_H__
|
|
||||||
#define __ARMV7_H__
|
|
||||||
|
|
||||||
/* the exception stack without VFP registers */
|
|
||||||
struct rt_hw_exp_stack
|
|
||||||
{
|
|
||||||
unsigned long r0;
|
|
||||||
unsigned long r1;
|
|
||||||
unsigned long r2;
|
|
||||||
unsigned long r3;
|
|
||||||
unsigned long r4;
|
|
||||||
unsigned long r5;
|
|
||||||
unsigned long r6;
|
|
||||||
unsigned long r7;
|
|
||||||
unsigned long r8;
|
|
||||||
unsigned long r9;
|
|
||||||
unsigned long r10;
|
|
||||||
unsigned long fp;
|
|
||||||
unsigned long ip;
|
|
||||||
unsigned long sp;
|
|
||||||
unsigned long lr;
|
|
||||||
unsigned long pc;
|
|
||||||
unsigned long cpsr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_hw_stack
|
|
||||||
{
|
|
||||||
unsigned long cpsr;
|
|
||||||
unsigned long r0;
|
|
||||||
unsigned long r1;
|
|
||||||
unsigned long r2;
|
|
||||||
unsigned long r3;
|
|
||||||
unsigned long r4;
|
|
||||||
unsigned long r5;
|
|
||||||
unsigned long r6;
|
|
||||||
unsigned long r7;
|
|
||||||
unsigned long r8;
|
|
||||||
unsigned long r9;
|
|
||||||
unsigned long r10;
|
|
||||||
unsigned long fp;
|
|
||||||
unsigned long ip;
|
|
||||||
unsigned long lr;
|
|
||||||
unsigned long pc;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define USERMODE 0x10
|
|
||||||
#define FIQMODE 0x11
|
|
||||||
#define IRQMODE 0x12
|
|
||||||
#define SVCMODE 0x13
|
|
||||||
#define MONITORMODE 0x16
|
|
||||||
#define ABORTMODE 0x17
|
|
||||||
#define HYPMODE 0x1b
|
|
||||||
#define UNDEFMODE 0x1b
|
|
||||||
#define MODEMASK 0x1f
|
|
||||||
#define NOINT 0xc0
|
|
||||||
|
|
||||||
#define T_Bit (1<<5)
|
|
||||||
#define F_Bit (1<<6)
|
|
||||||
#define I_Bit (1<<7)
|
|
||||||
#define A_Bit (1<<8)
|
|
||||||
#define E_Bit (1<<9)
|
|
||||||
#define J_Bit (1<<24)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-05 Bernard the first version
|
|
||||||
* 2019-07-28 zdzn add smp support
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../rtconfig.h"
|
|
||||||
.section .text, "ax"
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
#define rt_hw_interrupt_disable rt_hw_local_irq_disable
|
|
||||||
#define rt_hw_interrupt_enable rt_hw_local_irq_enable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rt_base_t rt_hw_interrupt_disable();
|
|
||||||
*/
|
|
||||||
.globl rt_hw_interrupt_disable
|
|
||||||
rt_hw_interrupt_disable:
|
|
||||||
mrs r0, cpsr
|
|
||||||
cpsid i
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void rt_hw_interrupt_enable(rt_base_t level);
|
|
||||||
*/
|
|
||||||
.globl rt_hw_interrupt_enable
|
|
||||||
rt_hw_interrupt_enable:
|
|
||||||
msr cpsr, r0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void rt_hw_context_switch_to(rt_uint32 to, struct rt_thread *to_thread);
|
|
||||||
* r0 --> to (thread stack)
|
|
||||||
* r1 --> to_thread
|
|
||||||
*/
|
|
||||||
.globl rt_hw_context_switch_to
|
|
||||||
rt_hw_context_switch_to:
|
|
||||||
ldr sp, [r0] @ get new task stack pointer
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
mov r0, r1
|
|
||||||
bl rt_cpus_lock_status_restore
|
|
||||||
#endif /*RT_USING_SMP*/
|
|
||||||
b rt_hw_context_switch_exit
|
|
||||||
|
|
||||||
.section .bss.share.isr
|
|
||||||
_guest_switch_lvl:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
.globl vmm_virq_update
|
|
||||||
|
|
||||||
.section .text.isr, "ax"
|
|
||||||
/*
|
|
||||||
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread);
|
|
||||||
* r0 --> from (from_thread stack)
|
|
||||||
* r1 --> to (to_thread stack)
|
|
||||||
* r2 --> to_thread
|
|
||||||
*/
|
|
||||||
.globl rt_hw_context_switch
|
|
||||||
rt_hw_context_switch:
|
|
||||||
stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC)
|
|
||||||
stmfd sp!, {r0-r12, lr} @ push lr & register file
|
|
||||||
|
|
||||||
mrs r4, cpsr
|
|
||||||
tst lr, #0x01
|
|
||||||
orrne r4, r4, #0x20 @ it's thumb code
|
|
||||||
|
|
||||||
stmfd sp!, {r4} @ push cpsr
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
stmfd sp, {r13, r14}^ @ push usr_sp usr_lr
|
|
||||||
sub sp, #8
|
|
||||||
#endif
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
/* fpu context */
|
|
||||||
vmrs r6, fpexc
|
|
||||||
tst r6, #(1<<30)
|
|
||||||
beq 1f
|
|
||||||
vstmdb sp!, {d0-d15}
|
|
||||||
vstmdb sp!, {d16-d31}
|
|
||||||
vmrs r5, fpscr
|
|
||||||
stmfd sp!, {r5}
|
|
||||||
1:
|
|
||||||
stmfd sp!, {r6}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
str sp, [r0] @ store sp in preempted tasks TCB
|
|
||||||
ldr sp, [r1] @ get new task stack pointer
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
mov r0, r2
|
|
||||||
bl rt_cpus_lock_status_restore
|
|
||||||
#endif /*RT_USING_SMP*/
|
|
||||||
b rt_hw_context_switch_exit
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
|
|
||||||
*/
|
|
||||||
.equ Mode_USR, 0x10
|
|
||||||
.equ Mode_FIQ, 0x11
|
|
||||||
.equ Mode_IRQ, 0x12
|
|
||||||
.equ Mode_SVC, 0x13
|
|
||||||
.equ Mode_ABT, 0x17
|
|
||||||
.equ Mode_UND, 0x1B
|
|
||||||
.equ Mode_SYS, 0x1F
|
|
||||||
|
|
||||||
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
|
|
||||||
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
|
|
||||||
|
|
||||||
.globl rt_thread_switch_interrupt_flag
|
|
||||||
.globl rt_interrupt_from_thread
|
|
||||||
.globl rt_interrupt_to_thread
|
|
||||||
.globl rt_hw_context_switch_interrupt
|
|
||||||
rt_hw_context_switch_interrupt:
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
/* r0 :svc_mod context
|
|
||||||
* r1 :addr of from_thread's sp
|
|
||||||
* r2 :addr of to_thread's sp
|
|
||||||
* r3 :to_thread's tcb
|
|
||||||
*/
|
|
||||||
|
|
||||||
str r0, [r1]
|
|
||||||
|
|
||||||
ldr sp, [r2]
|
|
||||||
mov r0, r3
|
|
||||||
bl rt_cpus_lock_status_restore
|
|
||||||
|
|
||||||
b rt_hw_context_switch_exit
|
|
||||||
|
|
||||||
#else /*RT_USING_SMP*/
|
|
||||||
ldr r2, =rt_thread_switch_interrupt_flag
|
|
||||||
ldr r3, [r2]
|
|
||||||
cmp r3, #1
|
|
||||||
beq _reswitch
|
|
||||||
ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread
|
|
||||||
mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1
|
|
||||||
str r0, [ip]
|
|
||||||
str r3, [r2]
|
|
||||||
_reswitch:
|
|
||||||
ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
|
|
||||||
str r1, [r2]
|
|
||||||
bx lr
|
|
||||||
#endif /*RT_USING_SMP*/
|
|
||||||
|
|
||||||
.global rt_hw_context_switch_exit
|
|
||||||
rt_hw_context_switch_exit:
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
#ifdef RT_USING_SIGNALS
|
|
||||||
mov r0, sp
|
|
||||||
cps #Mode_IRQ
|
|
||||||
bl rt_signal_check
|
|
||||||
cps #Mode_SVC
|
|
||||||
mov sp, r0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
/* fpu context */
|
|
||||||
ldmfd sp!, {r6}
|
|
||||||
vmsr fpexc, r6
|
|
||||||
tst r6, #(1<<30)
|
|
||||||
beq 1f
|
|
||||||
ldmfd sp!, {r5}
|
|
||||||
vmsr fpscr, r5
|
|
||||||
vldmia sp!, {d16-d31}
|
|
||||||
vldmia sp!, {d0-d15}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */
|
|
||||||
add sp, #8
|
|
||||||
#endif
|
|
||||||
ldmfd sp!, {r4}
|
|
||||||
msr spsr_cxsf, r4 /* original mode */
|
|
||||||
ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */
|
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 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
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_vector_set_base
|
|
||||||
rt_cpu_vector_set_base:
|
|
||||||
/* clear SCTRL.V to customize the vector address */
|
|
||||||
mrc p15, #0, r1, c1, c0, #0
|
|
||||||
bic r1, #(1 << 13)
|
|
||||||
mcr p15, #0, r1, c1, c0, #0
|
|
||||||
/* set up the vector address */
|
|
||||||
mcr p15, #0, r0, c12, c0, #0
|
|
||||||
dsb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_dcache_enable
|
|
||||||
rt_hw_cpu_dcache_enable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
orr r0, r0, #0x00000004
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_icache_enable
|
|
||||||
rt_hw_cpu_icache_enable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
orr r0, r0, #0x00001000
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
_FLD_MAX_WAY:
|
|
||||||
.word 0x3ff
|
|
||||||
_FLD_MAX_IDX:
|
|
||||||
.word 0x7ff
|
|
||||||
|
|
||||||
.globl set_timer_counter
|
|
||||||
set_timer_counter:
|
|
||||||
mcr p15, #0, r0, c14, c3, #0 @ write virtual timer timerval register
|
|
||||||
bx lr
|
|
||||||
.globl set_timer_control
|
|
||||||
set_timer_control:
|
|
||||||
mcr p15, #0, r0, c14, c3, #1 @ write virtual timer control register
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_dcache_clean_flush
|
|
||||||
rt_cpu_dcache_clean_flush:
|
|
||||||
push {r4-r11}
|
|
||||||
dmb
|
|
||||||
mrc p15, #1, r0, c0, c0, #1 @ read clid register
|
|
||||||
ands r3, r0, #0x7000000 @ get level of coherency
|
|
||||||
mov r3, r3, lsr #23
|
|
||||||
beq finished
|
|
||||||
mov r10, #0
|
|
||||||
loop1:
|
|
||||||
add r2, r10, r10, lsr #1
|
|
||||||
mov r1, r0, lsr r2
|
|
||||||
and r1, r1, #7
|
|
||||||
cmp r1, #2
|
|
||||||
blt skip
|
|
||||||
mcr p15, #2, r10, c0, c0, #0
|
|
||||||
isb
|
|
||||||
mrc p15, #1, r1, c0, c0, #0
|
|
||||||
and r2, r1, #7
|
|
||||||
add r2, r2, #4
|
|
||||||
ldr r4, _FLD_MAX_WAY
|
|
||||||
ands r4, r4, r1, lsr #3
|
|
||||||
clz r5, r4
|
|
||||||
ldr r7, _FLD_MAX_IDX
|
|
||||||
ands r7, r7, r1, lsr #13
|
|
||||||
loop2:
|
|
||||||
mov r9, r4
|
|
||||||
loop3:
|
|
||||||
orr r11, r10, r9, lsl r5
|
|
||||||
orr r11, r11, r7, lsl r2
|
|
||||||
mcr p15, #0, r11, c7, c14, #2
|
|
||||||
subs r9, r9, #1
|
|
||||||
bge loop3
|
|
||||||
subs r7, r7, #1
|
|
||||||
bge loop2
|
|
||||||
skip:
|
|
||||||
add r10, r10, #2
|
|
||||||
cmp r3, r10
|
|
||||||
bgt loop1
|
|
||||||
|
|
||||||
finished:
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
pop {r4-r11}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_icache_flush
|
|
||||||
rt_cpu_icache_flush:
|
|
||||||
mov r0, #0
|
|
||||||
mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_dcache_disable
|
|
||||||
rt_hw_cpu_dcache_disable:
|
|
||||||
push {r4-r11, lr}
|
|
||||||
bl rt_cpu_dcache_clean_flush
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
bic r0, r0, #0x00000004
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
pop {r4-r11, lr}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_icache_disable
|
|
||||||
rt_hw_cpu_icache_disable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
bic r0, r0, #0x00001000
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_mmu_disable
|
|
||||||
rt_cpu_mmu_disable:
|
|
||||||
mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
bic r0, r0, #1
|
|
||||||
mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit
|
|
||||||
dsb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_mmu_enable
|
|
||||||
rt_cpu_mmu_enable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
orr r0, r0, #0x001
|
|
||||||
mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit
|
|
||||||
dsb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_tlb_set
|
|
||||||
rt_cpu_tlb_set:
|
|
||||||
mcr p15, #0, r0, c2, c0, #0
|
|
||||||
dmb
|
|
||||||
bx lr
|
|
|
@ -1,51 +0,0 @@
|
||||||
#ifndef MMU_H__
|
|
||||||
#define MMU_H__
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <board.h>
|
|
||||||
#include "cp15.h"
|
|
||||||
|
|
||||||
#define DESC_SEC (0x2)
|
|
||||||
#define CB (3 << 2) //cache_on, write_back
|
|
||||||
#define CNB (2 << 2) //cache_on, write_through
|
|
||||||
#define NCB (1 << 2) //cache_off,WR_BUF on
|
|
||||||
#define NCNB (0 << 2) //cache_off,WR_BUF off
|
|
||||||
#define AP_RW (3 << 10) //supervisor=RW, user=RW
|
|
||||||
#define AP_RO (2 << 10) //supervisor=RW, user=RO
|
|
||||||
#define XN (1 << 4) // eXecute Never
|
|
||||||
#define SHARED (1 << 16) /* shareable */
|
|
||||||
#define SHAREDEVICE (1 << 2) /* shared device */
|
|
||||||
#define STRONGORDER (0 << 2) /* strong ordered */
|
|
||||||
#define MEMWBWA ((1 << 12) | (3 << 2)) /* write back, write allocate */
|
|
||||||
|
|
||||||
#define DOMAIN_FAULT (0x0)
|
|
||||||
#define DOMAIN_CHK (0x1)
|
|
||||||
#define DOMAIN_NOTCHK (0x3)
|
|
||||||
#define DOMAIN0 (0x0 << 5)
|
|
||||||
#define DOMAIN1 (0x1 << 5)
|
|
||||||
|
|
||||||
#define DOMAIN0_ATTR (DOMAIN_CHK << 0)
|
|
||||||
#define DOMAIN1_ATTR (DOMAIN_FAULT << 2)
|
|
||||||
|
|
||||||
/* Read/Write, cache, write back */
|
|
||||||
#define RW_CB (AP_RW | DOMAIN0 | CB | DESC_SEC)
|
|
||||||
/* Read/Write, cache, write through */
|
|
||||||
#define RW_CNB (AP_RW | DOMAIN0 | CNB | DESC_SEC)
|
|
||||||
/* Read/Write without cache and write buffer */
|
|
||||||
#define RW_NCNB (AP_RW | DOMAIN0 | NCNB | DESC_SEC)
|
|
||||||
/* Read/Write without cache and write buffer, no execute */
|
|
||||||
#define RW_NCNBXN (AP_RW | DOMAIN0 | NCNB | DESC_SEC | XN)
|
|
||||||
/* Read/Write without cache and write buffer */
|
|
||||||
#define RW_FAULT (AP_RW | DOMAIN1 | NCNB | DESC_SEC)
|
|
||||||
|
|
||||||
/* device mapping type */
|
|
||||||
#define DEVICE_MEM (SHARED | SHAREDEVICE | RW_NCNBXN)
|
|
||||||
/* normal memory mapping type */
|
|
||||||
#define NORMAL_MEM (SHARED | AP_RW | DOMAIN0 | MEMWBWA | DESC_SEC)
|
|
||||||
#define STRONG_ORDER_MEM (SHARED | AP_RO | XN | DESC_SEC)
|
|
||||||
#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000)
|
|
||||||
|
|
||||||
void rt_hw_change_mmu_table(rt_uint32_t vaddrStart,
|
|
||||||
rt_uint32_t size,
|
|
||||||
rt_uint32_t paddrStart, rt_uint32_t attr);
|
|
||||||
#endif
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-09-23 Bernard the first version
|
|
||||||
* 2011-10-05 Bernard add thumb mode
|
|
||||||
*/
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <board.h>
|
|
||||||
#include <armv7.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup AM33xx
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will initialize thread stack
|
|
||||||
*
|
|
||||||
* @param tentry the entry of thread
|
|
||||||
* @param parameter the parameter of entry
|
|
||||||
* @param stack_addr the beginning stack address
|
|
||||||
* @param texit the function will be called when thread exit
|
|
||||||
*
|
|
||||||
* @return stack address
|
|
||||||
*/
|
|
||||||
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
|
||||||
rt_uint8_t *stack_addr, void *texit)
|
|
||||||
{
|
|
||||||
rt_uint32_t *stk;
|
|
||||||
|
|
||||||
stack_addr += sizeof(rt_uint32_t);
|
|
||||||
stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
|
|
||||||
stk = (rt_uint32_t *)stack_addr;
|
|
||||||
*(--stk) = (rt_uint32_t)tentry; /* entry point */
|
|
||||||
*(--stk) = (rt_uint32_t)texit; /* lr */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r12 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r11 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r10 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r9 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r8 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r7 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r6 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r5 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r4 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r3 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r2 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r1 */
|
|
||||||
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
|
||||||
|
|
||||||
/* cpsr */
|
|
||||||
if ((rt_uint32_t)tentry & 0x01)
|
|
||||||
*(--stk) = SVCMODE | 0x20; /* thumb mode */
|
|
||||||
else
|
|
||||||
*(--stk) = SVCMODE; /* arm mode */
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
*(--stk) = 0; /* user lr */
|
|
||||||
*(--stk) = 0; /* user sp*/
|
|
||||||
#endif
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
*(--stk) = 0; /* not use fpu*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* return task's current stack address */
|
|
||||||
return (rt_uint8_t *)stk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@}*/
|
|
|
@ -1,459 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-05 Bernard the first version
|
|
||||||
* 2019-07-28 zdzn add smp support
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../rtconfig.h"
|
|
||||||
.equ Mode_USR, 0x10
|
|
||||||
.equ Mode_FIQ, 0x11
|
|
||||||
.equ Mode_IRQ, 0x12
|
|
||||||
.equ Mode_SVC, 0x13
|
|
||||||
.equ Mode_ABT, 0x17
|
|
||||||
.equ Mode_UND, 0x1B
|
|
||||||
.equ Mode_SYS, 0x1F
|
|
||||||
|
|
||||||
.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 RT_FIQ_STACK_PGSZ, 0x00000000
|
|
||||||
.equ RT_IRQ_STACK_PGSZ, 0x00000800
|
|
||||||
.equ 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)
|
|
||||||
|
|
||||||
.section .data.share.isr
|
|
||||||
/* stack */
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
.globl stack_start0
|
|
||||||
.globl stack_top0
|
|
||||||
.globl stack_start1
|
|
||||||
.globl stack_top1
|
|
||||||
.globl stack_start2
|
|
||||||
.globl stack_top2
|
|
||||||
.globl stack_start3
|
|
||||||
.globl stack_top3
|
|
||||||
stack_start0:
|
|
||||||
.rept ISR_Stack_Size
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
stack_top0:
|
|
||||||
|
|
||||||
stack_start1:
|
|
||||||
.rept ISR_Stack_Size
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
stack_top1:
|
|
||||||
|
|
||||||
stack_start2:
|
|
||||||
.rept ISR_Stack_Size
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
stack_top2:
|
|
||||||
|
|
||||||
stack_start3:
|
|
||||||
.rept ISR_Stack_Size
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
stack_top3:
|
|
||||||
|
|
||||||
.globl boot_indicate
|
|
||||||
boot_indicate:
|
|
||||||
.rept 16
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
|
|
||||||
#else
|
|
||||||
.globl stack_start
|
|
||||||
.globl stack_top
|
|
||||||
stack_start:
|
|
||||||
.rept ISR_Stack_Size
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
stack_top:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
.text
|
|
||||||
/* reset entry */
|
|
||||||
.globl _reset
|
|
||||||
_reset:
|
|
||||||
|
|
||||||
/* Disable IRQ & FIQ */
|
|
||||||
cpsid if
|
|
||||||
|
|
||||||
/* Check for HYP mode */
|
|
||||||
mrs r0, cpsr_all
|
|
||||||
and r0, r0, #0x1F
|
|
||||||
mov r8, #0x1A
|
|
||||||
cmp r0, r8
|
|
||||||
beq overHyped
|
|
||||||
b continue
|
|
||||||
|
|
||||||
overHyped: /* Get out of HYP mode */
|
|
||||||
ldr r1, =continue
|
|
||||||
msr ELR_hyp, r1
|
|
||||||
mrs r1, cpsr_all
|
|
||||||
and r1, r1, #0x1f ;@ CPSR_MODE_MASK
|
|
||||||
orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR
|
|
||||||
msr SPSR_hyp, r1
|
|
||||||
eret
|
|
||||||
|
|
||||||
continue:
|
|
||||||
|
|
||||||
/* disable mmu */
|
|
||||||
bl rt_cpu_mmu_disable
|
|
||||||
/* set the cpu to SVC32 mode and disable interrupt */
|
|
||||||
mrs r0, cpsr
|
|
||||||
bic r0, r0, #0x1f
|
|
||||||
orr r0, r0, #0x13
|
|
||||||
msr cpsr_c, r0
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
mrc p15, 0, r0, c0, c0, 5
|
|
||||||
ubfx r0, r0, #0, #2
|
|
||||||
cmp r0, #0
|
|
||||||
beq 1f
|
|
||||||
/* write boot indicate */
|
|
||||||
ldr r5, = boot_indicate
|
|
||||||
str r0, [r5, r0, lsl #2]
|
|
||||||
bl secondary_cpu_start
|
|
||||||
b .
|
|
||||||
1:
|
|
||||||
#endif
|
|
||||||
/* setup stack */
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
ldr r0, =stack_top0
|
|
||||||
#else
|
|
||||||
ldr r0, =stack_top
|
|
||||||
#endif
|
|
||||||
bl stack_setup
|
|
||||||
|
|
||||||
/* clear .bss */
|
|
||||||
mov r0,#0 /* get a zero */
|
|
||||||
ldr r1,=__bss_start /* bss start */
|
|
||||||
ldr r2,=__bss_end /* bss end */
|
|
||||||
|
|
||||||
bss_loop:
|
|
||||||
cmp r1,r2 /* check if data to clear */
|
|
||||||
strlo r0,[r1],#4 /* clear 4 bytes */
|
|
||||||
blo bss_loop /* loop until done */
|
|
||||||
bl rt_hw_init_mmu_table
|
|
||||||
bl init_mbox_mmu_map
|
|
||||||
bl rt_hw_mmu_init
|
|
||||||
|
|
||||||
/* start RT-Thread Kernel */
|
|
||||||
ldr pc, _rtthread_startup
|
|
||||||
_rtthread_startup:
|
|
||||||
.word rtthread_startup
|
|
||||||
|
|
||||||
stack_setup:
|
|
||||||
|
|
||||||
@ Set the startup stack for svc
|
|
||||||
mov sp, r0
|
|
||||||
|
|
||||||
@ Enter Undefined Instruction Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #UND_Stack_Size
|
|
||||||
|
|
||||||
@ Enter Abort Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #ABT_Stack_Size
|
|
||||||
|
|
||||||
@ Enter FIQ Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #RT_FIQ_STACK_PGSZ
|
|
||||||
|
|
||||||
@ Enter IRQ Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #RT_IRQ_STACK_PGSZ
|
|
||||||
|
|
||||||
/* come back to SVC mode */
|
|
||||||
msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */
|
|
||||||
.section .text.isr, "ax"
|
|
||||||
.align 5
|
|
||||||
.globl vector_fiq
|
|
||||||
vector_fiq:
|
|
||||||
stmfd sp!,{r0-r7,lr}
|
|
||||||
bl rt_hw_trap_fiq
|
|
||||||
ldmfd sp!,{r0-r7,lr}
|
|
||||||
subs pc, lr, #4
|
|
||||||
|
|
||||||
.globl rt_interrupt_enter
|
|
||||||
.globl rt_interrupt_leave
|
|
||||||
.globl rt_thread_switch_interrupt_flag
|
|
||||||
.globl rt_interrupt_from_thread
|
|
||||||
.globl rt_interrupt_to_thread
|
|
||||||
|
|
||||||
.globl rt_current_thread
|
|
||||||
.globl vmm_thread
|
|
||||||
.globl vmm_virq_check
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_irq
|
|
||||||
vector_irq:
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
clrex
|
|
||||||
|
|
||||||
stmfd sp!, {r0, r1}
|
|
||||||
cps #Mode_SVC
|
|
||||||
mov r0, sp /* svc_sp */
|
|
||||||
mov r1, lr /* svc_lr */
|
|
||||||
|
|
||||||
cps #Mode_IRQ
|
|
||||||
sub lr, lr, #4
|
|
||||||
stmfd r0!, {r1, lr} /* svc_lr, svc_pc */
|
|
||||||
stmfd r0!, {r2 - r12}
|
|
||||||
ldmfd sp!, {r1, r2} /* original r0, r1 */
|
|
||||||
stmfd r0!, {r1 - r2}
|
|
||||||
mrs r1, spsr /* original mode */
|
|
||||||
stmfd r0!, {r1}
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
stmfd r0, {r13, r14}^ /* usr_sp, usr_lr */
|
|
||||||
sub r0, #8
|
|
||||||
#endif
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
/* fpu context */
|
|
||||||
vmrs r6, fpexc
|
|
||||||
tst r6, #(1<<30)
|
|
||||||
beq 1f
|
|
||||||
vstmdb r0!, {d0-d15}
|
|
||||||
vstmdb r0!, {d16-d31}
|
|
||||||
vmrs r5, fpscr
|
|
||||||
stmfd r0!, {r5}
|
|
||||||
1:
|
|
||||||
stmfd r0!, {r6}
|
|
||||||
#endif
|
|
||||||
mov r8, r0
|
|
||||||
|
|
||||||
bl rt_interrupt_enter
|
|
||||||
bl rt_hw_trap_irq
|
|
||||||
bl rt_interrupt_leave
|
|
||||||
|
|
||||||
cps #Mode_SVC
|
|
||||||
mov sp, r8
|
|
||||||
mov r0, r8
|
|
||||||
|
|
||||||
bl rt_scheduler_do_irq_switch
|
|
||||||
|
|
||||||
b rt_hw_context_switch_exit
|
|
||||||
|
|
||||||
#else
|
|
||||||
stmfd sp!, {r0-r12,lr}
|
|
||||||
|
|
||||||
bl rt_interrupt_enter
|
|
||||||
bl rt_hw_trap_irq
|
|
||||||
bl rt_interrupt_leave
|
|
||||||
|
|
||||||
@ if rt_thread_switch_interrupt_flag set, jump to
|
|
||||||
@ rt_hw_context_switch_interrupt_do and don't return
|
|
||||||
ldr r0, =rt_thread_switch_interrupt_flag
|
|
||||||
ldr r1, [r0]
|
|
||||||
cmp r1, #1
|
|
||||||
beq rt_hw_context_switch_interrupt_do
|
|
||||||
|
|
||||||
ldmfd sp!, {r0-r12,lr}
|
|
||||||
subs pc, lr, #4
|
|
||||||
|
|
||||||
rt_hw_context_switch_interrupt_do:
|
|
||||||
mov r1, #0 @ clear flag
|
|
||||||
str r1, [r0]
|
|
||||||
|
|
||||||
mov r1, sp @ r1 point to {r0-r3} in stack
|
|
||||||
add sp, sp, #4*4
|
|
||||||
ldmfd sp!, {r4-r12,lr}@ reload saved registers
|
|
||||||
mrs r0, spsr @ get cpsr of interrupt thread
|
|
||||||
sub r2, lr, #4 @ save old task's pc to r2
|
|
||||||
|
|
||||||
@ Switch to SVC mode with no interrupt. If the usr mode guest is
|
|
||||||
@ interrupted, this will just switch to the stack of kernel space.
|
|
||||||
@ save the registers in kernel space won't trigger data abort.
|
|
||||||
msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
|
||||||
|
|
||||||
stmfd sp!, {r2} @ push old task's pc
|
|
||||||
stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
|
|
||||||
ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread
|
|
||||||
stmfd sp!, {r1-r4} @ push old task's r0-r3
|
|
||||||
stmfd sp!, {r0} @ push old task's cpsr
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
stmfd sp, {r13, r14}^ @push usr_sp, usr_lr
|
|
||||||
sub sp, #8
|
|
||||||
#endif
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
/* fpu context */
|
|
||||||
vmrs r6, fpexc
|
|
||||||
tst r6, #(1<<30)
|
|
||||||
beq 1f
|
|
||||||
vstmdb sp!, {d0-d15}
|
|
||||||
vstmdb sp!, {d16-d31}
|
|
||||||
vmrs r5, fpscr
|
|
||||||
stmfd sp!, {r5}
|
|
||||||
1:
|
|
||||||
stmfd sp!, {r6}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ldr r4, =rt_interrupt_from_thread
|
|
||||||
ldr r5, [r4]
|
|
||||||
str sp, [r5] @ store sp in preempted tasks's TCB
|
|
||||||
|
|
||||||
ldr r6, =rt_interrupt_to_thread
|
|
||||||
ldr r6, [r6]
|
|
||||||
ldr sp, [r6] @ get new task's stack pointer
|
|
||||||
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
/* fpu context */
|
|
||||||
ldmfd sp!, {r6}
|
|
||||||
vmsr fpexc, r6
|
|
||||||
tst r6, #(1<<30)
|
|
||||||
beq 1f
|
|
||||||
ldmfd sp!, {r5}
|
|
||||||
vmsr fpscr, r5
|
|
||||||
vldmia sp!, {d16-d31}
|
|
||||||
vldmia sp!, {d0-d15}
|
|
||||||
1:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RT_USING_LWP
|
|
||||||
ldmfd sp, {r13, r14}^ @pop usr_sp, usr_lr
|
|
||||||
add sp, #8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
|
|
||||||
msr spsr_cxsf, r4
|
|
||||||
|
|
||||||
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.macro push_svc_reg
|
|
||||||
sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
|
|
||||||
stmia sp, {r0 - r12} @/* Calling r0-r12 */
|
|
||||||
mov r0, sp
|
|
||||||
mrs r6, spsr @/* Save CPSR */
|
|
||||||
str lr, [r0, #15*4] @/* Push PC */
|
|
||||||
str r6, [r0, #16*4] @/* Push CPSR */
|
|
||||||
cps #Mode_SVC
|
|
||||||
str sp, [r0, #13*4] @/* Save calling SP */
|
|
||||||
str lr, [r0, #14*4] @/* Save calling PC */
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_swi
|
|
||||||
vector_swi:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_swi
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_undef
|
|
||||||
vector_undef:
|
|
||||||
push_svc_reg
|
|
||||||
cps #Mode_UND
|
|
||||||
bl rt_hw_trap_undef
|
|
||||||
#ifdef RT_USING_FPU
|
|
||||||
ldr lr, [sp, #15*4]
|
|
||||||
ldmia sp, {r0 - r12}
|
|
||||||
add sp, sp, #17 * 4
|
|
||||||
movs pc, lr
|
|
||||||
#endif
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_pabt
|
|
||||||
vector_pabt:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_pabt
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_dabt
|
|
||||||
vector_dabt:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_dabt
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_resv
|
|
||||||
vector_resv:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_resv
|
|
||||||
b .
|
|
||||||
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
|
|
||||||
.global secondary_cpu_start
|
|
||||||
secondary_cpu_start:
|
|
||||||
/* set vector base */
|
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
|
||||||
bic r0, #(1<<13)
|
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
|
||||||
|
|
||||||
/* setup stack */
|
|
||||||
mrc p15, 0, r0, c0, c0, 5
|
|
||||||
ubfx r0, r0, #0, #2
|
|
||||||
ldr r1, =stack_top0
|
|
||||||
ldr r2, =ISR_Stack_Size
|
|
||||||
mul r3, r2, r0
|
|
||||||
add r0, r1, r3
|
|
||||||
bl stack_setup
|
|
||||||
/* initialize the mmu table and enable mmu */
|
|
||||||
bl rt_hw_mmu_init
|
|
||||||
b secondary_cpu_c_start
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
;@ void arm_smp_enable(void);
|
|
||||||
.globl arm_smp_enable
|
|
||||||
arm_smp_enable:
|
|
||||||
mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR
|
|
||||||
orr r0, r0, #0x40
|
|
||||||
mcr p15, 0, r0, c1, c0, 1
|
|
||||||
bx lr
|
|
||||||
/*
|
|
||||||
mrrc p15, 1, r0, r1, c15
|
|
||||||
orr r0, r0, #0x40
|
|
||||||
mcrr p15, 1, r0, r1, c15
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
bx lr
|
|
||||||
*/
|
|
||||||
.text
|
|
||||||
;@ void arm_smp_disable(void);
|
|
||||||
.globl arm_smp_disable
|
|
||||||
|
|
||||||
arm_smp_disable:
|
|
||||||
mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR
|
|
||||||
bic r0, r0, #0x40
|
|
||||||
mcr p15, 0, r0, c1, c0, 1
|
|
||||||
bx lr
|
|
||||||
/*
|
|
||||||
mrrc p15, 1, r0, r1, c15
|
|
||||||
bic r0, r0, #0x40
|
|
||||||
mcrr p15, 1, r0, r1, c15
|
|
||||||
bx lr
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-20 Bernard first version
|
|
||||||
* 2019-07-28 zdzn add smp support
|
|
||||||
* 2019-08-09 zhangjun fixup the problem of smp startup and scheduling issues,
|
|
||||||
* write addr to mailbox3 to startup smp, and we use mailbox0 for ipi
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <board.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
|
|
||||||
#include "armv7.h"
|
|
||||||
|
|
||||||
extern struct rt_thread *rt_current_thread;
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
extern long list_thread(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function will show registers of CPU
|
|
||||||
*
|
|
||||||
* @param regs the registers point
|
|
||||||
*/
|
|
||||||
void rt_hw_show_register(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("Execption:\n");
|
|
||||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
|
||||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
|
||||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
|
||||||
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
|
||||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
|
||||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When comes across an instruction which it cannot handle,
|
|
||||||
* it takes the undefined instruction trap.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("undefined instruction:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The software interrupt instruction (SWI) is used for entering
|
|
||||||
* Supervisor mode, usually to request a particular supervisor
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("software interrupt:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abort indicates that the current memory access cannot be completed,
|
|
||||||
* which occurs during an instruction prefetch.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("prefetch abort:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abort indicates that the current memory access cannot be completed,
|
|
||||||
* which occurs during a data access.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("data abort:");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normally, system will never reach here
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("reserved trap:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_trap_irq(void)
|
|
||||||
{
|
|
||||||
void *param;
|
|
||||||
uint32_t irq;
|
|
||||||
rt_isr_handler_t isr_func;
|
|
||||||
extern struct rt_irq_desc isr_table[];
|
|
||||||
uint32_t value = 0;
|
|
||||||
value = IRQ_PEND_BASIC & 0x3ff;
|
|
||||||
#ifdef RT_USING_SMP
|
|
||||||
uint32_t mailbox_data;
|
|
||||||
uint32_t cpu_id = rt_hw_cpu_id();
|
|
||||||
uint32_t int_source = CORE_IRQSOURCE(cpu_id);
|
|
||||||
mailbox_data = IPI_MAILBOX_CLEAR(cpu_id);
|
|
||||||
if (int_source & 0x0f)
|
|
||||||
{
|
|
||||||
if (int_source & 0x08)
|
|
||||||
{
|
|
||||||
isr_func = isr_table[IRQ_ARM_TIMER].handler;
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
isr_table[IRQ_ARM_TIMER].counter++;
|
|
||||||
#endif
|
|
||||||
if (isr_func)
|
|
||||||
{
|
|
||||||
param = isr_table[IRQ_ARM_TIMER].param;
|
|
||||||
isr_func(IRQ_ARM_TIMER, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (int_source & 0xf0)
|
|
||||||
{
|
|
||||||
/*it's a ipi interrupt*/
|
|
||||||
if (mailbox_data & 0x1)
|
|
||||||
{
|
|
||||||
/* clear mailbox */
|
|
||||||
IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data;
|
|
||||||
isr_func = isr_table[IRQ_ARM_MAILBOX].handler;
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
isr_table[IRQ_ARM_MAILBOX].counter++;
|
|
||||||
#endif
|
|
||||||
if (isr_func)
|
|
||||||
{
|
|
||||||
param = isr_table[IRQ_ARM_MAILBOX].param;
|
|
||||||
isr_func(IRQ_ARM_MAILBOX, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* local interrupt*/
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
if (value & (1 << 8))
|
|
||||||
{
|
|
||||||
value = IRQ_PEND1;
|
|
||||||
irq = __rt_ffs(value) - 1;
|
|
||||||
}
|
|
||||||
else if (value & (1 << 9))
|
|
||||||
{
|
|
||||||
value = IRQ_PEND2;
|
|
||||||
irq = __rt_ffs(value) + 31;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value &= 0x0f;
|
|
||||||
irq = __rt_ffs(value) + 63;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get interrupt service routine */
|
|
||||||
isr_func = isr_table[irq].handler;
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
isr_table[irq].counter++;
|
|
||||||
#endif
|
|
||||||
if (isr_func)
|
|
||||||
{
|
|
||||||
/* Interrupt for myself. */
|
|
||||||
param = isr_table[irq].param;
|
|
||||||
/* turn to interrupt service routine */
|
|
||||||
isr_func(irq, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_trap_fiq(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-05 Bernard the first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
.section .vectors, "ax"
|
|
||||||
.code 32
|
|
||||||
|
|
||||||
.globl system_vectors
|
|
||||||
system_vectors:
|
|
||||||
ldr pc, _vector_reset
|
|
||||||
ldr pc, _vector_undef
|
|
||||||
ldr pc, _vector_swi
|
|
||||||
ldr pc, _vector_pabt
|
|
||||||
ldr pc, _vector_dabt
|
|
||||||
ldr pc, _vector_resv
|
|
||||||
ldr pc, _vector_irq
|
|
||||||
ldr pc, _vector_fiq
|
|
||||||
|
|
||||||
.globl _reset
|
|
||||||
.globl vector_undef
|
|
||||||
.globl vector_swi
|
|
||||||
.globl vector_pabt
|
|
||||||
.globl vector_dabt
|
|
||||||
.globl vector_resv
|
|
||||||
.globl vector_irq
|
|
||||||
.globl vector_fiq
|
|
||||||
|
|
||||||
_vector_reset:
|
|
||||||
.word _reset
|
|
||||||
_vector_undef:
|
|
||||||
.word vector_undef
|
|
||||||
_vector_swi:
|
|
||||||
.word vector_swi
|
|
||||||
_vector_pabt:
|
|
||||||
.word vector_pabt
|
|
||||||
_vector_dabt:
|
|
||||||
.word vector_dabt
|
|
||||||
_vector_resv:
|
|
||||||
.word vector_resv
|
|
||||||
_vector_irq:
|
|
||||||
.word vector_irq
|
|
||||||
_vector_fiq:
|
|
||||||
.word vector_fiq
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
|
@ -1,9 +0,0 @@
|
||||||
from building import *
|
|
||||||
|
|
||||||
cwd = GetCurrentDir()
|
|
||||||
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
|
|
||||||
CPPPATH = [cwd]
|
|
||||||
|
|
||||||
group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
|
|
||||||
|
|
||||||
Return('group')
|
|
|
@ -1,64 +0,0 @@
|
||||||
#ifndef __ARMV7_H__
|
|
||||||
#define __ARMV7_H__
|
|
||||||
|
|
||||||
/* the exception stack without VFP registers */
|
|
||||||
struct rt_hw_exp_stack
|
|
||||||
{
|
|
||||||
unsigned long r0;
|
|
||||||
unsigned long r1;
|
|
||||||
unsigned long r2;
|
|
||||||
unsigned long r3;
|
|
||||||
unsigned long r4;
|
|
||||||
unsigned long r5;
|
|
||||||
unsigned long r6;
|
|
||||||
unsigned long r7;
|
|
||||||
unsigned long r8;
|
|
||||||
unsigned long r9;
|
|
||||||
unsigned long r10;
|
|
||||||
unsigned long fp;
|
|
||||||
unsigned long ip;
|
|
||||||
unsigned long sp;
|
|
||||||
unsigned long lr;
|
|
||||||
unsigned long pc;
|
|
||||||
unsigned long cpsr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_hw_stack
|
|
||||||
{
|
|
||||||
unsigned long cpsr;
|
|
||||||
unsigned long r0;
|
|
||||||
unsigned long r1;
|
|
||||||
unsigned long r2;
|
|
||||||
unsigned long r3;
|
|
||||||
unsigned long r4;
|
|
||||||
unsigned long r5;
|
|
||||||
unsigned long r6;
|
|
||||||
unsigned long r7;
|
|
||||||
unsigned long r8;
|
|
||||||
unsigned long r9;
|
|
||||||
unsigned long r10;
|
|
||||||
unsigned long fp;
|
|
||||||
unsigned long ip;
|
|
||||||
unsigned long lr;
|
|
||||||
unsigned long pc;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define USERMODE 0x10
|
|
||||||
#define FIQMODE 0x11
|
|
||||||
#define IRQMODE 0x12
|
|
||||||
#define SVCMODE 0x13
|
|
||||||
#define MONITORMODE 0x16
|
|
||||||
#define ABORTMODE 0x17
|
|
||||||
#define HYPMODE 0x1b
|
|
||||||
#define UNDEFMODE 0x1b
|
|
||||||
#define MODEMASK 0x1f
|
|
||||||
#define NOINT 0xc0
|
|
||||||
|
|
||||||
#define T_Bit (1<<5)
|
|
||||||
#define F_Bit (1<<6)
|
|
||||||
#define I_Bit (1<<7)
|
|
||||||
#define A_Bit (1<<8)
|
|
||||||
#define E_Bit (1<<9)
|
|
||||||
#define J_Bit (1<<24)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,105 +0,0 @@
|
||||||
/*
|
|
||||||
* File : context.S
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-05 Bernard the first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
.section .text, "ax"
|
|
||||||
/*
|
|
||||||
* rt_base_t rt_hw_interrupt_disable();
|
|
||||||
*/
|
|
||||||
.globl rt_hw_interrupt_disable
|
|
||||||
rt_hw_interrupt_disable:
|
|
||||||
mrs r0, cpsr
|
|
||||||
cpsid i
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void rt_hw_interrupt_enable(rt_base_t level);
|
|
||||||
*/
|
|
||||||
.globl rt_hw_interrupt_enable
|
|
||||||
rt_hw_interrupt_enable:
|
|
||||||
msr cpsr_c, r0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void rt_hw_context_switch_to(rt_uint32 to);
|
|
||||||
* r0 --> to
|
|
||||||
*/
|
|
||||||
.globl rt_hw_context_switch_to
|
|
||||||
rt_hw_context_switch_to:
|
|
||||||
ldr sp, [r0] @ get new task stack pointer
|
|
||||||
|
|
||||||
ldmfd sp!, {r4} @ pop new task spsr
|
|
||||||
msr spsr_cxsf, r4
|
|
||||||
|
|
||||||
ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc
|
|
||||||
|
|
||||||
.section .bss.share.isr
|
|
||||||
_guest_switch_lvl:
|
|
||||||
.word 0
|
|
||||||
|
|
||||||
.globl vmm_virq_update
|
|
||||||
|
|
||||||
.section .text.isr, "ax"
|
|
||||||
/*
|
|
||||||
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
|
||||||
* r0 --> from
|
|
||||||
* r1 --> to
|
|
||||||
*/
|
|
||||||
.globl rt_hw_context_switch
|
|
||||||
rt_hw_context_switch:
|
|
||||||
stmfd sp!, {lr} @ push pc (lr should be pushed in place of PC)
|
|
||||||
stmfd sp!, {r0-r12, lr} @ push lr & register file
|
|
||||||
|
|
||||||
mrs r4, cpsr
|
|
||||||
tst lr, #0x01
|
|
||||||
orrne r4, r4, #0x20 @ it's thumb code
|
|
||||||
|
|
||||||
stmfd sp!, {r4} @ push cpsr
|
|
||||||
|
|
||||||
str sp, [r0] @ store sp in preempted tasks TCB
|
|
||||||
ldr sp, [r1] @ get new task stack pointer
|
|
||||||
|
|
||||||
ldmfd sp!, {r4} @ pop new task cpsr to spsr
|
|
||||||
msr spsr_cxsf, r4
|
|
||||||
ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc, copy spsr to cpsr
|
|
||||||
|
|
||||||
/*
|
|
||||||
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
|
|
||||||
*/
|
|
||||||
.globl rt_thread_switch_interrupt_flag
|
|
||||||
.globl rt_interrupt_from_thread
|
|
||||||
.globl rt_interrupt_to_thread
|
|
||||||
.globl rt_hw_context_switch_interrupt
|
|
||||||
rt_hw_context_switch_interrupt:
|
|
||||||
ldr r2, =rt_thread_switch_interrupt_flag
|
|
||||||
ldr r3, [r2]
|
|
||||||
cmp r3, #1
|
|
||||||
beq _reswitch
|
|
||||||
ldr ip, =rt_interrupt_from_thread @ set rt_interrupt_from_thread
|
|
||||||
mov r3, #1 @ set rt_thread_switch_interrupt_flag to 1
|
|
||||||
str r0, [ip]
|
|
||||||
str r3, [r2]
|
|
||||||
_reswitch:
|
|
||||||
ldr r2, =rt_interrupt_to_thread @ set rt_interrupt_to_thread
|
|
||||||
str r1, [r2]
|
|
||||||
bx lr
|
|
|
@ -1,12 +0,0 @@
|
||||||
#ifndef __CP15_H__
|
|
||||||
#define __CP15_H__
|
|
||||||
|
|
||||||
unsigned long rt_cpu_get_smp_id(void);
|
|
||||||
|
|
||||||
void rt_cpu_mmu_disable(void);
|
|
||||||
void rt_cpu_mmu_enable(void);
|
|
||||||
void rt_cpu_tlb_set(volatile unsigned long*);
|
|
||||||
|
|
||||||
void rt_cpu_vector_set_base(unsigned int addr);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,140 +0,0 @@
|
||||||
/*
|
|
||||||
* File : cp15_gcc.S
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013, RT-Thread Development Team
|
|
||||||
* http://www.rt-thread.org
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 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
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_vector_set_base
|
|
||||||
rt_cpu_vector_set_base:
|
|
||||||
mcr p15, #0, r0, c12, c0, #0
|
|
||||||
dsb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_dcache_enable
|
|
||||||
rt_hw_cpu_dcache_enable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
orr r0, r0, #0x00000004
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_icache_enable
|
|
||||||
rt_hw_cpu_icache_enable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
orr r0, r0, #0x00001000
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
_FLD_MAX_WAY:
|
|
||||||
.word 0x3ff
|
|
||||||
_FLD_MAX_IDX:
|
|
||||||
.word 0x7ff
|
|
||||||
|
|
||||||
.globl rt_cpu_dcache_clean_flush
|
|
||||||
rt_cpu_dcache_clean_flush:
|
|
||||||
push {r4-r11}
|
|
||||||
dmb
|
|
||||||
mrc p15, #1, r0, c0, c0, #1 @ read clid register
|
|
||||||
ands r3, r0, #0x7000000 @ get level of coherency
|
|
||||||
mov r3, r3, lsr #23
|
|
||||||
beq finished
|
|
||||||
mov r10, #0
|
|
||||||
loop1:
|
|
||||||
add r2, r10, r10, lsr #1
|
|
||||||
mov r1, r0, lsr r2
|
|
||||||
and r1, r1, #7
|
|
||||||
cmp r1, #2
|
|
||||||
blt skip
|
|
||||||
mcr p15, #2, r10, c0, c0, #0
|
|
||||||
isb
|
|
||||||
mrc p15, #1, r1, c0, c0, #0
|
|
||||||
and r2, r1, #7
|
|
||||||
add r2, r2, #4
|
|
||||||
ldr r4, _FLD_MAX_WAY
|
|
||||||
ands r4, r4, r1, lsr #3
|
|
||||||
clz r5, r4
|
|
||||||
ldr r7, _FLD_MAX_IDX
|
|
||||||
ands r7, r7, r1, lsr #13
|
|
||||||
loop2:
|
|
||||||
mov r9, r4
|
|
||||||
loop3:
|
|
||||||
orr r11, r10, r9, lsl r5
|
|
||||||
orr r11, r11, r7, lsl r2
|
|
||||||
mcr p15, #0, r11, c7, c14, #2
|
|
||||||
subs r9, r9, #1
|
|
||||||
bge loop3
|
|
||||||
subs r7, r7, #1
|
|
||||||
bge loop2
|
|
||||||
skip:
|
|
||||||
add r10, r10, #2
|
|
||||||
cmp r3, r10
|
|
||||||
bgt loop1
|
|
||||||
|
|
||||||
finished:
|
|
||||||
dsb
|
|
||||||
isb
|
|
||||||
pop {r4-r11}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_dcache_disable
|
|
||||||
rt_hw_cpu_dcache_disable:
|
|
||||||
push {r4-r11, lr}
|
|
||||||
bl rt_cpu_dcache_clean_flush
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
bic r0, r0, #0x00000004
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
pop {r4-r11, lr}
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_hw_cpu_icache_disable
|
|
||||||
rt_hw_cpu_icache_disable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
bic r0, r0, #0x00001000
|
|
||||||
mcr p15, #0, r0, c1, c0, #0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_mmu_disable
|
|
||||||
rt_cpu_mmu_disable:
|
|
||||||
mcr p15, #0, r0, c8, c7, #0 @ invalidate tlb
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
bic r0, r0, #1
|
|
||||||
mcr p15, #0, r0, c1, c0, #0 @ clear mmu bit
|
|
||||||
dsb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_mmu_enable
|
|
||||||
rt_cpu_mmu_enable:
|
|
||||||
mrc p15, #0, r0, c1, c0, #0
|
|
||||||
orr r0, r0, #0x001
|
|
||||||
mcr p15, #0, r0, c1, c0, #0 @ set mmu enable bit
|
|
||||||
dsb
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.globl rt_cpu_tlb_set
|
|
||||||
rt_cpu_tlb_set:
|
|
||||||
mcr p15, #0, r0, c2, c0, #0
|
|
||||||
dmb
|
|
||||||
bx lr
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* File : cpu.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-09-15 Bernard first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup AM33xx
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/** shutdown CPU */
|
|
||||||
void rt_hw_cpu_shutdown()
|
|
||||||
{
|
|
||||||
rt_uint32_t level;
|
|
||||||
rt_kprintf("shutdown...\n");
|
|
||||||
|
|
||||||
level = rt_hw_interrupt_disable();
|
|
||||||
while (level)
|
|
||||||
{
|
|
||||||
RT_ASSERT(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@}*/
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* File : interrupt.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013-2014, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2018/5/3 Bernard first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
|
|
||||||
#include "cp15.h"
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
#define MAX_HANDLERS 64
|
|
||||||
|
|
||||||
extern volatile rt_uint8_t rt_interrupt_nest;
|
|
||||||
|
|
||||||
/* exception and interrupt handler table */
|
|
||||||
struct rt_irq_desc isr_table[MAX_HANDLERS];
|
|
||||||
|
|
||||||
rt_uint32_t rt_interrupt_from_thread;
|
|
||||||
rt_uint32_t rt_interrupt_to_thread;
|
|
||||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
|
||||||
|
|
||||||
extern int system_vectors;
|
|
||||||
|
|
||||||
static void default_isr_handler(int vector, void *param)
|
|
||||||
{
|
|
||||||
rt_kprintf("unhandled irq: %d\n", vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will initialize hardware interrupt
|
|
||||||
*/
|
|
||||||
void rt_hw_interrupt_init(void)
|
|
||||||
{
|
|
||||||
uint32_t index;
|
|
||||||
|
|
||||||
/* mask all of interrupts */
|
|
||||||
IRQ_DISABLE_BASIC = 0x000000ff;
|
|
||||||
IRQ_DISABLE1 = 0xffffffff;
|
|
||||||
IRQ_DISABLE2 = 0xffffffff;
|
|
||||||
|
|
||||||
for (index = 0; index < MAX_HANDLERS; index ++)
|
|
||||||
{
|
|
||||||
isr_table[index].handler = default_isr_handler;
|
|
||||||
isr_table[index].param = NULL;
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX);
|
|
||||||
isr_table[index].counter = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init interrupt nest, and context in thread sp */
|
|
||||||
rt_interrupt_nest = 0;
|
|
||||||
rt_interrupt_from_thread = 0;
|
|
||||||
rt_interrupt_to_thread = 0;
|
|
||||||
rt_thread_switch_interrupt_flag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will mask a interrupt.
|
|
||||||
* @param vector the interrupt number
|
|
||||||
*/
|
|
||||||
void rt_hw_interrupt_mask(int vector)
|
|
||||||
{
|
|
||||||
if (vector < 8)
|
|
||||||
{
|
|
||||||
IRQ_DISABLE_BASIC = (1 << vector);
|
|
||||||
}
|
|
||||||
else if (vector < 32)
|
|
||||||
{
|
|
||||||
IRQ_DISABLE1 = (1 << vector);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vector = vector % 32;
|
|
||||||
IRQ_DISABLE2 = (1 << vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will un-mask a interrupt.
|
|
||||||
* @param vector the interrupt number
|
|
||||||
*/
|
|
||||||
void rt_hw_interrupt_umask(int vector)
|
|
||||||
{
|
|
||||||
if (vector < 8)
|
|
||||||
{
|
|
||||||
IRQ_ENABLE_BASIC = (1 << vector);
|
|
||||||
}
|
|
||||||
else if (vector < 32)
|
|
||||||
{
|
|
||||||
IRQ_ENABLE1 = (1 << vector);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vector = vector % 32;
|
|
||||||
IRQ_ENABLE2 = (1 << vector);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will install a interrupt service routine to a interrupt.
|
|
||||||
* @param vector the interrupt number
|
|
||||||
* @param new_handler the interrupt service routine to be installed
|
|
||||||
* @param old_handler the old interrupt service routine
|
|
||||||
*/
|
|
||||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
|
||||||
void *param, const char *name)
|
|
||||||
{
|
|
||||||
rt_isr_handler_t old_handler = RT_NULL;
|
|
||||||
|
|
||||||
if (vector < MAX_HANDLERS)
|
|
||||||
{
|
|
||||||
old_handler = isr_table[vector].handler;
|
|
||||||
|
|
||||||
if (handler != RT_NULL)
|
|
||||||
{
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
|
|
||||||
#endif /* RT_USING_INTERRUPT_INFO */
|
|
||||||
isr_table[vector].handler = handler;
|
|
||||||
isr_table[vector].param = param;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return old_handler;
|
|
||||||
}
|
|
|
@ -1,207 +0,0 @@
|
||||||
/*
|
|
||||||
* File : mmu.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2012-01-10 bernard porting to AM1808
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <board.h>
|
|
||||||
|
|
||||||
#include "cp15.h"
|
|
||||||
|
|
||||||
#define DESC_SEC (0x2)
|
|
||||||
#define CB (3<<2) //cache_on, write_back
|
|
||||||
#define CNB (2<<2) //cache_on, write_through
|
|
||||||
#define NCB (1<<2) //cache_off,WR_BUF on
|
|
||||||
#define NCNB (0<<2) //cache_off,WR_BUF off
|
|
||||||
#define AP_RW (3<<10) //supervisor=RW, user=RW
|
|
||||||
#define AP_RO (2<<10) //supervisor=RW, user=RO
|
|
||||||
#define XN (1<<4) // eXecute Never
|
|
||||||
|
|
||||||
#define DOMAIN_FAULT (0x0)
|
|
||||||
#define DOMAIN_CHK (0x1)
|
|
||||||
#define DOMAIN_NOTCHK (0x3)
|
|
||||||
#define DOMAIN0 (0x0<<5)
|
|
||||||
#define DOMAIN1 (0x1<<5)
|
|
||||||
|
|
||||||
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
|
|
||||||
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
|
|
||||||
|
|
||||||
/* Read/Write, cache, write back */
|
|
||||||
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
|
|
||||||
/* Read/Write, cache, write through */
|
|
||||||
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
|
|
||||||
/* Read/Write without cache and write buffer */
|
|
||||||
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
|
|
||||||
/* Read/Write without cache and write buffer, no execute */
|
|
||||||
#define RW_NCNBXN (AP_RW|DOMAIN0|NCNB|DESC_SEC|XN)
|
|
||||||
/* Read/Write without cache and write buffer */
|
|
||||||
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
|
|
||||||
|
|
||||||
/* dump 2nd level page table */
|
|
||||||
void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int fcnt = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
rt_uint32_t pte2 = ptb[i];
|
|
||||||
if ((pte2 & 0x3) == 0)
|
|
||||||
{
|
|
||||||
if (fcnt == 0)
|
|
||||||
rt_kprintf(" ");
|
|
||||||
rt_kprintf("%04x: ", i);
|
|
||||||
fcnt++;
|
|
||||||
if (fcnt == 16)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fcnt != 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_kprintf(" %04x: %x: ", i, pte2);
|
|
||||||
if ((pte2 & 0x3) == 0x1)
|
|
||||||
{
|
|
||||||
rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
|
|
||||||
((pte2 >> 7) | (pte2 >> 4))& 0xf,
|
|
||||||
(pte2 >> 15) & 0x1,
|
|
||||||
((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
|
|
||||||
((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
|
|
||||||
((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int fcnt = 0;
|
|
||||||
|
|
||||||
rt_kprintf("page table@%p\n", ptb);
|
|
||||||
for (i = 0; i < 1024*4; i++)
|
|
||||||
{
|
|
||||||
rt_uint32_t pte1 = ptb[i];
|
|
||||||
if ((pte1 & 0x3) == 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("%03x: ", i);
|
|
||||||
fcnt++;
|
|
||||||
if (fcnt == 16)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (fcnt != 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("fault\n");
|
|
||||||
fcnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_kprintf("%03x: %08x: ", i, pte1);
|
|
||||||
if ((pte1 & 0x3) == 0x3)
|
|
||||||
{
|
|
||||||
rt_kprintf("LPAE\n");
|
|
||||||
}
|
|
||||||
else if ((pte1 & 0x3) == 0x1)
|
|
||||||
{
|
|
||||||
rt_kprintf("pte,ns:%d,domain:%d\n",
|
|
||||||
(pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
|
|
||||||
/*
|
|
||||||
*rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
|
|
||||||
* - 0x80000000 + 0xC0000000));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else if (pte1 & (1 << 18))
|
|
||||||
{
|
|
||||||
rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
|
|
||||||
(pte1 >> 19) & 0x1,
|
|
||||||
((pte1 >> 13) | (pte1 >> 10))& 0xf,
|
|
||||||
(pte1 >> 4) & 0x1,
|
|
||||||
((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("section,ns:%d,ap:%x,"
|
|
||||||
"xn:%d,texcb:%02x,domain:%d\n",
|
|
||||||
(pte1 >> 19) & 0x1,
|
|
||||||
((pte1 >> 13) | (pte1 >> 10))& 0xf,
|
|
||||||
(pte1 >> 4) & 0x1,
|
|
||||||
(((pte1 & (0x7 << 12)) >> 10) |
|
|
||||||
((pte1 & 0x0c) >> 2)) & 0x1f,
|
|
||||||
(pte1 >> 5) & 0xf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* level1 page table, each entry for 1MB memory. */
|
|
||||||
volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
|
|
||||||
void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
|
|
||||||
rt_uint32_t vaddrEnd,
|
|
||||||
rt_uint32_t paddrStart,
|
|
||||||
rt_uint32_t attr)
|
|
||||||
{
|
|
||||||
volatile rt_uint32_t *pTT;
|
|
||||||
volatile int i, nSec;
|
|
||||||
pTT = (rt_uint32_t *)MMUTable + (vaddrStart >> 20);
|
|
||||||
nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
|
|
||||||
for(i = 0; i <= nSec; i++)
|
|
||||||
{
|
|
||||||
*pTT = attr | (((paddrStart >> 20) + i) << 20);
|
|
||||||
pTT++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long rt_hw_set_domain_register(unsigned long domain_val)
|
|
||||||
{
|
|
||||||
unsigned long old_domain;
|
|
||||||
|
|
||||||
asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
|
|
||||||
asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
|
|
||||||
|
|
||||||
return old_domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_mmu_init(void)
|
|
||||||
{
|
|
||||||
rt_hw_cpu_dcache_disable();
|
|
||||||
rt_hw_cpu_icache_disable();
|
|
||||||
rt_cpu_mmu_disable();
|
|
||||||
|
|
||||||
/* set page table */
|
|
||||||
/* 4G 1:1 memory */
|
|
||||||
rt_hw_mmu_setmtt(0, 0xffffffff-1, 0, RW_CB);
|
|
||||||
/* IO memory region */
|
|
||||||
rt_hw_mmu_setmtt(0x44000000, 0x80000000-1, 0x44000000, RW_NCNBXN);
|
|
||||||
|
|
||||||
/*rt_hw_cpu_dump_page_table(MMUTable);*/
|
|
||||||
rt_hw_set_domain_register(0x55555555);
|
|
||||||
|
|
||||||
rt_cpu_tlb_set(MMUTable);
|
|
||||||
|
|
||||||
rt_cpu_mmu_enable();
|
|
||||||
|
|
||||||
rt_hw_cpu_icache_enable();
|
|
||||||
rt_hw_cpu_dcache_enable();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* File : stack.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2011, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2011-09-23 Bernard the first version
|
|
||||||
* 2011-10-05 Bernard add thumb mode
|
|
||||||
*/
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <board.h>
|
|
||||||
#include <armv7.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup AM33xx
|
|
||||||
*/
|
|
||||||
/*@{*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will initialize thread stack
|
|
||||||
*
|
|
||||||
* @param tentry the entry of thread
|
|
||||||
* @param parameter the parameter of entry
|
|
||||||
* @param stack_addr the beginning stack address
|
|
||||||
* @param texit the function will be called when thread exit
|
|
||||||
*
|
|
||||||
* @return stack address
|
|
||||||
*/
|
|
||||||
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
|
|
||||||
rt_uint8_t *stack_addr, void *texit)
|
|
||||||
{
|
|
||||||
rt_uint32_t *stk;
|
|
||||||
|
|
||||||
stack_addr += sizeof(rt_uint32_t);
|
|
||||||
stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
|
|
||||||
stk = (rt_uint32_t *)stack_addr;
|
|
||||||
*(--stk) = (rt_uint32_t)tentry; /* entry point */
|
|
||||||
*(--stk) = (rt_uint32_t)texit; /* lr */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r12 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r11 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r10 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r9 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r8 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r7 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r6 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r5 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r4 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r3 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r2 */
|
|
||||||
*(--stk) = 0xdeadbeef; /* r1 */
|
|
||||||
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
|
|
||||||
|
|
||||||
/* cpsr */
|
|
||||||
if ((rt_uint32_t)tentry & 0x01)
|
|
||||||
*(--stk) = SVCMODE | 0x20; /* thumb mode */
|
|
||||||
else
|
|
||||||
*(--stk) = SVCMODE; /* arm mode */
|
|
||||||
|
|
||||||
/* return task's current stack address */
|
|
||||||
return (rt_uint8_t *)stk;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*@}*/
|
|
|
@ -1,280 +0,0 @@
|
||||||
/*
|
|
||||||
* File : start_gcc.S
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013-2014, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-05 Bernard the first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
.equ Mode_USR, 0x10
|
|
||||||
.equ Mode_FIQ, 0x11
|
|
||||||
.equ Mode_IRQ, 0x12
|
|
||||||
.equ Mode_SVC, 0x13
|
|
||||||
.equ Mode_ABT, 0x17
|
|
||||||
.equ Mode_UND, 0x1B
|
|
||||||
.equ Mode_SYS, 0x1F
|
|
||||||
|
|
||||||
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
|
|
||||||
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
|
|
||||||
|
|
||||||
.equ UND_Stack_Size, 0x00000000
|
|
||||||
.equ SVC_Stack_Size, 0x00000100
|
|
||||||
.equ ABT_Stack_Size, 0x00000000
|
|
||||||
.equ RT_FIQ_STACK_PGSZ, 0x00000000
|
|
||||||
.equ RT_IRQ_STACK_PGSZ, 0x00000100
|
|
||||||
.equ USR_Stack_Size, 0x00000100
|
|
||||||
|
|
||||||
#define ISR_Stack_Size (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
|
|
||||||
RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
|
|
||||||
|
|
||||||
.section .data.share.isr
|
|
||||||
/* stack */
|
|
||||||
.globl stack_start
|
|
||||||
.globl stack_top
|
|
||||||
|
|
||||||
.align 3
|
|
||||||
stack_start:
|
|
||||||
.rept ISR_Stack_Size
|
|
||||||
.byte 0
|
|
||||||
.endr
|
|
||||||
stack_top:
|
|
||||||
|
|
||||||
.text
|
|
||||||
/* reset entry */
|
|
||||||
.globl _reset
|
|
||||||
_reset:
|
|
||||||
/* Disable IRQ & FIQ */
|
|
||||||
cpsid if
|
|
||||||
|
|
||||||
/* Check for HYP mode */
|
|
||||||
mrs r0, cpsr_all
|
|
||||||
and r0, r0, #0x1F
|
|
||||||
mov r8, #0x1A
|
|
||||||
cmp r0, r8
|
|
||||||
beq overHyped
|
|
||||||
b continue
|
|
||||||
|
|
||||||
overHyped: /* Get out of HYP mode */
|
|
||||||
ldr r1, =continue
|
|
||||||
msr ELR_hyp, r1
|
|
||||||
mrs r1, cpsr_all
|
|
||||||
and r1, r1, #0x1f ;@ CPSR_MODE_MASK
|
|
||||||
orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR
|
|
||||||
msr SPSR_hyp, r1
|
|
||||||
eret
|
|
||||||
|
|
||||||
continue:
|
|
||||||
|
|
||||||
/* disable smp */
|
|
||||||
bl arm_smp_disable
|
|
||||||
|
|
||||||
/* disable mmu */
|
|
||||||
bl rt_cpu_mmu_disable
|
|
||||||
/* set the cpu to SVC32 mode and disable interrupt */
|
|
||||||
mrs r0, cpsr
|
|
||||||
bic r0, r0, #0x1f
|
|
||||||
orr r0, r0, #0x13
|
|
||||||
msr cpsr_c, r0
|
|
||||||
|
|
||||||
/* setup stack */
|
|
||||||
bl stack_setup
|
|
||||||
|
|
||||||
/* clear .bss */
|
|
||||||
mov r0,#0 /* get a zero */
|
|
||||||
ldr r1,=__bss_start /* bss start */
|
|
||||||
ldr r2,=__bss_end /* bss end */
|
|
||||||
|
|
||||||
bss_loop:
|
|
||||||
cmp r1,r2 /* check if data to clear */
|
|
||||||
strlo r0,[r1],#4 /* clear 4 bytes */
|
|
||||||
blo bss_loop /* loop until done */
|
|
||||||
|
|
||||||
/* start RT-Thread Kernel */
|
|
||||||
ldr pc, _rtthread_startup
|
|
||||||
_rtthread_startup:
|
|
||||||
.word rtthread_startup
|
|
||||||
|
|
||||||
stack_setup:
|
|
||||||
ldr r0, =stack_top
|
|
||||||
|
|
||||||
@ 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
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #UND_Stack_Size
|
|
||||||
|
|
||||||
@ Enter Abort Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #ABT_Stack_Size
|
|
||||||
|
|
||||||
@ Enter FIQ Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #RT_FIQ_STACK_PGSZ
|
|
||||||
|
|
||||||
@ Enter IRQ Mode and set its Stack Pointer
|
|
||||||
msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
|
|
||||||
mov sp, r0
|
|
||||||
sub r0, r0, #RT_IRQ_STACK_PGSZ
|
|
||||||
|
|
||||||
/* come back to SVC mode */
|
|
||||||
msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.text
|
|
||||||
;@ void arm_smp_enable(void);
|
|
||||||
.globl arm_smp_enable
|
|
||||||
arm_smp_enable:
|
|
||||||
mrc p15, 0, r0, c1, c0, 1 ;@ set SMP bit in ACTLR
|
|
||||||
orr r0, r0, #0x40
|
|
||||||
mcr p15, 0, r0, c1, c0, 1
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.text
|
|
||||||
;@ void arm_smp_disable(void);
|
|
||||||
.globl arm_smp_disable
|
|
||||||
arm_smp_disable:
|
|
||||||
mrc p15, 0, r0, c1, c0, 1 ;@ clear SMP bit in ACTLR
|
|
||||||
bic r0, r0, #0x40
|
|
||||||
mcr p15, 0, r0, c1, c0, 1
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq */
|
|
||||||
.section .text.isr, "ax"
|
|
||||||
.align 5
|
|
||||||
.globl vector_fiq
|
|
||||||
vector_fiq:
|
|
||||||
stmfd sp!,{r0-r7,lr}
|
|
||||||
bl rt_hw_trap_fiq
|
|
||||||
ldmfd sp!,{r0-r7,lr}
|
|
||||||
subs pc, lr, #4
|
|
||||||
|
|
||||||
.globl rt_interrupt_enter
|
|
||||||
.globl rt_interrupt_leave
|
|
||||||
.globl rt_thread_switch_interrupt_flag
|
|
||||||
.globl rt_interrupt_from_thread
|
|
||||||
.globl rt_interrupt_to_thread
|
|
||||||
|
|
||||||
.globl rt_current_thread
|
|
||||||
.globl vmm_thread
|
|
||||||
.globl vmm_virq_check
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_irq
|
|
||||||
vector_irq:
|
|
||||||
stmfd sp!, {r0-r12,lr}
|
|
||||||
|
|
||||||
bl rt_interrupt_enter
|
|
||||||
bl rt_hw_trap_irq
|
|
||||||
bl rt_interrupt_leave
|
|
||||||
|
|
||||||
@ if rt_thread_switch_interrupt_flag set, jump to
|
|
||||||
@ rt_hw_context_switch_interrupt_do and don't return
|
|
||||||
ldr r0, =rt_thread_switch_interrupt_flag
|
|
||||||
ldr r1, [r0]
|
|
||||||
cmp r1, #1
|
|
||||||
beq rt_hw_context_switch_interrupt_do
|
|
||||||
|
|
||||||
ldmfd sp!, {r0-r12,lr}
|
|
||||||
subs pc, lr, #4
|
|
||||||
|
|
||||||
rt_hw_context_switch_interrupt_do:
|
|
||||||
mov r1, #0 @ clear flag
|
|
||||||
str r1, [r0]
|
|
||||||
|
|
||||||
mov r1, sp @ r1 point to {r0-r3} in stack
|
|
||||||
add sp, sp, #4*4
|
|
||||||
ldmfd sp!, {r4-r12,lr}@ reload saved registers
|
|
||||||
mrs r0, spsr @ get cpsr of interrupt thread
|
|
||||||
sub r2, lr, #4 @ save old task's pc to r2
|
|
||||||
|
|
||||||
@ Switch to SVC mode with no interrupt. If the usr mode guest is
|
|
||||||
@ interrupted, this will just switch to the stack of kernel space.
|
|
||||||
@ save the registers in kernel space won't trigger data abort.
|
|
||||||
msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
|
||||||
|
|
||||||
stmfd sp!, {r2} @ push old task's pc
|
|
||||||
stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
|
|
||||||
ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread
|
|
||||||
stmfd sp!, {r1-r4} @ push old task's r0-r3
|
|
||||||
stmfd sp!, {r0} @ push old task's cpsr
|
|
||||||
|
|
||||||
ldr r4, =rt_interrupt_from_thread
|
|
||||||
ldr r5, [r4]
|
|
||||||
str sp, [r5] @ store sp in preempted tasks's TCB
|
|
||||||
|
|
||||||
ldr r6, =rt_interrupt_to_thread
|
|
||||||
ldr r6, [r6]
|
|
||||||
ldr sp, [r6] @ get new task's stack pointer
|
|
||||||
|
|
||||||
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
|
|
||||||
msr spsr_cxsf, r4
|
|
||||||
|
|
||||||
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
|
||||||
|
|
||||||
.macro push_svc_reg
|
|
||||||
sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
|
|
||||||
stmia sp, {r0 - r12} @/* Calling r0-r12 */
|
|
||||||
mov r0, sp
|
|
||||||
mrs r6, spsr @/* Save CPSR */
|
|
||||||
str lr, [r0, #15*4] @/* Push PC */
|
|
||||||
str r6, [r0, #16*4] @/* Push CPSR */
|
|
||||||
cps #Mode_SVC
|
|
||||||
str sp, [r0, #13*4] @/* Save calling SP */
|
|
||||||
str lr, [r0, #14*4] @/* Save calling PC */
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_swi
|
|
||||||
vector_swi:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_swi
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_undef
|
|
||||||
vector_undef:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_undef
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_pabt
|
|
||||||
vector_pabt:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_pabt
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_dabt
|
|
||||||
vector_dabt:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_dabt
|
|
||||||
b .
|
|
||||||
|
|
||||||
.align 5
|
|
||||||
.globl vector_resv
|
|
||||||
vector_resv:
|
|
||||||
push_svc_reg
|
|
||||||
bl rt_hw_trap_resv
|
|
||||||
b .
|
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
* File : trap.c
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013, RT-Thread Develop Team
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may be
|
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-20 Bernard first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <board.h>
|
|
||||||
#include <rtthread.h>
|
|
||||||
|
|
||||||
#include "armv7.h"
|
|
||||||
|
|
||||||
extern struct rt_thread *rt_current_thread;
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
extern long list_thread(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* this function will show registers of CPU
|
|
||||||
*
|
|
||||||
* @param regs the registers point
|
|
||||||
*/
|
|
||||||
void rt_hw_show_register(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("Execption:\n");
|
|
||||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
|
||||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
|
||||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
|
||||||
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
|
||||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
|
||||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When comes across an instruction which it cannot handle,
|
|
||||||
* it takes the undefined instruction trap.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("undefined instruction:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The software interrupt instruction (SWI) is used for entering
|
|
||||||
* Supervisor mode, usually to request a particular supervisor
|
|
||||||
* function.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("software interrupt:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abort indicates that the current memory access cannot be completed,
|
|
||||||
* which occurs during an instruction prefetch.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("prefetch abort:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abort indicates that the current memory access cannot be completed,
|
|
||||||
* which occurs during a data access.
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("data abort:");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normally, system will never reach here
|
|
||||||
*
|
|
||||||
* @param regs system registers
|
|
||||||
*
|
|
||||||
* @note never invoke this function in application
|
|
||||||
*/
|
|
||||||
void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
|
|
||||||
{
|
|
||||||
rt_kprintf("reserved trap:\n");
|
|
||||||
rt_hw_show_register(regs);
|
|
||||||
#ifdef RT_USING_FINSH
|
|
||||||
list_thread();
|
|
||||||
#endif
|
|
||||||
rt_hw_cpu_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_trap_irq(void)
|
|
||||||
{
|
|
||||||
void *param;
|
|
||||||
rt_isr_handler_t isr_func;
|
|
||||||
extern struct rt_irq_desc isr_table[];
|
|
||||||
|
|
||||||
uint32_t value = 0;
|
|
||||||
|
|
||||||
// rt_kprintf("pend basic: 0x%08x\n", IRQ_PEND_BASIC);
|
|
||||||
// rt_kprintf(" pend1: 0x%08x\n", IRQ_PEND1);
|
|
||||||
// rt_kprintf(" pend2: 0x%08x\n", IRQ_PEND2);
|
|
||||||
|
|
||||||
value = IRQ_PEND_BASIC & 0x3ff;
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
uint32_t irq;
|
|
||||||
|
|
||||||
if (value & (1 << 8))
|
|
||||||
{
|
|
||||||
value = IRQ_PEND1;
|
|
||||||
irq = __rt_ffs(value) - 1;
|
|
||||||
}
|
|
||||||
else if (value & (1 << 9))
|
|
||||||
{
|
|
||||||
value = IRQ_PEND2;
|
|
||||||
irq = __rt_ffs(value) + 31;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value &= 0x0f;
|
|
||||||
irq = __rt_ffs(value) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get interrupt service routine */
|
|
||||||
isr_func = isr_table[irq].handler;
|
|
||||||
#ifdef RT_USING_INTERRUPT_INFO
|
|
||||||
isr_table[irq].counter++;
|
|
||||||
#endif
|
|
||||||
if (isr_func)
|
|
||||||
{
|
|
||||||
/* Interrupt for myself. */
|
|
||||||
param = isr_table[irq].param;
|
|
||||||
/* turn to interrupt service routine */
|
|
||||||
isr_func(irq, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void rt_hw_trap_fiq(void)
|
|
||||||
{
|
|
||||||
/* TODO */
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* File : vector_gcc.S
|
|
||||||
* This file is part of RT-Thread RTOS
|
|
||||||
* COPYRIGHT (C) 2013, RT-Thread Development Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Change Logs:
|
|
||||||
* Date Author Notes
|
|
||||||
* 2013-07-05 Bernard the first version
|
|
||||||
*/
|
|
||||||
|
|
||||||
.section .vectors, "ax"
|
|
||||||
.code 32
|
|
||||||
|
|
||||||
.globl system_vectors
|
|
||||||
system_vectors:
|
|
||||||
ldr pc, _vector_reset
|
|
||||||
ldr pc, _vector_undef
|
|
||||||
ldr pc, _vector_swi
|
|
||||||
ldr pc, _vector_pabt
|
|
||||||
ldr pc, _vector_dabt
|
|
||||||
ldr pc, _vector_resv
|
|
||||||
ldr pc, _vector_irq
|
|
||||||
ldr pc, _vector_fiq
|
|
||||||
|
|
||||||
.globl _reset
|
|
||||||
.globl vector_undef
|
|
||||||
.globl vector_swi
|
|
||||||
.globl vector_pabt
|
|
||||||
.globl vector_dabt
|
|
||||||
.globl vector_resv
|
|
||||||
.globl vector_irq
|
|
||||||
.globl vector_fiq
|
|
||||||
|
|
||||||
_vector_reset:
|
|
||||||
.word _reset
|
|
||||||
_vector_undef:
|
|
||||||
.word vector_undef
|
|
||||||
_vector_swi:
|
|
||||||
.word vector_swi
|
|
||||||
_vector_pabt:
|
|
||||||
.word vector_pabt
|
|
||||||
_vector_dabt:
|
|
||||||
.word vector_dabt
|
|
||||||
_vector_resv:
|
|
||||||
.word vector_resv
|
|
||||||
_vector_irq:
|
|
||||||
.word vector_irq
|
|
||||||
_vector_fiq:
|
|
||||||
.word vector_fiq
|
|
||||||
|
|
||||||
.balignl 16,0xdeadbeef
|
|
Loading…
Reference in New Issue