summaryrefslogtreecommitdiff
path: root/libcpu/arm
diff options
context:
space:
mode:
authoryangjie11 <[email protected]>2020-11-18 09:56:35 +0800
committerGitHub <[email protected]>2020-11-18 09:56:35 +0800
commitd4a682e8d97fa131e5a8d795f8c5451d55cdd5b0 (patch)
tree4773b40cb012475c5daf74bfd55707e141477669 /libcpu/arm
parent2b98f4720c827ae1850df78299f6b273d568c8c7 (diff)
parent2ef3c9d861f55253620996a94831a4be31ca6620 (diff)
Merge pull request #3 from RT-Thread/master
sync
Diffstat (limited to 'libcpu/arm')
-rw-r--r--libcpu/arm/AT91SAM7S/SConscript23
-rw-r--r--libcpu/arm/AT91SAM7S/context_rvds.S130
-rw-r--r--libcpu/arm/AT91SAM7X/SConscript23
-rw-r--r--libcpu/arm/AT91SAM7X/context_rvds.S22
-rw-r--r--libcpu/arm/SConscript16
-rw-r--r--libcpu/arm/am335x/SConscript23
-rw-r--r--libcpu/arm/am335x/start_gcc.S1
-rw-r--r--libcpu/arm/arm926/SConscript25
-rw-r--r--libcpu/arm/arm926/context_gcc.S19
-rw-r--r--libcpu/arm/arm926/context_iar.S34
-rw-r--r--libcpu/arm/arm926/context_rvds.S22
-rw-r--r--libcpu/arm/arm926/cpuport.c44
-rw-r--r--libcpu/arm/arm926/machine.c27
-rw-r--r--libcpu/arm/arm926/mmu.c40
-rw-r--r--libcpu/arm/arm926/mmu.h5
-rw-r--r--libcpu/arm/arm926/stack.c2
-rw-r--r--libcpu/arm/arm926/start_gcc.S503
-rw-r--r--libcpu/arm/arm926/start_iar.S18
-rw-r--r--libcpu/arm/arm926/start_rvds.S44
-rw-r--r--libcpu/arm/arm926/trap.c91
-rw-r--r--libcpu/arm/armv6/SConscript23
-rw-r--r--libcpu/arm/common/SConscript23
-rw-r--r--libcpu/arm/common/backtrace.c58
-rw-r--r--libcpu/arm/cortex-a/SConscript23
-rw-r--r--libcpu/arm/cortex-a/cache.c100
-rw-r--r--libcpu/arm/cortex-a/context_gcc.S115
-rw-r--r--libcpu/arm/cortex-a/cp15.h4
-rw-r--r--libcpu/arm/cortex-a/cp15_gcc.S15
-rw-r--r--libcpu/arm/cortex-a/cpu.c72
-rw-r--r--libcpu/arm/cortex-a/gic.c300
-rw-r--r--libcpu/arm/cortex-a/gic.h35
-rw-r--r--libcpu/arm/cortex-a/interrupt.c119
-rw-r--r--libcpu/arm/cortex-a/interrupt.h34
-rw-r--r--libcpu/arm/cortex-a/mmu.c49
-rw-r--r--libcpu/arm/cortex-a/mmu.h49
-rw-r--r--libcpu/arm/cortex-a/stack.c9
-rw-r--r--libcpu/arm/cortex-a/start_gcc.S233
-rw-r--r--libcpu/arm/cortex-a/trap.c101
-rw-r--r--libcpu/arm/cortex-m0/SConscript23
-rw-r--r--libcpu/arm/cortex-m0/context_gcc.S4
-rw-r--r--libcpu/arm/cortex-m0/context_iar.S12
-rw-r--r--libcpu/arm/cortex-m0/context_rvds.S12
-rw-r--r--libcpu/arm/cortex-m0/cpuport.c19
-rw-r--r--libcpu/arm/cortex-m23/SConscript23
-rw-r--r--libcpu/arm/cortex-m23/context_gcc.S211
-rw-r--r--libcpu/arm/cortex-m23/context_iar.S207
-rw-r--r--libcpu/arm/cortex-m23/context_rvds.S216
-rw-r--r--libcpu/arm/cortex-m23/cpuport.c136
-rw-r--r--libcpu/arm/cortex-m3/SConscript23
-rw-r--r--libcpu/arm/cortex-m3/context_gcc.S4
-rw-r--r--libcpu/arm/cortex-m3/context_iar.S12
-rw-r--r--libcpu/arm/cortex-m3/context_rvds.S12
-rw-r--r--libcpu/arm/cortex-m3/cpuport.c19
-rw-r--r--libcpu/arm/cortex-m33/SConscript23
-rw-r--r--libcpu/arm/cortex-m33/context_gcc.S293
-rw-r--r--libcpu/arm/cortex-m33/context_iar.S300
-rw-r--r--libcpu/arm/cortex-m33/context_rvds.S306
-rw-r--r--libcpu/arm/cortex-m33/cpuport.c510
-rw-r--r--libcpu/arm/cortex-m33/syscall_gcc.S59
-rw-r--r--libcpu/arm/cortex-m33/syscall_iar.S63
-rw-r--r--libcpu/arm/cortex-m33/syscall_rvds.S74
-rw-r--r--libcpu/arm/cortex-m33/trustzone.c123
-rw-r--r--libcpu/arm/cortex-m4/SConscript23
-rw-r--r--libcpu/arm/cortex-m4/context_gcc.S4
-rw-r--r--libcpu/arm/cortex-m4/context_iar.S12
-rw-r--r--libcpu/arm/cortex-m4/context_rvds.S4
-rw-r--r--libcpu/arm/cortex-m4/cpuport.c21
-rw-r--r--libcpu/arm/cortex-m7/SConscript23
-rw-r--r--libcpu/arm/cortex-m7/context_gcc.S4
-rw-r--r--libcpu/arm/cortex-m7/context_iar.S12
-rw-r--r--libcpu/arm/cortex-m7/context_rvds.S12
-rw-r--r--libcpu/arm/cortex-m7/cpu_cache.c89
-rw-r--r--libcpu/arm/cortex-m7/cpuport.c21
-rw-r--r--libcpu/arm/cortex-r4/SConscript23
-rw-r--r--libcpu/arm/cortex-r4/context_ccs.asm10
-rw-r--r--libcpu/arm/cortex-r4/start_gcc.S1
-rw-r--r--libcpu/arm/dm36x/SConscript23
-rw-r--r--libcpu/arm/dm36x/context_rvds.S18
-rw-r--r--libcpu/arm/lpc214x/SConscript23
-rw-r--r--libcpu/arm/lpc214x/context_rvds.S8
-rw-r--r--libcpu/arm/lpc24xx/SConscript23
-rw-r--r--libcpu/arm/lpc24xx/context_rvds.S8
-rw-r--r--libcpu/arm/realview-a8-vmm/SConscript22
-rw-r--r--libcpu/arm/realview-a8-vmm/start_gcc.S1
-rw-r--r--libcpu/arm/s3c24x0/SConscript23
-rw-r--r--libcpu/arm/s3c24x0/context_rvds.S8
-rw-r--r--libcpu/arm/s3c24x0/serial.c291
-rw-r--r--libcpu/arm/s3c24x0/serial.h66
-rw-r--r--libcpu/arm/s3c24x0/start_gcc.S2
-rw-r--r--libcpu/arm/s3c44b0/SConscript23
-rw-r--r--libcpu/arm/s3c44b0/context_rvds.S8
-rw-r--r--libcpu/arm/s3c44b0/start_gcc.S2
-rw-r--r--libcpu/arm/sep4020/SConscript23
-rw-r--r--libcpu/arm/sep4020/context_rvds.S8
-rw-r--r--libcpu/arm/zynq7000/SConscript22
-rw-r--r--libcpu/arm/zynq7000/context_gcc.S20
-rw-r--r--libcpu/arm/zynq7000/cp15.h25
-rw-r--r--libcpu/arm/zynq7000/gic.c25
-rw-r--r--libcpu/arm/zynq7000/gic.h20
-rw-r--r--libcpu/arm/zynq7000/interrupt.h25
-rw-r--r--libcpu/arm/zynq7000/mmu.c20
-rw-r--r--libcpu/arm/zynq7000/start_gcc.S1
-rw-r--r--libcpu/arm/zynq7000/trap.c20
103 files changed, 4840 insertions, 1335 deletions
diff --git a/libcpu/arm/AT91SAM7S/SConscript b/libcpu/arm/AT91SAM7S/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/AT91SAM7S/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/AT91SAM7S/context_rvds.S b/libcpu/arm/AT91SAM7S/context_rvds.S
index 641ec7a6b1..78e3df9736 100644
--- a/libcpu/arm/AT91SAM7S/context_rvds.S
+++ b/libcpu/arm/AT91SAM7S/context_rvds.S
@@ -1,43 +1,39 @@
-;/*
-; * File : context_rvds.S
-; * 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
-; * 2009-01-20 Bernard first version
-; */
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-20 Bernard first version
+ */
NOINT EQU 0xc0 ; disable interrupt in psr
- AREA |.text|, CODE, READONLY, ALIGN=2
- ARM
- REQUIRE8
- PRESERVE8
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ ARM
+ REQUIRE8
+ PRESERVE8
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
- EXPORT rt_hw_interrupt_disable
- MRS r0, cpsr
- ORR r1, r0, #NOINT
- MSR cpsr_c, r1
- BX lr
- ENDP
+ EXPORT rt_hw_interrupt_disable
+ MRS r0, cpsr
+ ORR r1, r0, #NOINT
+ MSR cpsr_c, r1
+ BX lr
+ ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
- EXPORT rt_hw_interrupt_enable
- MSR cpsr_c, r0
- BX lr
- ENDP
+ EXPORT rt_hw_interrupt_enable
+ MSR cpsr_c, r0
+ BX lr
+ ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
@@ -45,63 +41,63 @@ rt_hw_interrupt_enable PROC
; * r1 --> to
; */
rt_hw_context_switch PROC
- EXPORT 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
+ EXPORT 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
- STMFD sp!, {r4} ; push cpsr
- MRS r4, spsr
- STMFD sp!, {r4} ; push spsr
+ MRS r4, cpsr
+ STMFD sp!, {r4} ; push cpsr
+ MRS r4, spsr
+ STMFD sp!, {r4} ; push spsr
- STR sp, [r0] ; store sp in preempted tasks TCB
- LDR sp, [r1] ; get new task stack pointer
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
- LDMFD sp!, {r4} ; pop new task spsr
- MSR spsr_cxsf, r4
- LDMFD sp!, {r4} ; pop new task cpsr
- MSR cpsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
- LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
- ENDP
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; */
rt_hw_context_switch_to PROC
- EXPORT rt_hw_context_switch_to
- LDR sp, [r0] ; get new task stack pointer
+ EXPORT 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!, {r4} ; pop new task cpsr
- MSR cpsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task spsr
+ MSR spsr_cxsf, r4
+ LDMFD sp!, {r4} ; pop new task cpsr
+ MSR cpsr_cxsf, r4
- LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
- ENDP
+ LDMFD sp!, {r0-r12, lr, pc} ; pop new task r0-r12, lr & pc
+ ENDP
;/*
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
; */
- IMPORT rt_thread_switch_interrupt_flag
- IMPORT rt_interrupt_from_thread
- IMPORT rt_interrupt_to_thread
+ IMPORT rt_thread_switch_interrupt_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
rt_hw_context_switch_interrupt PROC
- EXPORT rt_hw_context_switch_interrupt
- LDR r2, =rt_thread_switch_interrupt_flag
- LDR r3, [r2]
- CMP r3, #1
- BEQ _reswitch
- MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1
- STR r3, [r2]
- LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
- STR r0, [r2]
+ EXPORT rt_hw_context_switch_interrupt
+ LDR r2, =rt_thread_switch_interrupt_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1
+ STR r3, [r2]
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
_reswitch
- LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
- STR r1, [r2]
- BX lr
- ENDP
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+ BX lr
+ ENDP
- END \ No newline at end of file
+ END \ No newline at end of file
diff --git a/libcpu/arm/AT91SAM7X/SConscript b/libcpu/arm/AT91SAM7X/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/AT91SAM7X/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/AT91SAM7X/context_rvds.S b/libcpu/arm/AT91SAM7X/context_rvds.S
index 641ec7a6b1..0d8bf56237 100644
--- a/libcpu/arm/AT91SAM7X/context_rvds.S
+++ b/libcpu/arm/AT91SAM7X/context_rvds.S
@@ -1,16 +1,12 @@
-;/*
-; * File : context_rvds.S
-; * 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
-; * 2009-01-20 Bernard first version
-; */
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-01-20 Bernard first version
+ */
NOINT EQU 0xc0 ; disable interrupt in psr
diff --git a/libcpu/arm/SConscript b/libcpu/arm/SConscript
new file mode 100644
index 0000000000..f6ea13fb91
--- /dev/null
+++ b/libcpu/arm/SConscript
@@ -0,0 +1,16 @@
+# RT-Thread building script for bridge
+
+import os
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+
+# add common code files
+group = SConscript(os.path.join('common', 'SConscript'))
+
+# cpu porting code files
+group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
+
+Return('group')
diff --git a/libcpu/arm/am335x/SConscript b/libcpu/arm/am335x/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/am335x/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/am335x/start_gcc.S b/libcpu/arm/am335x/start_gcc.S
index 6b76fb04a4..7e996e2a80 100644
--- a/libcpu/arm/am335x/start_gcc.S
+++ b/libcpu/arm/am335x/start_gcc.S
@@ -33,6 +33,7 @@
.globl stack_start
.globl stack_top
+.align 3
stack_start:
.rept ISR_Stack_Size
.long 0
diff --git a/libcpu/arm/arm926/SConscript b/libcpu/arm/arm926/SConscript
new file mode 100644
index 0000000000..00785a135b
--- /dev/null
+++ b/libcpu/arm/arm926/SConscript
@@ -0,0 +1,25 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+ASFLAGS = ''
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+ ASFLAGS = ' --cpreproc'
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH, ASFLAGS = ASFLAGS)
+
+Return('group')
diff --git a/libcpu/arm/arm926/context_gcc.S b/libcpu/arm/arm926/context_gcc.S
index 5152618d24..f69aa9f5ba 100644
--- a/libcpu/arm/arm926/context_gcc.S
+++ b/libcpu/arm/arm926/context_gcc.S
@@ -1,21 +1,7 @@
;/*
-; * File : context_iar.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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.
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -24,6 +10,7 @@
#define NOINT 0xC0
+.text
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
diff --git a/libcpu/arm/arm926/context_iar.S b/libcpu/arm/arm926/context_iar.S
index 14110e5220..902552734e 100644
--- a/libcpu/arm/arm926/context_iar.S
+++ b/libcpu/arm/arm926/context_iar.S
@@ -1,27 +1,13 @@
-;/*
-; * File : context_iar.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, 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
-; * 2011-08-14 weety copy from mini2440
-; * 2015-04-15 ArdaFu convert from context_gcc.s
-; */
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-08-14 weety copy from mini2440
+ * 2015-04-15 ArdaFu convert from context_gcc.s
+ */
#define NOINT 0xc0
diff --git a/libcpu/arm/arm926/context_rvds.S b/libcpu/arm/arm926/context_rvds.S
index 32bd235fef..03eff68d4c 100644
--- a/libcpu/arm/arm926/context_rvds.S
+++ b/libcpu/arm/arm926/context_rvds.S
@@ -1,24 +1,10 @@
;/*
-; * file : context_rvds.s
-; * this file is part of rt-thread rtos
-; * copyright (c) 2006, rt-thread development team
+; * Copyright (c) 2006-2018, 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.
+; * SPDX-License-Identifier: Apache-2.0
; *
-; * 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
+; * Change Logs:
+; * Date Author Notes
; * 2011-08-14 weety copy from mini2440
; */
diff --git a/libcpu/arm/arm926/cpuport.c b/libcpu/arm/arm926/cpuport.c
index 1efb23e896..035e97d543 100644
--- a/libcpu/arm/arm926/cpuport.c
+++ b/libcpu/arm/arm926/cpuport.c
@@ -23,30 +23,30 @@ rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
- __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+ __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
__asm volatile(\
- "mrc p15,0,r0,c1,c0,0\n\t" \
- "orr r0,r0,%0\n\t" \
- "mcr p15,0,r0,c1,c0,0" \
- : \
- :"r" (bit) \
- :"memory");
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "orr r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ : "r"(bit) \
+ : "memory");
}
rt_inline void cache_disable(rt_uint32_t bit)
{
__asm volatile(\
- "mrc p15,0,r0,c1,c0,0\n\t" \
- "bic r0,r0,%0\n\t" \
- "mcr p15,0,r0,c1,c0,0" \
- : \
- :"r" (bit) \
- :"memory");
+ "mrc p15,0,r0,c1,c0,0\n\t" \
+ "bic r0,r0,%0\n\t" \
+ "mcr p15,0,r0,c1,c0,0" \
+ : \
+ : "r"(bit) \
+ : "memory");
}
#endif
@@ -152,7 +152,7 @@ void rt_hw_cpu_reset()
rt_kprintf("Restarting system...\n");
machine_reset();
- while(1); /* loop forever and wait for reset to happen */
+ while (1); /* loop forever and wait for reset to happen */
/* NEVER REACHED */
}
@@ -206,21 +206,7 @@ int __rt_ffs(int value)
#elif defined(__GNUC__) || defined(__ICCARM__)
int __rt_ffs(int value)
{
- register rt_uint32_t x;
-
- if (value == 0)
- return value;
-
- __asm
- (
- "rsb %[temp], %[val], #0\n"
- "and %[temp], %[temp], %[val]\n"
- "clz %[temp], %[temp]\n"
- "rsb %[temp], %[temp], #32\n"
- :[temp] "=r"(x)
- :[val] "r"(value)
- );
- return x;
+ return __builtin_ffs(value);
}
#endif
diff --git a/libcpu/arm/arm926/machine.c b/libcpu/arm/arm926/machine.c
new file mode 100644
index 0000000000..aa26d10ec6
--- /dev/null
+++ b/libcpu/arm/arm926/machine.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-02-08 RT-Thread the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+RT_WEAK void machine_reset(void)
+{
+ rt_kprintf("reboot system...\n");
+ rt_hw_interrupt_disable();
+ while (1);
+}
+
+RT_WEAK void machine_shutdown(void)
+{
+ rt_kprintf("shutdown...\n");
+ rt_hw_interrupt_disable();
+ while (1);
+}
+
diff --git a/libcpu/arm/arm926/mmu.c b/libcpu/arm/arm926/mmu.c
index f1e475189b..19d70b9b0b 100644
--- a/libcpu/arm/arm926/mmu.c
+++ b/libcpu/arm/arm926/mmu.c
@@ -140,7 +140,7 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
- while(ptr < buffer + size)
+ while (ptr < buffer + size)
{
__asm volatile { MCR p15, 0, ptr, c7, c14, 1 }
ptr += CACHE_LINE_SIZE;
@@ -211,18 +211,18 @@ void mmu_setttbase(register rt_uint32_t i)
* set by page table entry
*/
value = 0;
- asm volatile ("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
+ asm volatile("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
value = 0x55555555;
- asm volatile ("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
+ asm volatile("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
- asm volatile ("mcr p15, 0, %0, c2, c0, 0"::"r"(i));
+ asm volatile("mcr p15, 0, %0, c2, c0, 0"::"r"(i));
}
void mmu_set_domain(register rt_uint32_t i)
{
- asm volatile ("mcr p15,0, %0, c3, c0, 0": :"r" (i));
+ asm volatile("mcr p15,0, %0, c3, c0, 0": :"r"(i));
}
void mmu_enable()
@@ -321,7 +321,7 @@ void mmu_disable_alignfault()
void mmu_clean_invalidated_cache_index(int index)
{
- asm volatile ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
+ asm volatile("mcr p15, 0, %0, c7, c14, 2": :"r"(index));
}
void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
@@ -330,9 +330,9 @@ void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
- while(ptr < buffer + size)
+ while (ptr < buffer + size)
{
- asm volatile ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr));
+ asm volatile("mcr p15, 0, %0, c7, c14, 1": :"r"(ptr));
ptr += CACHE_LINE_SIZE;
}
@@ -347,7 +347,7 @@ void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
while (ptr < buffer + size)
{
- asm volatile ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr));
+ asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr));
ptr += CACHE_LINE_SIZE;
}
@@ -361,7 +361,7 @@ void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
while (ptr < buffer + size)
{
- asm volatile ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr));
+ asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr));
ptr += CACHE_LINE_SIZE;
}
@@ -369,19 +369,19 @@ void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
void mmu_invalidate_tlb()
{
- asm volatile ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
+ asm volatile("mcr p15, 0, %0, c8, c7, 0": :"r"(0));
}
void mmu_invalidate_icache()
{
- asm volatile ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
+ asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0));
}
void mmu_invalidate_dcache_all()
{
- asm volatile ("mcr p15, 0, %0, c7, c6, 0": :"r" (0));
+ asm volatile("mcr p15, 0, %0, c7, c6, 0": :"r"(0));
}
#endif
@@ -389,10 +389,10 @@ void mmu_invalidate_dcache_all()
/* level1 page table */
#if defined(__ICCARM__)
#pragma data_alignment=(16*1024)
-static volatile rt_uint32_t _page_table[4*1024];
+static volatile rt_uint32_t _page_table[4 * 1024];
#else
-static volatile rt_uint32_t _page_table[4*1024] \
- __attribute__((aligned(16*1024)));
+static volatile rt_uint32_t _page_table[4 * 1024] \
+__attribute__((aligned(16 * 1024)));
#endif
void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd,
@@ -401,11 +401,11 @@ void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd,
volatile rt_uint32_t *pTT;
volatile int nSec;
int i = 0;
- pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20);
- nSec=(vaddrEnd>>20)-(vaddrStart>>20);
- for(i=0; i<=nSec; i++)
+ pTT = (rt_uint32_t *)_page_table + (vaddrStart >> 20);
+ nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
+ for (i = 0; i <= nSec; i++)
{
- *pTT = attr |(((paddrStart>>20)+i)<<20);
+ *pTT = attr | (((paddrStart >> 20) + i) << 20);
pTT++;
}
}
diff --git a/libcpu/arm/arm926/mmu.h b/libcpu/arm/arm926/mmu.h
index 7b930f5358..36fdbeacd8 100644
--- a/libcpu/arm/arm926/mmu.h
+++ b/libcpu/arm/arm926/mmu.h
@@ -5,6 +5,7 @@
*
* Change Logs:
* Date Author Notes
+ * 2018-02-08 RT-Thread the first version
*/
#ifndef __MMU_H__
@@ -45,5 +46,7 @@ struct mem_desc
};
void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
-
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size);
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
#endif
diff --git a/libcpu/arm/arm926/stack.c b/libcpu/arm/arm926/stack.c
index fa98feb824..f90bfa8c22 100644
--- a/libcpu/arm/arm926/stack.c
+++ b/libcpu/arm/arm926/stack.c
@@ -38,7 +38,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
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 *)stack_addr;
*(--stk) = (rt_uint32_t)tentry; /* entry point */
*(--stk) = (rt_uint32_t)texit; /* lr */
diff --git a/libcpu/arm/arm926/start_gcc.S b/libcpu/arm/arm926/start_gcc.S
index fee8e018cb..35c1f1722e 100644
--- a/libcpu/arm/arm926/start_gcc.S
+++ b/libcpu/arm/arm926/start_gcc.S
@@ -11,295 +11,320 @@
* 2015-06-04 aozima Align stack address to 8 byte.
*/
-#include "rt_low_level_init.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 MODEMASK, 0x1F
+.equ NOINT, 0xC0
-#define S_FRAME_SIZE (18*4) //72
+.equ I_BIT, 0x80
+.equ F_BIT, 0x40
-@#define S_SPSR (17*4) //SPSR
-@#define S_CPSR (16*4) //CPSR
-#define S_PC (15*4) //R15
-@#define S_LR (14*4) //R14
-@#define S_SP (13*4) //R13
+.equ UND_STACK_SIZE, 0x00000100
+.equ SVC_STACK_SIZE, 0x00000100
+.equ ABT_STACK_SIZE, 0x00000100
+.equ FIQ_STACK_SIZE, 0x00000100
+.equ IRQ_STACK_SIZE, 0x00000100
+.equ SYS_STACK_SIZE, 0x00000100
-@#define S_IP (12*4) //R12
-@#define S_FP (11*4) //R11
-@#define S_R10 (10*4)
-@#define S_R9 (9*4)
-@#define S_R8 (8*4)
-@#define S_R7 (7*4)
-@#define S_R6 (6*4)
-@#define S_R5 (5*4)
-@#define S_R4 (4*4)
-@#define S_R3 (3*4)
-@#define S_R2 (2*4)
-@#define S_R1 (1*4)
-@#define S_R0 (0*4)
+ /*
+ ***************************************
+ * Interrupt vector table
+ ***************************************
+ */
+.section .vectors
+.code 32
-#define MODE_SYS 0x1F
-#define MODE_FIQ 0x11
-#define MODE_IRQ 0x12
-#define MODE_SVC 0x13
-#define MODE_ABT 0x17
-#define MODE_UND 0x1B
-#define MODEMASK 0x1F
+.global 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
-#define NOINT 0xC0
+_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
-@;----------------------- Stack and Heap Definitions ---------------------------
- .section .nobss, "w"
+.balignl 16,0xdeadbeef
- .space UND_STK_SIZE
+ /*
+ ***************************************
+ * Stack and Heap Definitions
+ ***************************************
+ */
+ .section .data
+ .space UND_STACK_SIZE
.align 3
- .global UND_STACK_START
-UND_STACK_START:
+ .global und_stack_start
+und_stack_start:
- .space ABT_STK_SIZE
+ .space ABT_STACK_SIZE
.align 3
- .global ABT_STACK_START
-ABT_STACK_START:
+ .global abt_stack_start
+abt_stack_start:
- .space FIQ_STK_SIZE
+ .space FIQ_STACK_SIZE
.align 3
- .global FIQ_STACK_START
-FIQ_STACK_START:
+ .global fiq_stack_start
+fiq_stack_start:
- .space IRQ_STK_SIZE
+ .space IRQ_STACK_SIZE
.align 3
- .global IRQ_STACK_START
-IRQ_STACK_START:
+ .global irq_stack_start
+irq_stack_start:
- .skip SYS_STK_SIZE
+ .skip SYS_STACK_SIZE
.align 3
- .global SYS_STACK_START
-SYS_STACK_START:
+ .global sys_stack_start
+sys_stack_start:
- .space SVC_STK_SIZE
+ .space SVC_STACK_SIZE
.align 3
- .global SVC_STACK_START
-SVC_STACK_START:
-
-@;--------------Jump vector table-----------------------------------------------
- .section .init, "ax"
- .arm
+ .global svc_stack_start
+svc_stack_start:
- .global start
-start:
- 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
+/*
+ ***************************************
+ * Startup Code
+ ***************************************
+ */
+ .section .text
+ .global reset
+reset:
+ /* Enter svc mode and mask interrupts */
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
+ orr r0, r0, #MODE_SVC|NOINT
+ msr cpsr_cxsf, r0
-vector_reset:
- .word Reset_Handler
-vector_undef:
- .word Undef_Handler
-vector_swi:
- .word SWI_Handler
-vector_pabt:
- .word PAbt_Handler
-vector_dabt:
- .word DAbt_Handler
-vector_resv:
- .word Resv_Handler
-vector_irq:
- .word IRQ_Handler
-vector_fiq:
- .word FIQ_Handler
+ /* init cpu */
+ bl cpu_init_crit
+
+ /* todo:copyself to link address */
+
+ /* Copy vector to the correct address */
+ ldr r0, =system_vectors
+ mrc p15, 0, r2, c1, c0, 0
+ ands r2, r2, #(1 << 13)
+ ldreq r1, =0x00000000
+ ldrne r1, =0xffff0000
+ ldmia r0!, {r2-r8, r10}
+ stmia r1!, {r2-r8, r10}
+ ldmia r0!, {r2-r8, r10}
+ stmia r1!, {r2-r8, r10}
- .balignl 16,0xdeadbeef
+ /* turn off the watchdog */
+ ldr r0, =0x01C20CB8
+ mov r1, #0x0
+ str r1, [r0]
-@;----------------- Reset Handler ---------------------------------------------
- .global rt_low_level_init
- .global main
- .global Reset_Handler
-Reset_Handler:
- @; Set the cpu to SVC32 mode
- MRS R0, CPSR
- BIC R0, R0, #MODEMASK
- ORR R0, R0, #MODE_SVC|NOINT
- MSR CPSR_cxsf, R0
+ /* mask all IRQs source */
+ ldr r1, =0xffffffff
+ ldr r0, =0x01C20430
+ str r1, [r0], #0x04
+ str r1, [r0]
+
+ /* Call low level init function */
+ ldr sp, =svc_stack_start
+ ldr r0, =rt_low_level_init
+ blx r0
- @; Set CO-Processor
- @; little-end锛宒isbale I/D Cache MMU, vector table is 0x00000000
- MRC P15, 0, R0, C1, C0, 0 @; Read CP15
- LDR R1, =0x00003085 @; set clear bits
- BIC R0, R0, R1
- MCR P15, 0, R0, C1, C0, 0 @; Write CP15
+ /* init stack */
+ bl stack_setup
+
+ /* clear bss */
+ mov r0, #0
+ ldr r1, =__bss_start
+ ldr r2, =__bss_end
+
+bss_clear_loop:
+ cmp r1, r2
+ strlo r0, [r1], #4
+ blo bss_clear_loop
+
+ /* call c++ constructors of global objects */
+ /*
+ ldr r0, =__ctors_start__
+ ldr r1, =__ctors_end__
+
+ctor_loop:
+ cmp r0, r1
+ beq ctor_end
+ ldr r2, [r0], #4
+ stmfd sp!, {r0-r1}
+ mov lr, pc
+ bx r2
+ ldmfd sp!, {r0-r1}
+ b ctor_loop
+ctor_end:
+ */
+ /* start RT-Thread Kernel */
+ ldr pc, _rtthread_startup
+_rtthread_startup:
+ .word rtthread_startup
- @; Call low level init function,
- @; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
- LDR SP, =SVC_STACK_START
- LDR R0, =rt_low_level_init
- BLX R0
-Setup_Stack:
- @; Setup Stack for each mode
- MRS R0, CPSR
- BIC R0, R0, #MODEMASK
- ORR R1, R0, #MODE_UND|NOINT
- MSR CPSR_cxsf, R1 @; Undef mode
- LDR SP, =UND_STACK_START
+cpu_init_crit:
+ /* invalidate I/D caches */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0
+ mcr p15, 0, r0, c8, c7, 0
- ORR R1, R0, #MODE_ABT|NOINT
- MSR CPSR_cxsf, R1 @; Abort mode
- LDR SP, =ABT_STACK_START
+ /* disable MMU stuff and caches */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300
+ bic r0, r0, #0x00000087
+ orr r0, r0, #0x00000002
+ orr r0, r0, #0x00001000
+ mcr p15, 0, r0, c1, c0, 0
- ORR R1, R0, #MODE_IRQ|NOINT
- MSR CPSR_cxsf, R1 @; IRQ mode
- LDR SP, =IRQ_STACK_START
+ bx lr
+
+stack_setup:
+ /* Setup Stack for each mode */
+ mrs r0, cpsr
+ bic r0, r0, #MODEMASK
- ORR R1, R0, #MODE_FIQ|NOINT
- MSR CPSR_cxsf, R1 @; FIQ mode
- LDR SP, =FIQ_STACK_START
+ orr r1, r0, #MODE_UND|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =und_stack_start
- ORR R1, R0, #MODE_SYS|NOINT
- MSR CPSR_cxsf,R1 @; SYS/User mode
- LDR SP, =SYS_STACK_START
+ orr r1, r0, #MODE_ABT|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =abt_stack_start
- ORR R1, R0, #MODE_SVC|NOINT
- MSR CPSR_cxsf, R1 @; SVC mode
- LDR SP, =SVC_STACK_START
+ orr r1, r0, #MODE_IRQ|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =irq_stack_start
- @; clear .bss
- MOV R0, #0 @; get a zero
- LDR R1, =__bss_start__ @; bss start
- LDR R2, =__bss_end__ @; bss end
+ orr r1, r0, #MODE_FIQ|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =fiq_stack_start
-bss_clear_loop:
- CMP R1, R2 @; check if data to clear
- STRLO R0, [R1], #4 @; clear 4 bytes
- BLO bss_clear_loop @; loop until done
+ orr r1, r0, #MODE_SYS|NOINT
+ msr cpsr_cxsf,r1
+ ldr sp, =sys_stack_start
- @; call C++ constructors of global objects
- LDR R0, =__ctors_start__
- LDR R1, =__ctors_end__
+ orr r1, r0, #MODE_SVC|NOINT
+ msr cpsr_cxsf, r1
+ ldr sp, =svc_stack_start
-ctor_loop:
- CMP R0, R1
- BEQ ctor_end
- LDR R2, [R0], #4
- STMFD SP!, {R0-R1}
- MOV LR, PC
- BX R2
- LDMFD SP!, {R0-R1}
- B ctor_loop
-ctor_end:
+ bx lr
+
+/*
+ ***************************************
+ * exception handlers
+ ***************************************
+ */
+ /* Interrupt */
+vector_fiq:
+ stmfd sp!,{r0-r7,lr}
+ bl rt_hw_trap_fiq
+ ldmfd sp!,{r0-r7,lr}
+ subs pc, lr, #4
- @; Enter the C code
- LDR R0, =rtthread_startup
- BLX R0
+vector_irq:
+ stmfd sp!, {r0-r12,lr}
-@;----------------- Exception Handler -----------------------------------------
- .global rt_hw_trap_udef
- .global rt_hw_trap_swi
- .global rt_hw_trap_pabt
- .global rt_hw_trap_dabt
- .global rt_hw_trap_resv
- .global rt_hw_trap_irq
- .global rt_hw_trap_fiq
+ bl rt_interrupt_enter
+ bl rt_hw_trap_irq
+ bl rt_interrupt_leave
- .global rt_interrupt_enter
- .global rt_interrupt_leave
- .global rt_thread_switch_interrupt_flag
- .global rt_interrupt_from_thread
- .global rt_interrupt_to_thread
-
- .align 5
-Undef_Handler:
- SUB SP, SP, #S_FRAME_SIZE
- STMIA SP, {R0 - R12} @; Calling R0-R12
- ADD R8, SP, #S_PC
- STMDB R8, {SP, LR} @; Calling SP, LR
- STR LR, [R8, #0] @; Save calling PC
- MRS R6, SPSR
- STR R6, [R8, #4] @; Save CPSR
- STR R0, [R8, #8] @; Save SPSR
- MOV R0, SP
- BL rt_hw_trap_udef
-
- .align 5
-SWI_Handler:
- BL rt_hw_trap_swi
-
- .align 5
-PAbt_Handler:
- BL rt_hw_trap_pabt
+ ldr r0, =rt_thread_switch_interrupt_flag
+ ldr r1, [r0]
+ cmp r1, #1
+ beq rt_hw_context_switch_interrupt_do
- .align 5
-DAbt_Handler:
- SUB SP, SP, #S_FRAME_SIZE
- STMIA SP, {R0 - R12} @; Calling R0-R12
- ADD R8, SP, #S_PC
- STMDB R8, {SP, LR} @; Calling SP, LR
- STR LR, [R8, #0] @; Save calling PC
- MRS R6, SPSR
- STR R6, [R8, #4] @; Save CPSR
- STR R0, [R8, #8] @; Save SPSR
- MOV R0, SP
- BL rt_hw_trap_dabt
+ ldmfd sp!, {r0-r12,lr}
+ subs pc, lr, #4
- .align 5
-Resv_Handler:
- BL rt_hw_trap_resv
+rt_hw_context_switch_interrupt_do:
+ mov r1, #0
+ str r1, [r0]
- .align 5
-FIQ_Handler:
- STMFD SP!, {R0-R7,LR}
- BL rt_hw_trap_fiq
- LDMFD SP!, {R0-R7,LR}
- SUBS PC, LR, #4
+ mov r1, sp
+ add sp, sp, #4*4
+ ldmfd sp!, {r4-r12,lr}
+ mrs r0, spsr
+ sub r2, lr, #4
- .align 5
-IRQ_Handler:
- STMFD SP!, {R0-R12,LR}
- BL rt_interrupt_enter
- BL rt_hw_trap_irq
- BL rt_interrupt_leave
+ msr cpsr_c, #I_BIT|F_BIT|MODE_SVC
- @; 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
+ stmfd sp!, {r2}
+ stmfd sp!, {r4-r12,lr}
+ ldmfd r1, {r1-r4}
+ stmfd sp!, {r1-r4}
+ stmfd sp!, {r0}
- LDMFD SP!, {R0-R12,LR}
- SUBS PC, LR, #4
+ ldr r4, =rt_interrupt_from_thread
+ ldr r5, [r4]
+ str sp, [r5]
-@;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
-rt_hw_context_switch_interrupt_do:
- MOV R1, #0 @; Clear flag
- STR R1, [R0] @; Save to flag variable
+ ldr r6, =rt_interrupt_to_thread
+ ldr r6, [r6]
+ ldr sp, [r6]
- LDMFD SP!, {R0-R12,LR} @; Reload saved registers
- STMFD SP, {R0-R2} @; Save R0-R2
- SUB R1, SP, #4*3 @; Save old task's SP to R1
- SUB R2, LR, #4 @; Save old task's PC to R2
+ ldmfd sp!, {r4}
+ msr spsr_cxsf, r4
- MRS R0, SPSR @; Get CPSR of interrupt thread
+ ldmfd sp!, {r0-r12,lr,pc}^
- MSR CPSR_c, #MODE_SVC|NOINT @; Switch to SVC mode and no interrupt
+ /* Exception */
+.macro push_svc_reg
+ sub sp, sp, #17 * 4
+ stmia sp, {r0 - r12}
+ mov r0, sp
+ mrs r6, spsr
+ str lr, [r0, #15*4]
+ str r6, [r0, #16*4]
+ str sp, [r0, #13*4]
+ str lr, [r0, #14*4]
+.endm
- STMFD SP!, {R2} @; Push old task's PC
- STMFD SP!, {R3-R12,LR} @; Push old task's LR,R12-R3
- LDMFD R1, {R1-R3}
- STMFD SP!, {R1-R3} @; Push old task's R2-R0
- STMFD SP!, {R0} @; Push old task's CPSR
+vector_swi:
+ push_svc_reg
+ bl rt_hw_trap_swi
+ b .
- LDR R4, =rt_interrupt_from_thread
- LDR R5, [R4] @; R5 = stack ptr in old tasks's TCB
- STR SP, [R5] @; Store SP in preempted tasks's TCB
+vector_undef:
+ push_svc_reg
+ bl rt_hw_trap_udef
+ b .
- LDR R6, =rt_interrupt_to_thread
- LDR R6, [R6] @; R6 = stack ptr in new tasks's TCB
- LDR SP, [R6] @; Get new task's stack pointer
+vector_pabt:
+ push_svc_reg
+ bl rt_hw_trap_pabt
+ b .
- LDMFD SP!, {R4} @; Pop new task's SPSR
- MSR SPSR_cxsf, R4
+vector_dabt:
+ push_svc_reg
+ bl rt_hw_trap_dabt
+ b .
- LDMFD SP!, {R0-R12,LR,PC}^ @; pop new task's R0-R12,LR & PC SPSR 2 CPSR
+vector_resv:
+ push_svc_reg
+ bl rt_hw_trap_resv
+ b .
diff --git a/libcpu/arm/arm926/start_iar.S b/libcpu/arm/arm926/start_iar.S
index 880f2d9706..080acd57b6 100644
--- a/libcpu/arm/arm926/start_iar.S
+++ b/libcpu/arm/arm926/start_iar.S
@@ -1,21 +1,7 @@
;/*
-; * File : start.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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.
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/arm926/start_rvds.S b/libcpu/arm/arm926/start_rvds.S
index 9f789b97f7..fc7e84ffaa 100644
--- a/libcpu/arm/arm926/start_rvds.S
+++ b/libcpu/arm/arm926/start_rvds.S
@@ -1,21 +1,7 @@
;/*
-; * File : start_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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.
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -25,28 +11,16 @@
; * 2015-06-04 aozima Align stack address to 8 byte.
; */
-#include "rt_low_level_init.h"
+UND_STK_SIZE EQU 512
+SVC_STK_SIZE EQU 4096
+ABT_STK_SIZE EQU 512
+IRQ_STK_SIZE EQU 1024
+FIQ_STK_SIZE EQU 1024
+SYS_STK_SIZE EQU 512
+Heap_Size EQU 512
S_FRAME_SIZE EQU (18*4) ;72
-;S_SPSR EQU (17*4) ;SPSR
-;S_CPSR EQU (16*4) ;CPSR
S_PC EQU (15*4) ;R15
-;S_LR EQU (14*4) ;R14
-;S_SP EQU (13*4) ;R13
-
-;S_IP EQU (12*4) ;R12
-;S_FP EQU (11*4) ;R11
-;S_R10 EQU (10*4)
-;S_R9 EQU (9*4)
-;S_R8 EQU (8*4)
-;S_R7 EQU (7*4)
-;S_R6 EQU (6*4)
-;S_R5 EQU (5*4)
-;S_R4 EQU (4*4)
-;S_R3 EQU (3*4)
-;S_R2 EQU (2*4)
-;S_R1 EQU (1*4)
-;S_R0 EQU (0*4)
MODE_USR EQU 0X10
MODE_FIQ EQU 0X11
diff --git a/libcpu/arm/arm926/trap.c b/libcpu/arm/arm926/trap.c
index 054cc2741a..9e7ba48037 100644
--- a/libcpu/arm/arm926/trap.c
+++ b/libcpu/arm/arm926/trap.c
@@ -41,14 +41,18 @@ struct rt_hw_register
rt_uint32_t cpsr;
rt_uint32_t ORIG_r0;
};
-
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
+{
+ rt_exception_hook = exception_handle;
+}
/**
* this function will show registers of CPU
*
* @param regs the registers point
*/
-void rt_hw_show_register (struct rt_hw_register *regs)
+void rt_hw_show_register(struct rt_hw_register *regs)
{
rt_kprintf("Execption:\n");
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
@@ -74,6 +78,13 @@ void rt_hw_show_register (struct rt_hw_register *regs)
*/
void rt_hw_trap_udef(struct rt_hw_register *regs)
{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
rt_hw_show_register(regs);
rt_kprintf("undefined instruction\n");
@@ -96,6 +107,13 @@ void rt_hw_trap_udef(struct rt_hw_register *regs)
*/
void rt_hw_trap_swi(struct rt_hw_register *regs)
{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
rt_hw_show_register(regs);
rt_kprintf("software interrupt\n");
@@ -112,6 +130,13 @@ void rt_hw_trap_swi(struct rt_hw_register *regs)
*/
void rt_hw_trap_pabt(struct rt_hw_register *regs)
{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
rt_hw_show_register(regs);
rt_kprintf("prefetch abort\n");
@@ -133,6 +158,13 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs)
*/
void rt_hw_trap_dabt(struct rt_hw_register *regs)
{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
rt_hw_show_register(regs);
rt_kprintf("data abort\n");
@@ -153,55 +185,26 @@ void rt_hw_trap_dabt(struct rt_hw_register *regs)
*/
void rt_hw_trap_resv(struct rt_hw_register *regs)
{
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(regs);
+ if (result == RT_EOK) return;
+ }
rt_kprintf("not used\n");
rt_hw_show_register(regs);
rt_hw_cpu_shutdown();
}
-extern struct rt_irq_desc irq_desc[];
-extern rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq);
-extern void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id);
-
-void rt_hw_trap_irq()
-{
- rt_isr_handler_t isr_func;
- rt_uint32_t irq;
- void *param;
-
- /* get irq number */
- irq = rt_hw_interrupt_get_active(INT_IRQ);
+extern void rt_interrupt_dispatch(rt_uint32_t fiq_irq);
- /* get interrupt service routine */
- isr_func = irq_desc[irq].handler;
- param = irq_desc[irq].param;
-
- /* turn to interrupt service routine */
- isr_func(irq, param);
-
- rt_hw_interrupt_ack(INT_IRQ, irq);
-#ifdef RT_USING_INTERRUPT_INFO
- irq_desc[irq].counter ++;
-#endif
+void rt_hw_trap_irq(void)
+{
+ rt_interrupt_dispatch(INT_IRQ);
}
-void rt_hw_trap_fiq()
+void rt_hw_trap_fiq(void)
{
- rt_isr_handler_t isr_func;
- rt_uint32_t irq;
- void *param;
-
- /* get irq number */
- irq = rt_hw_interrupt_get_active(INT_FIQ);
-
- /* get interrupt service routine */
- isr_func = irq_desc[irq].handler;
- param = irq_desc[irq].param;
-
- /* turn to interrupt service routine */
- isr_func(irq, param);
-
- rt_hw_interrupt_ack(INT_FIQ, irq);
-#ifdef RT_USING_INTERRUPT_INFO
- irq_desc[irq].counter ++;
-#endif
+ rt_interrupt_dispatch(INT_FIQ);
}
diff --git a/libcpu/arm/armv6/SConscript b/libcpu/arm/armv6/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/armv6/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/common/SConscript b/libcpu/arm/common/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/common/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/common/backtrace.c b/libcpu/arm/common/backtrace.c
index f61c69ef01..4fc87b20d1 100644
--- a/libcpu/arm/common/backtrace.c
+++ b/libcpu/arm/common/backtrace.c
@@ -13,51 +13,51 @@
#ifdef __GNUC__
/*
-->High Address,Stack Top
-PC<-----|
-LR |
-IP |
-FP |
-...... |
-PC<-| |
-LR | |
-IP | |
+PC<------|
+LR |
+IP |
+FP |
+...... |
+PC <-| |
+LR | |
+IP | |
FP---|-- |
-...... |
-PC |
-LR |
-IP |
+...... |
+PC |
+LR |
+IP |
FP---
-->Low Address,Stack Bottom
*/
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
{
- rt_uint32_t i, pc, func_entry;
+ rt_uint32_t i, pc, func_entry;
- pc = *fp;
- rt_kprintf("[0x%x]\n", pc-0xC);
+ pc = *fp;
+ rt_kprintf("[0x%x]\n", pc-0xC);
- for(i=0; i<10; i++)
- {
- fp = (rt_uint32_t *)*(fp - 3);
- pc = *fp ;
+ for(i=0; i<10; i++)
+ {
+ fp = (rt_uint32_t *)*(fp - 3);
+ pc = *fp ;
- func_entry = pc - 0xC;
+ func_entry = pc - 0xC;
- if(func_entry <= 0x30000000) break;
+ if(func_entry <= 0x30000000) break;
- if(func_entry == thread_entry)
- {
- rt_kprintf("EntryPoint:0x%x\n", func_entry);
+ if(func_entry == thread_entry)
+ {
+ rt_kprintf("EntryPoint:0x%x\n", func_entry);
- break;
- }
+ break;
+ }
- rt_kprintf("[0x%x]\n", func_entry);
- }
+ rt_kprintf("[0x%x]\n", func_entry);
+ }
}
#else
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
{
- /* old compiler implementation */
+ /* old compiler implementation */
}
#endif
diff --git a/libcpu/arm/cortex-a/SConscript b/libcpu/arm/cortex-a/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-a/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-a/cache.c b/libcpu/arm/cortex-a/cache.c
new file mode 100644
index 0000000000..30af86baa1
--- /dev/null
+++ b/libcpu/arm/cortex-a/cache.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-03-29 quanzhao the first version
+ */
+#include <rthw.h>
+#include <rtdef.h>
+
+rt_inline rt_uint32_t rt_cpu_icache_line_size(void)
+{
+ rt_uint32_t ctr;
+ asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr));
+ return 4 << (ctr & 0xF);
+}
+
+rt_inline rt_uint32_t rt_cpu_dcache_line_size(void)
+{
+ rt_uint32_t ctr;
+ asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr));
+ return 4 << ((ctr >> 16) & 0xF);
+}
+
+void rt_hw_cpu_icache_invalidate(void *addr, int size)
+{
+ rt_uint32_t line_size = rt_cpu_icache_line_size();
+ rt_uint32_t start_addr = (rt_uint32_t)addr;
+ rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
+
+ asm volatile ("dmb":::"memory");
+ start_addr &= ~(line_size-1);
+ end_addr &= ~(line_size-1);
+ while (start_addr < end_addr)
+ {
+ asm volatile ("mcr p15, 0, %0, c7, c5, 1" :: "r"(start_addr)); /* icimvau */
+ start_addr += line_size;
+ }
+ asm volatile ("dsb\n\tisb":::"memory");
+}
+
+void rt_hw_cpu_dcache_invalidate(void *addr, int size)
+{
+ rt_uint32_t line_size = rt_cpu_dcache_line_size();
+ rt_uint32_t start_addr = (rt_uint32_t)addr;
+ rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
+
+ asm volatile ("dmb":::"memory");
+ start_addr &= ~(line_size-1);
+ end_addr &= ~(line_size-1);
+ while (start_addr < end_addr)
+ {
+ asm volatile ("mcr p15, 0, %0, c7, c6, 1" :: "r"(start_addr)); /* dcimvac */
+ start_addr += line_size;
+ }
+ asm volatile ("dsb":::"memory");
+}
+
+void rt_hw_cpu_dcache_clean(void *addr, int size)
+{
+ rt_uint32_t line_size = rt_cpu_dcache_line_size();
+ rt_uint32_t start_addr = (rt_uint32_t)addr;
+ rt_uint32_t end_addr = (rt_uint32_t) addr + size + line_size - 1;
+
+ asm volatile ("dmb":::"memory");
+ start_addr &= ~(line_size-1);
+ end_addr &= ~(line_size-1);
+ while (start_addr < end_addr)
+ {
+ asm volatile ("mcr p15, 0, %0, c7, c10, 1" :: "r"(start_addr)); /* dccmvac */
+ start_addr += line_size;
+ }
+ asm volatile ("dsb":::"memory");
+}
+
+void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
+{
+ if (ops == RT_HW_CACHE_INVALIDATE)
+ rt_hw_cpu_icache_invalidate(addr, size);
+}
+
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+ if (ops == RT_HW_CACHE_FLUSH)
+ rt_hw_cpu_dcache_clean(addr, size);
+ else if (ops == RT_HW_CACHE_INVALIDATE)
+ rt_hw_cpu_dcache_invalidate(addr, size);
+}
+
+rt_base_t rt_hw_cpu_icache_status(void)
+{
+ return 0;
+}
+
+rt_base_t rt_hw_cpu_dcache_status(void)
+{
+ return 0;
+}
diff --git a/libcpu/arm/cortex-a/context_gcc.S b/libcpu/arm/cortex-a/context_gcc.S
index 97b3dbc447..768c5138e9 100644
--- a/libcpu/arm/cortex-a/context_gcc.S
+++ b/libcpu/arm/cortex-a/context_gcc.S
@@ -8,7 +8,14 @@
* 2013-07-05 Bernard the first version
*/
+#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();
*/
@@ -27,17 +34,19 @@ rt_hw_interrupt_enable:
bx lr
/*
- * void rt_hw_context_switch_to(rt_uint32 to);
- * r0 --> to
+ * 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
- ldmfd sp!, {r4} @ pop new task spsr
- msr spsr_cxsf, r4
-
- ldmfd sp!, {r0-r12, lr, pc}^ @ pop new task r0-r12, lr & pc
+#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:
@@ -47,9 +56,10 @@ _guest_switch_lvl:
.section .text.isr, "ax"
/*
- * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
- * r0 --> from
- * r1 --> to
+ * 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:
@@ -62,21 +72,67 @@ rt_hw_context_switch:
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
- 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
+#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
@@ -89,3 +145,38 @@ _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}
+1:
+#endif
+
+#ifdef RT_USING_LWP
+ ldmfd sp, {r13, r14}^ /* usr_sp, usr_lr */
+ add sp, #8
+#endif
+ ldmfd sp!, {r1}
+ msr spsr_cxsf, r1 /* original mode */
+ ldmfd sp!, {r0-r12,lr,pc}^ /* irq return */
+
diff --git a/libcpu/arm/cortex-a/cp15.h b/libcpu/arm/cortex-a/cp15.h
index 486f38200d..97c5b93ad2 100644
--- a/libcpu/arm/cortex-a/cp15.h
+++ b/libcpu/arm/cortex-a/cp15.h
@@ -5,6 +5,7 @@
*
* Change Logs:
* Date Author Notes
+ * 2018-03-25 quanzhao the first version
*/
#ifndef __CP15_H__
#define __CP15_H__
@@ -15,6 +16,9 @@ void rt_cpu_mmu_disable(void);
void rt_cpu_mmu_enable(void);
void rt_cpu_tlb_set(volatile unsigned long*);
+void rt_cpu_dcache_clean_flush(void);
+void rt_cpu_icache_flush(void);
+
void rt_cpu_vector_set_base(unsigned int addr);
#endif
diff --git a/libcpu/arm/cortex-a/cp15_gcc.S b/libcpu/arm/cortex-a/cp15_gcc.S
index 0e3e60655c..dd2436ffee 100644
--- a/libcpu/arm/cortex-a/cp15_gcc.S
+++ b/libcpu/arm/cortex-a/cp15_gcc.S
@@ -15,6 +15,11 @@ rt_cpu_get_smp_id:
.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
@@ -36,7 +41,7 @@ rt_hw_cpu_icache_enable:
_FLD_MAX_WAY:
.word 0x3ff
_FLD_MAX_IDX:
- .word 0x7ff
+ .word 0x7fff
.globl rt_cpu_dcache_clean_flush
rt_cpu_dcache_clean_flush:
@@ -84,6 +89,14 @@ finished:
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}
diff --git a/libcpu/arm/cortex-a/cpu.c b/libcpu/arm/cortex-a/cpu.c
index 2d78715011..7c6bf58a4b 100644
--- a/libcpu/arm/cortex-a/cpu.c
+++ b/libcpu/arm/cortex-a/cpu.c
@@ -6,28 +6,84 @@
* Change Logs:
* Date Author Notes
* 2011-09-15 Bernard first version
+ * 2018-11-22 Jesven add rt_hw_cpu_id()
*/
#include <rthw.h>
#include <rtthread.h>
#include <board.h>
+#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;
+}
+
+void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
+{
+ unsigned long tmp;
+ unsigned long newval;
+ rt_hw_spinlock_t lockval;
+
+ __asm__ __volatile__(
+ "pld [%0]"
+ ::"r"(&lock->slock)
+ );
+
+ __asm__ __volatile__(
+ "1: ldrex %0, [%3]\n"
+ " add %1, %0, %4\n"
+ " strex %2, %1, [%3]\n"
+ " teq %2, #0\n"
+ " bne 1b"
+ : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
+ : "r" (&lock->slock), "I" (1 << 16)
+ : "cc");
+
+ while (lockval.tickets.next != lockval.tickets.owner) {
+ __asm__ __volatile__("wfe":::"memory");
+ lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
+ }
+
+ __asm__ volatile ("dmb":::"memory");
+}
+
+void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
+{
+ __asm__ volatile ("dmb":::"memory");
+ lock->tickets.owner++;
+ __asm__ volatile ("dsb ishst\nsev":::"memory");
+}
+#endif /*RT_USING_SMP*/
+
/**
- * @addtogroup AM33xx
+ * @addtogroup ARM CPU
*/
/*@{*/
/** shutdown CPU */
void rt_hw_cpu_shutdown()
{
- rt_uint32_t level;
- rt_kprintf("shutdown...\n");
+ rt_uint32_t level;
+ rt_kprintf("shutdown...\n");
- level = rt_hw_interrupt_disable();
- while (level)
- {
- RT_ASSERT(0);
- }
+ level = rt_hw_interrupt_disable();
+ while (level)
+ {
+ RT_ASSERT(0);
+ }
}
/*@}*/
diff --git a/libcpu/arm/cortex-a/gic.c b/libcpu/arm/cortex-a/gic.c
new file mode 100644
index 0000000000..2e94b88277
--- /dev/null
+++ b/libcpu/arm/cortex-a/gic.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2006-2018, 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()
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "gic.h"
+#include "cp15.h"
+
+struct arm_gic
+{
+ rt_uint32_t offset; /* the first interrupt index in the vector table */
+
+ rt_uint32_t dist_hw_base; /* the base address of the gic distributor */
+ rt_uint32_t cpu_hw_base; /* the base addrees of the gic cpu interface */
+};
+
+/* 'ARM_GIC_MAX_NR' is the number of cores */
+static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
+
+#define GIC_CPU_CTRL(hw_base) __REG32((hw_base) + 0x00)
+#define GIC_CPU_PRIMASK(hw_base) __REG32((hw_base) + 0x04)
+#define GIC_CPU_BINPOINT(hw_base) __REG32((hw_base) + 0x08)
+#define GIC_CPU_INTACK(hw_base) __REG32((hw_base) + 0x0c)
+#define GIC_CPU_EOI(hw_base) __REG32((hw_base) + 0x10)
+#define GIC_CPU_RUNNINGPRI(hw_base) __REG32((hw_base) + 0x14)
+#define GIC_CPU_HIGHPRI(hw_base) __REG32((hw_base) + 0x18)
+
+#define GIC_DIST_CTRL(hw_base) __REG32((hw_base) + 0x000)
+#define GIC_DIST_TYPE(hw_base) __REG32((hw_base) + 0x004)
+#define GIC_DIST_IGROUP(hw_base, n) __REG32((hw_base) + 0x080 + ((n)/32) * 4)
+#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + ((n)/32) * 4)
+#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + ((n)/32) * 4)
+#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200 + ((n)/32) * 4)
+#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + ((n)/32) * 4)
+#define GIC_DIST_ACTIVE_SET(hw_base, n) __REG32((hw_base) + 0x300 + ((n)/32) * 4)
+#define GIC_DIST_ACTIVE_CLEAR(hw_base, n) __REG32((hw_base) + 0x380 + ((n)/32) * 4)
+#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + ((n)/4) * 4)
+#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + ((n)/4) * 4)
+#define GIC_DIST_CONFIG(hw_base, n) __REG32((hw_base) + 0xc00 + ((n)/16) * 4)
+#define GIC_DIST_SOFTINT(hw_base) __REG32((hw_base) + 0xf00)
+#define GIC_DIST_CPENDSGI(hw_base, n) __REG32((hw_base) + 0xf10 + ((n)/4) * 4)
+#define GIC_DIST_ICPIDR2(hw_base) __REG32((hw_base) + 0xfe8)
+
+static unsigned int _gic_max_irq;
+
+int arm_gic_get_active_irq(rt_uint32_t index)
+{
+ int irq;
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = GIC_CPU_INTACK(_gic_table[index].cpu_hw_base);
+ irq += _gic_table[index].offset;
+ return irq;
+}
+
+void arm_gic_ack(rt_uint32_t index, int irq)
+{
+ rt_uint32_t mask = 1 << (irq % 32);
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = irq - _gic_table[index].offset;
+ RT_ASSERT(irq >= 0);
+
+ GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+ GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq;
+}
+
+void arm_gic_mask(rt_uint32_t index, int irq)
+{
+ rt_uint32_t mask = 1 << (irq % 32);
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = irq - _gic_table[index].offset;
+ RT_ASSERT(irq >= 0);
+
+ GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+void arm_gic_clear_pending(rt_uint32_t index, int irq)
+{
+ rt_uint32_t mask = 1 << (irq % 32);
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = irq - _gic_table[index].offset;
+ RT_ASSERT(irq >= 0);
+
+ GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+void arm_gic_clear_active(rt_uint32_t index, int irq)
+{
+ rt_uint32_t mask = 1 << (irq % 32);
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = irq - _gic_table[index].offset;
+ RT_ASSERT(irq >= 0);
+
+ GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+/* Set up the cpu mask for the specific interrupt */
+void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask)
+{
+ rt_uint32_t old_tgt;
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = irq - _gic_table[index].offset;
+ RT_ASSERT(irq >= 0);
+
+ old_tgt = GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq);
+
+ old_tgt &= ~(0x0FFUL << ((irq % 4)*8));
+ old_tgt |= cpumask << ((irq % 4)*8);
+
+ GIC_DIST_TARGET(_gic_table[index].dist_hw_base, irq) = old_tgt;
+}
+
+void arm_gic_umask(rt_uint32_t index, int irq)
+{
+ rt_uint32_t mask = 1 << (irq % 32);
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ irq = irq - _gic_table[index].offset;
+ RT_ASSERT(irq >= 0);
+
+ GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask;
+}
+
+void arm_gic_dump_type(rt_uint32_t index)
+{
+ unsigned int gic_type;
+
+ gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base);
+ rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n",
+ (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4) & 0xf,
+ _gic_table[index].dist_hw_base,
+ _gic_max_irq,
+ gic_type & (1 << 10) ? "has" : "no",
+ gic_type);
+}
+
+void arm_gic_dump(rt_uint32_t index)
+{
+ unsigned int i, k;
+
+ k = GIC_CPU_HIGHPRI(_gic_table[index].cpu_hw_base);
+ rt_kprintf("--- high pending priority: %d(%08x)\n", k, k);
+ rt_kprintf("--- hw mask ---\n");
+ for (i = 0; i < _gic_max_irq / 32; i++)
+ {
+ rt_kprintf("0x%08x, ",
+ GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base,
+ i * 32));
+ }
+ rt_kprintf("\n--- hw pending ---\n");
+ for (i = 0; i < _gic_max_irq / 32; i++)
+ {
+ rt_kprintf("0x%08x, ",
+ GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base,
+ i * 32));
+ }
+ rt_kprintf("\n--- hw active ---\n");
+ for (i = 0; i < _gic_max_irq / 32; i++)
+ {
+ rt_kprintf("0x%08x, ",
+ GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base,
+ i * 32));
+ }
+ rt_kprintf("\n");
+}
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT_ALIAS(arm_gic_dump, gic, show gic status);
+#endif
+
+int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start)
+{
+ unsigned int gic_type, i;
+ rt_uint32_t cpumask = 1 << 0;
+
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ _gic_table[index].dist_hw_base = dist_base;
+ _gic_table[index].offset = irq_start;
+
+ /* Find out how many interrupts are supported. */
+ gic_type = GIC_DIST_TYPE(dist_base);
+ _gic_max_irq = ((gic_type & 0x1f) + 1) * 32;
+
+ /*
+ * The GIC only supports up to 1020 interrupt sources.
+ * Limit this to either the architected maximum, or the
+ * platform maximum.
+ */
+ if (_gic_max_irq > 1020)
+ _gic_max_irq = 1020;
+ if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */
+ _gic_max_irq = ARM_GIC_NR_IRQS;
+
+ cpumask |= cpumask << 8;
+ cpumask |= cpumask << 16;
+ cpumask |= cpumask << 24;
+
+ GIC_DIST_CTRL(dist_base) = 0x0;
+
+ /* Set all global interrupts to be level triggered, active low. */
+ for (i = 32; i < _gic_max_irq; i += 16)
+ GIC_DIST_CONFIG(dist_base, i) = 0x0;
+
+ /* Set all global interrupts to this CPU only. */
+ for (i = 32; i < _gic_max_irq; i += 4)
+ GIC_DIST_TARGET(dist_base, i) = cpumask;
+
+ /* Set priority on all interrupts. */
+ for (i = 0; i < _gic_max_irq; i += 4)
+ GIC_DIST_PRI(dist_base, i) = 0xa0a0a0a0;
+
+ /* Disable all interrupts. */
+ for (i = 0; i < _gic_max_irq; i += 32)
+ GIC_DIST_ENABLE_CLEAR(dist_base, i) = 0xffffffff;
+
+#if 0
+ /* All interrupts defaults to IGROUP1(IRQ). */
+ for (i = 0; i < _gic_max_irq; i += 32)
+ GIC_DIST_IGROUP(dist_base, i) = 0xffffffff;
+#endif
+ for (i = 0; i < _gic_max_irq; i += 32)
+ GIC_DIST_IGROUP(dist_base, i) = 0;
+
+ /* Enable group0 and group1 interrupt forwarding. */
+ GIC_DIST_CTRL(dist_base) = 0x01;
+
+ return 0;
+}
+
+int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base)
+{
+ RT_ASSERT(index < ARM_GIC_MAX_NR);
+
+ _gic_table[index].cpu_hw_base = cpu_base;
+
+ GIC_CPU_PRIMASK(cpu_base) = 0xf0;
+ GIC_CPU_BINPOINT(cpu_base) = 0x7;
+ /* Enable CPU interrupt */
+ GIC_CPU_CTRL(cpu_base) = 0x01;
+
+ return 0;
+}
+
+void arm_gic_set_group(rt_uint32_t index, int vector, int group)
+{
+ /* As for GICv2, there are only group0 and group1. */
+ RT_ASSERT(group <= 1);
+ RT_ASSERT(vector < _gic_max_irq);
+
+ if (group == 0)
+ {
+ GIC_DIST_IGROUP(_gic_table[index].dist_hw_base,
+ vector) &= ~(1 << (vector % 32));
+ }
+ else if (group == 1)
+ {
+ GIC_DIST_IGROUP(_gic_table[index].dist_hw_base,
+ vector) |= (1 << (vector % 32));
+ }
+}
+
+#ifdef RT_USING_SMP
+void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
+ {
+ /* note: ipi_vector maybe different with irq_vector */
+ GIC_DIST_SOFTINT(_gic_table[0].dist_hw_base) = (cpu_mask << 16) | ipi_vector;
+}
+#endif
+
+#ifdef RT_USING_SMP
+void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
+{
+ /* note: ipi_vector maybe different with irq_vector */
+ rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER");
+}
+#endif
diff --git a/libcpu/arm/cortex-a/gic.h b/libcpu/arm/cortex-a/gic.h
new file mode 100644
index 0000000000..a16d0467fb
--- /dev/null
+++ b/libcpu/arm/cortex-a/gic.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2013-07-20 Bernard first version
+ */
+
+#ifndef __GIC_H__
+#define __GIC_H__
+
+#include <rthw.h>
+#include <board.h>
+
+int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start);
+int arm_gic_cpu_init(rt_uint32_t index, rt_uint32_t cpu_base);
+
+void arm_gic_mask(rt_uint32_t index, int irq);
+void arm_gic_umask(rt_uint32_t index, int irq);
+void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask);
+void arm_gic_set_group(rt_uint32_t index, int vector, int group);
+
+int arm_gic_get_active_irq(rt_uint32_t index);
+void arm_gic_ack(rt_uint32_t index, int irq);
+
+void arm_gic_clear_active(rt_uint32_t index, int irq);
+void arm_gic_clear_pending(rt_uint32_t index, int irq);
+
+void arm_gic_dump_type(rt_uint32_t index);
+void arm_gic_dump(rt_uint32_t index);
+
+#endif
+
diff --git a/libcpu/arm/cortex-a/interrupt.c b/libcpu/arm/cortex-a/interrupt.c
index fb6e3ff3e0..b7a70719a9 100644
--- a/libcpu/arm/cortex-a/interrupt.c
+++ b/libcpu/arm/cortex-a/interrupt.c
@@ -6,68 +6,32 @@
* Change Logs:
* Date Author Notes
* 2013-07-06 Bernard first version
- * 2014-04-03 Grissiom port to VMM
+ * 2018-11-22 Jesven add smp support
*/
#include <rthw.h>
#include <rtthread.h>
+#include "interrupt.h"
+#include "gic.h"
-#include <irq_numbers.h>
-#include <interrupt.h>
-
-#include <gic.h>
-#include "cp15.h"
-
-#define MAX_HANDLERS IMX_INTERRUPT_COUNT
-
-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;
+#ifndef RT_USING_SMP
+/* Those varibles will be accessed in ISR, so we need to share them. */
+rt_uint32_t rt_interrupt_from_thread = 0;
+rt_uint32_t rt_interrupt_to_thread = 0;
+rt_uint32_t rt_thread_switch_interrupt_flag = 0;
+#endif
+const unsigned int VECTOR_BASE = 0x00;
extern void rt_cpu_vector_set_base(unsigned int addr);
extern int system_vectors;
-/* keep compatible with platform SDK */
-void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr)
-{
- rt_hw_interrupt_install(irq_id, (rt_isr_handler_t)isr, NULL, "unknown");
-}
-
-void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority)
+void rt_hw_vector_init(void)
{
- gic_set_irq_priority(irq_id, priority);
- gic_set_irq_security(irq_id, false); // set IRQ as non-secure
- gic_set_cpu_target(irq_id, cpu_id, true);
- gic_enable_irq(irq_id, true);
-}
-
-void disable_interrupt(uint32_t irq_id, uint32_t cpu_id)
-{
- gic_enable_irq(irq_id, false);
- gic_set_cpu_target(irq_id, cpu_id, false);
-}
-
-static void rt_hw_vector_init(void)
-{
- int sctrl;
- unsigned int *src = (unsigned int *)&system_vectors;
-
- /* C12-C0 is only active when SCTLR.V = 0 */
- asm volatile ("mrc p15, #0, %0, c1, c0, #0"
- :"=r" (sctrl));
- sctrl &= ~(1 << 13);
- asm volatile ("mcr p15, #0, %0, c1, c0, #0"
- :
- :"r" (sctrl));
-
- asm volatile ("mcr p15, #0, %0, c12, c0, #0"
- :
- :"r" (src));
+ rt_cpu_vector_set_base((unsigned int)&system_vectors);
}
/**
@@ -75,14 +39,24 @@ static void rt_hw_vector_init(void)
*/
void rt_hw_interrupt_init(void)
{
+ rt_uint32_t gic_cpu_base;
+ rt_uint32_t gic_dist_base;
+ rt_uint32_t gic_irq_start;
+
+ /* initialize vector table */
rt_hw_vector_init();
- gic_init();
- /* 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;
+ /* initialize exceptions table */
+ rt_memset(isr_table, 0x00, sizeof(isr_table));
+
+ /* initialize ARM GIC */
+ gic_dist_base = platform_get_gic_dist_base();
+ gic_cpu_base = platform_get_gic_cpu_base();
+
+ gic_irq_start = GIC_IRQ_START;
+
+ arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
+ arm_gic_cpu_init(0, gic_cpu_base);
}
/**
@@ -91,7 +65,7 @@ void rt_hw_interrupt_init(void)
*/
void rt_hw_interrupt_mask(int vector)
{
- disable_interrupt(vector, 0);
+ arm_gic_mask(0, vector);
}
/**
@@ -100,10 +74,27 @@ void rt_hw_interrupt_mask(int vector)
*/
void rt_hw_interrupt_umask(int vector)
{
- enable_interrupt(vector, 0, 0);
+ arm_gic_umask(0, vector);
}
/**
+ * This function returns the active interrupt number.
+ * @param none
+ */
+int rt_hw_interrupt_get_irq(void)
+{
+ return arm_gic_get_active_irq(0) & GIC_ACK_INTID_MASK;
+}
+
+/**
+ * This function acknowledges the interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_ack(int vector)
+{
+ arm_gic_ack(0, 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
@@ -126,23 +117,7 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
isr_table[vector].handler = handler;
isr_table[vector].param = param;
}
- // arm_gic_set_cpu(0, vector, 1 << rt_cpu_get_smp_id());
}
return old_handler;
}
-
-/**
- * Trigger a software IRQ
- *
- * Since we are running in single core, the target CPU are always CPU0.
- */
-void rt_hw_interrupt_trigger(int vector)
-{
- // arm_gic_trigger(0, 1, vector);
-}
-
-void rt_hw_interrupt_clear(int vector)
-{
- gic_write_end_of_irq(vector);
-}
diff --git a/libcpu/arm/cortex-a/interrupt.h b/libcpu/arm/cortex-a/interrupt.h
new file mode 100644
index 0000000000..442187edee
--- /dev/null
+++ b/libcpu/arm/cortex-a/interrupt.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2013-07-06 Bernard first version
+ */
+
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+#include <rthw.h>
+#include <board.h>
+
+#define INT_IRQ 0x00
+#define INT_FIQ 0x01
+
+void rt_hw_vector_init(void);
+
+void rt_hw_interrupt_control(int vector, int priority, int route);
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+
+int rt_hw_interrupt_get_irq(void);
+void rt_hw_interrupt_ack(int vector);
+
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+ void *param, const char *name);
+
+#endif
diff --git a/libcpu/arm/cortex-a/mmu.c b/libcpu/arm/cortex-a/mmu.c
index 58acdd8145..1260f41fe5 100644
--- a/libcpu/arm/cortex-a/mmu.c
+++ b/libcpu/arm/cortex-a/mmu.c
@@ -13,35 +13,7 @@
#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)
+#include "mmu.h"
/* dump 2nd level page table */
void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
@@ -178,18 +150,25 @@ unsigned long rt_hw_set_domain_register(unsigned long domain_val)
return old_domain;
}
+void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size)
+{
+ /* set page table */
+ for(; size > 0; size--)
+ {
+ rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+ mdesc->paddr_start, mdesc->attr);
+ mdesc++;
+ }
+}
+
void rt_hw_mmu_init(void)
{
+ rt_cpu_dcache_clean_flush();
+ rt_cpu_icache_flush();
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);
diff --git a/libcpu/arm/cortex-a/mmu.h b/libcpu/arm/cortex-a/mmu.h
new file mode 100644
index 0000000000..fbce6df935
--- /dev/null
+++ b/libcpu/arm/cortex-a/mmu.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-03-25 quanzhao the first version
+ */
+#ifndef __MMU_H_
+#define __MMU_H_
+
+#include <rtthread.h>
+
+#define DESC_SEC (0x2)
+#define MEMWBWA ((1<<12)|(3<<2)) /* write back, write allocate */
+#define MEMWB (3<<2) /* write back, no write allocate */
+#define MEMWT (2<<2) /* write through, no write allocate */
+#define SHAREDEVICE (1<<2) /* shared device */
+#define STRONGORDER (0<<2) /* strong ordered */
+#define XN (1<<4) /* eXecute Never */
+#define AP_RW (3<<10) /* supervisor=RW, user=RW */
+#define AP_RO (2<<10) /* supervisor=RW, user=RO */
+#define SHARED (1<<16) /* shareable */
+
+#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)
+
+/* device mapping type */
+#define DEVICE_MEM (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN)
+/* normal memory mapping type */
+#define NORMAL_MEM (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC)
+
+struct mem_desc
+{
+ rt_uint32_t vaddr_start;
+ rt_uint32_t vaddr_end;
+ rt_uint32_t paddr_start;
+ rt_uint32_t attr;
+};
+
+
+#endif
diff --git a/libcpu/arm/cortex-a/stack.c b/libcpu/arm/cortex-a/stack.c
index 1d3ebcb9e6..07d795ab5b 100644
--- a/libcpu/arm/cortex-a/stack.c
+++ b/libcpu/arm/cortex-a/stack.c
@@ -50,13 +50,20 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
*(--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;
}
diff --git a/libcpu/arm/cortex-a/start_gcc.S b/libcpu/arm/cortex-a/start_gcc.S
index 2f16d16807..2e99db7218 100644
--- a/libcpu/arm/cortex-a/start_gcc.S
+++ b/libcpu/arm/cortex-a/start_gcc.S
@@ -6,8 +6,11 @@
* Change Logs:
* Date Author Notes
* 2013-07-05 Bernard the first version
+ * 2018-11-22 Jesven in the interrupt context, use rt_scheduler_do_irq_switch checks
+ * and switches to a new thread
*/
+#include "rtconfig.h"
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
@@ -19,12 +22,16 @@
.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
-.equ SVC_Stack_Size, 0x00000100
+#endif
+.equ SVC_Stack_Size, 0x00000400
.equ ABT_Stack_Size, 0x00000000
.equ RT_FIQ_STACK_PGSZ, 0x00000000
-.equ RT_IRQ_STACK_PGSZ, 0x00000100
-.equ USR_Stack_Size, 0x00000100
+.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)
@@ -34,6 +41,7 @@
.globl stack_start
.globl stack_top
+.align 3
stack_start:
.rept ISR_Stack_Size
.byte 0
@@ -44,12 +52,38 @@ stack_top:
/* reset entry */
.globl _reset
_reset:
- bl rt_cpu_mmu_disable
+#ifdef ARCH_ARMV8
+ /* 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 */
+ adr 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:
+#endif
/* set the cpu to SVC32 mode and disable interrupt */
- mrs r0, cpsr
- bic r0, r0, #0x1f
- orr r0, r0, #0x13
- msr cpsr_c, r0
+ cps #Mode_SVC
+
+#ifdef RT_USING_FPU
+ mov r4, #0xfffffff
+ mcr p15, 0, r4, c1, c0, 2
+#endif
+
+ /* disable the data alignment check */
+ mrc p15, 0, r1, c1, c0, 0
+ bic r1, #(1<<1)
+ mcr p15, 0, r1, c1, c0, 0
/* setup stack */
bl stack_setup
@@ -64,6 +98,20 @@ bss_loop:
strlo r0,[r1],#4 /* clear 4 bytes */
blo bss_loop /* loop until done */
+#ifdef RT_USING_SMP
+ mrc p15, 0, r1, c1, c0, 1
+ mov r0, #(1<<6)
+ orr r1, r0
+ mcr p15, 0, r1, c1, c0, 1 //enable smp
+#endif
+
+ /* initialize the mmu table and enable mmu */
+ ldr r0, =platform_mem_desc
+ ldr r1, =platform_mem_desc_size
+ ldr r1, [r1]
+ bl rt_hw_init_mmu_table
+ bl rt_hw_mmu_init
+
/* call C++ constructors of global objects */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
@@ -137,6 +185,57 @@ vector_fiq:
.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, #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
+
+ /* now irq stack is clean */
+ /* r0 is task svc_sp */
+ /* backup r0 -> r8 */
+ 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
@@ -174,6 +273,23 @@ rt_hw_context_switch_interrupt_do:
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
@@ -182,11 +298,31 @@ rt_hw_context_switch_interrupt_do:
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 */
@@ -200,36 +336,107 @@ rt_hw_context_switch_interrupt_do:
.endm
.align 5
- .globl vector_swi
+.weak vector_swi
vector_swi:
push_svc_reg
bl rt_hw_trap_swi
b .
.align 5
- .globl vector_undef
+ .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
+ .globl vector_pabt
vector_pabt:
push_svc_reg
bl rt_hw_trap_pabt
b .
.align 5
- .globl vector_dabt
+ .globl vector_dabt
vector_dabt:
push_svc_reg
bl rt_hw_trap_dabt
b .
.align 5
- .globl vector_resv
+ .globl vector_resv
vector_resv:
push_svc_reg
bl rt_hw_trap_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:
+
+#ifdef RT_USING_FPU
+ mov r4, #0xfffffff
+ mcr p15, 0, r4, c1, c0, 2
+#endif
+
+ mrc p15, 0, r1, c1, c0, 1
+ mov r0, #(1<<6)
+ orr r1, r0
+ mcr p15, 0, r1, c1, c0, 1 //enable smp
+
+ mrc p15, 0, r0, c1, c0, 0
+ 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
+
+ cps #Mode_IRQ
+ ldr sp, =irq_stack_2_limit
+
+ cps #Mode_FIQ
+ ldr sp, =irq_stack_2_limit
+
+ 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:
+
+#ifdef RT_USING_FPU
+und_stack_2:
+ .space (1 << 10)
+und_stack_2_limit:
+#endif
diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c
index f3b2c26e6d..dc232a46ee 100644
--- a/libcpu/arm/cortex-a/trap.c
+++ b/libcpu/arm/cortex-a/trap.c
@@ -13,10 +13,8 @@
#include <board.h>
#include "armv7.h"
+#include "interrupt.h"
-#include "gic.h"
-
-extern struct rt_thread *rt_current_thread;
#ifdef RT_USING_FINSH
extern long list_thread(void);
#endif
@@ -47,6 +45,39 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs)
*/
void rt_hw_trap_undef(struct rt_hw_exp_stack *regs)
{
+#ifdef RT_USING_FPU
+ {
+ uint32_t ins;
+ uint32_t addr;
+
+ if (regs->cpsr & (1 << 5))
+ {
+ /* thumb mode */
+ addr = regs->pc - 2;
+ ins = (uint32_t)*(uint16_t*)addr;
+ if ((ins & (3 << 11)) != 0)
+ {
+ /* 32 bit ins */
+ ins <<= 16;
+ ins += *(uint16_t*)(addr + 2);
+ }
+ }
+ else
+ {
+ addr = regs->pc - 4;
+ ins = *(uint32_t*)addr;
+ }
+ if ((ins & 0xe00) == 0xa00)
+ {
+ /* float ins */
+ uint32_t val = (1U << 30);
+
+ asm volatile ("vmsr fpexc, %0"::"r"(val):"memory");
+ regs->pc = addr;
+ return;
+ }
+ }
+#endif
rt_kprintf("undefined instruction:\n");
rt_hw_show_register(regs);
#ifdef RT_USING_FINSH
@@ -130,48 +161,52 @@ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs)
void rt_hw_trap_irq(void)
{
void *param;
+ int ir;
rt_isr_handler_t isr_func;
extern struct rt_irq_desc isr_table[];
- // vectNum = RESERVED[31:13] | CPUID[12:10] | INTERRUPT_ID[9:0]
- // send ack and get ID source
- uint32_t vectNum = gic_read_irq_ack();
+ ir = rt_hw_interrupt_get_irq();
- // Check that INT_ID isn't 1023 or 1022 (spurious interrupt)
- if (vectNum & 0x0200)
+ if (ir == 1023)
{
- gic_write_end_of_irq(vectNum); // send end of irq
+ /* Spurious interrupt */
+ return;
}
- else
- {
- // copy the local value to the global image of CPUID
- unsigned cpu = (vectNum >> 10) & 0x7;
- unsigned irq = vectNum & 0x1FF;
-
- /* skip warning */
- cpu = cpu;
- // Call the service routine stored in the handlers array. If there isn't
- // one for this IRQ, then call the default handler.
- /* get interrupt service routine */
- isr_func = isr_table[irq].handler;
+ /* get interrupt service routine */
+ isr_func = isr_table[ir].handler;
#ifdef RT_USING_INTERRUPT_INFO
- isr_table[irq].counter++;
+ isr_table[ir].counter++;
#endif
- if (isr_func)
- {
- /* Interrupt for myself. */
- param = isr_table[irq].param;
- /* turn to interrupt service routine */
- isr_func(irq, param);
- }
-
- // Signal the end of the irq.
- gic_write_end_of_irq(vectNum);
+ if (isr_func)
+ {
+ /* Interrupt for myself. */
+ param = isr_table[ir].param;
+ /* turn to interrupt service routine */
+ isr_func(ir, param);
}
+
+ /* end of interrupt */
+ rt_hw_interrupt_ack(ir);
}
void rt_hw_trap_fiq(void)
{
- /* TODO */
+ void *param;
+ int ir;
+ rt_isr_handler_t isr_func;
+ extern struct rt_irq_desc isr_table[];
+
+ ir = rt_hw_interrupt_get_irq();
+
+ /* get interrupt service routine */
+ isr_func = isr_table[ir].handler;
+ param = isr_table[ir].param;
+
+ /* turn to interrupt service routine */
+ isr_func(ir, param);
+
+ /* end of interrupt */
+ rt_hw_interrupt_ack(ir);
}
+
diff --git a/libcpu/arm/cortex-m0/SConscript b/libcpu/arm/cortex-m0/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-m0/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-m0/context_gcc.S b/libcpu/arm/cortex-m0/context_gcc.S
index d9993247e2..a504ee076e 100644
--- a/libcpu/arm/cortex-m0/context_gcc.S
+++ b/libcpu/arm/cortex-m0/context_gcc.S
@@ -22,7 +22,7 @@
.equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
.equ NVIC_SHPR3, 0xE000ED20 /* system priority register (3) */
- .equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
+ .equ NVIC_PENDSV_PRI, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
/*
@@ -159,7 +159,7 @@ rt_hw_context_switch_to:
MOVS R0, #1
STR R0, [R1]
- /* set the PendSV exception priority */
+ /* set the PendSV and SysTick exception priority */
LDR R0, =NVIC_SHPR3
LDR R1, =NVIC_PENDSV_PRI
LDR R2, [R0,#0x00] /* read */
diff --git a/libcpu/arm/cortex-m0/context_iar.S b/libcpu/arm/cortex-m0/context_iar.S
index 67ea808d8c..6f410d1a24 100644
--- a/libcpu/arm/cortex-m0/context_iar.S
+++ b/libcpu/arm/cortex-m0/context_iar.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_iar.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -23,7 +19,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
@@ -167,7 +163,7 @@ rt_hw_context_switch_to:
MOVS r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m0/context_rvds.S b/libcpu/arm/cortex-m0/context_rvds.S
index bf68592e63..072486587c 100644
--- a/libcpu/arm/cortex-m0/context_rvds.S
+++ b/libcpu/arm/cortex-m0/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2009, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -23,7 +19,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
@@ -172,7 +168,7 @@ rt_hw_context_switch_to PROC
MOVS r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SHPR3
LDR r1, =NVIC_PENDSV_PRI
LDR r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m0/cpuport.c b/libcpu/arm/cortex-m0/cpuport.c
index f5ff8ec113..19aec42230 100644
--- a/libcpu/arm/cortex-m0/cpuport.c
+++ b/libcpu/arm/cortex-m0/cpuport.c
@@ -114,3 +114,22 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *contex)
while (1);
}
+
+#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
+#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
+#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
+#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
+
+#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
+#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
+#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
+
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+ SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk);
+}
diff --git a/libcpu/arm/cortex-m23/SConscript b/libcpu/arm/cortex-m23/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-m23/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S
new file mode 100644
index 0000000000..48f90413d9
--- /dev/null
+++ b/libcpu/arm/cortex-m23/context_gcc.S
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-25 Bernard first version
+ * 2012-06-01 aozima set pendsv priority to 0xFF.
+ * 2012-08-17 aozima fixed bug: store r8 - r11.
+ * 2013-02-20 aozima port to gcc.
+ * 2013-06-18 aozima add restore MSP feature.
+ * 2013-11-04 bright fixed hardfault bug for gcc.
+ * 2019-03-31 xuzhuoyi port to Cortex-M23.
+ */
+
+ .cpu cortex-m23
+ .fpu softvfp
+ .syntax unified
+ .thumb
+ .text
+
+ .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */
+ .equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
+ .equ NVIC_SHPR3, 0xE000ED20 /* system priority register (3) */
+ .equ NVIC_PENDSV_PRI, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
+ .equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+ .global rt_hw_interrupt_disable
+ .type rt_hw_interrupt_disable, %function
+rt_hw_interrupt_disable:
+ MRS R0, PRIMASK
+ CPSID I
+ BX LR
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+ .global rt_hw_interrupt_enable
+ .type rt_hw_interrupt_enable, %function
+rt_hw_interrupt_enable:
+ MSR PRIMASK, R0
+ BX LR
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * R0 --> from
+ * R1 --> to
+ */
+ .global rt_hw_context_switch_interrupt
+ .type rt_hw_context_switch_interrupt, %function
+ .global rt_hw_context_switch
+ .type rt_hw_context_switch, %function
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+ /* set rt_thread_switch_interrupt_flag to 1 */
+ LDR R2, =rt_thread_switch_interrupt_flag
+ LDR R3, [R2]
+ CMP R3, #1
+ BEQ _reswitch
+ MOVS R3, #1
+ STR R3, [R2]
+
+ LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
+ STR R0, [R2]
+
+_reswitch:
+ LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
+ STR R1, [R2]
+
+ LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
+ LDR R1, =NVIC_PENDSVSET
+ STR R1, [R0]
+ BX LR
+
+/* R0 --> switch from thread stack
+ * R1 --> switch to thread stack
+ * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
+ */
+ .global PendSV_Handler
+ .type PendSV_Handler, %function
+PendSV_Handler:
+ /* disable interrupt to protect context switch */
+ MRS R2, PRIMASK
+ CPSID I
+
+ /* get rt_thread_switch_interrupt_flag */
+ LDR R0, =rt_thread_switch_interrupt_flag
+ LDR R1, [R0]
+ CMP R1, #0x00
+ BEQ pendsv_exit /* pendsv aLReady handled */
+
+ /* clear rt_thread_switch_interrupt_flag to 0 */
+ MOVS R1, #0
+ STR R1, [R0]
+
+ LDR R0, =rt_interrupt_from_thread
+ LDR R1, [R0]
+ CMP R1, #0x00
+ BEQ switch_to_thread /* skip register save at the first time */
+
+ MRS R1, PSP /* get from thread stack pointer */
+
+ SUBS R1, R1, #0x20 /* space for {R4 - R7} and {R8 - R11} */
+ LDR R0, [R0]
+ STR R1, [R0] /* update from thread stack pointer */
+
+ STMIA R1!, {R4 - R7} /* push thread {R4 - R7} register to thread stack */
+
+ MOV R4, R8 /* mov thread {R8 - R11} to {R4 - R7} */
+ MOV R5, R9
+ MOV R6, R10
+ MOV R7, R11
+ STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */
+switch_to_thread:
+ LDR R1, =rt_interrupt_to_thread
+ LDR R1, [R1]
+ LDR R1, [R1] /* load thread stack pointer */
+
+ LDMIA R1!, {R4 - R7} /* pop thread {R4 - R7} register from thread stack */
+ PUSH {R4 - R7} /* push {R4 - R7} to MSP for copy {R8 - R11} */
+
+ LDMIA R1!, {R4 - R7} /* pop thread {R8 - R11} high register from thread stack to {R4 - R7} */
+ MOV R8, R4 /* mov {R4 - R7} to {R8 - R11} */
+ MOV R9, R5
+ MOV R10, R6
+ MOV R11, R7
+
+ POP {R4 - R7} /* pop {R4 - R7} from MSP */
+
+ MSR PSP, R1 /* update stack pointer */
+
+pendsv_exit:
+ /* restore interrupt */
+ MSR PRIMASK, R2
+
+ MOVS R0, #0x03
+ RSBS R0, R0, #0x00
+ BX R0
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * R0 --> to
+ */
+ .global rt_hw_context_switch_to
+ .type rt_hw_context_switch_to, %function
+rt_hw_context_switch_to:
+ LDR R1, =rt_interrupt_to_thread
+ STR R0, [R1]
+
+ /* set from thread to 0 */
+ LDR R1, =rt_interrupt_from_thread
+ MOVS R0, #0
+ STR R0, [R1]
+
+ /* set interrupt flag to 1 */
+ LDR R1, =rt_thread_switch_interrupt_flag
+ MOVS R0, #1
+ STR R0, [R1]
+
+ /* set the PendSV and SysTick exception priority */
+ LDR R0, =NVIC_SHPR3
+ LDR R1, =NVIC_PENDSV_PRI
+ LDR R2, [R0,#0x00] /* read */
+ ORRS R1, R1, R2 /* modify */
+ STR R1, [R0] /* write-back */
+
+ LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
+ LDR R1, =NVIC_PENDSVSET
+ STR R1, [R0]
+ NOP
+ /* restore MSP */
+ LDR R0, =SCB_VTOR
+ LDR R0, [R0]
+ LDR R0, [R0]
+ NOP
+ MSR MSP, R0
+
+ /* enable interrupts at processor level */
+ CPSIE I
+
+ /* never reach here! */
+
+/* compatible with old version */
+ .global rt_hw_interrupt_thread_switch
+ .type rt_hw_interrupt_thread_switch, %function
+rt_hw_interrupt_thread_switch:
+ BX LR
+ NOP
+
+ .global HardFault_Handler
+ .type HardFault_Handler, %function
+HardFault_Handler:
+ /* get current context */
+ MRS R0, PSP /* get fault thread stack pointer */
+ PUSH {LR}
+ BL rt_hw_hard_fault_exception
+ POP {PC}
+
+
+/*
+ * rt_uint32_t rt_hw_interrupt_check(void);
+ * R0 --> state
+ */
+ .global rt_hw_interrupt_check
+ .type rt_hw_interrupt_check, %function
+rt_hw_interrupt_check:
+ MRS R0, IPSR
+ BX LR
diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S
new file mode 100644
index 0000000000..c7d85cc5e2
--- /dev/null
+++ b/libcpu/arm/cortex-m23/context_iar.S
@@ -0,0 +1,207 @@
+;/*
+; * Copyright (c) 2006-2019, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2010-01-25 Bernard first version
+; * 2012-06-01 aozima set pendsv priority to 0xFF.
+; * 2012-08-17 aozima fixed bug: store r8 - r11.
+; * 2013-06-18 aozima add restore MSP feature.
+; * 2019-03-31 xuzhuoyi port to Cortex-M23.
+; */
+
+;/**
+; * @addtogroup CORTEX-M23
+; */
+;/*@{*/
+
+SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ SECTION .text:CODE(2)
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrupt_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+ EXPORT rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+ EXPORT rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ MSR PRIMASK, r0
+ BX LR
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+ EXPORT rt_hw_context_switch_interrupt
+ EXPORT rt_hw_context_switch
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+ ; set rt_thread_switch_interrupt_flag to 1
+ LDR r2, =rt_thread_switch_interrupt_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOVS r3, #0x1
+ STR r3, [r2]
+
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+
+_reswitch
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ BX LR
+
+; r0 --> switch from thread stack
+; r1 --> switch to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+ EXPORT PendSV_Handler
+PendSV_Handler:
+
+ ; disable interrupt to protect context switch
+ MRS r2, PRIMASK
+ CPSID I
+
+ ; get rt_thread_switch_interrupt_flag
+ LDR r0, =rt_thread_switch_interrupt_flag
+ LDR r1, [r0]
+ CMP r1, #0x00
+ BEQ pendsv_exit ; pendsv already handled
+
+ ; clear rt_thread_switch_interrupt_flag to 0
+ MOVS r1, #0x00
+ STR r1, [r0]
+
+ LDR r0, =rt_interrupt_from_thread
+ LDR r1, [r0]
+ CMP r1, #0x00
+ BEQ switch_to_thread ; skip register save at the first time
+
+ MRS r1, psp ; get from thread stack pointer
+
+ SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+ STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
+
+ MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
+ MOV r5, r9
+ MOV r6, r10
+ MOV r7, r11
+ STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
+
+switch_to_thread
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
+ PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
+
+ LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
+ MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
+ MOV r9, r5
+ MOV r10, r6
+ MOV r11, r7
+
+ POP {r4 - r7} ; pop {r4 - r7} from MSP
+
+ MSR psp, r1 ; update stack pointer
+
+pendsv_exit
+ ; restore interrupt
+ MSR PRIMASK, r2
+
+ MOVS r0, #0x03
+ RSBS r0, r0, #0x00
+ BX r0
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; * this fucntion is used to perform the first thread switch
+; */
+ EXPORT rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ ; set to thread
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOVS r0, #0x0
+ STR r0, [r1]
+
+ ; set interrupt flag to 1
+ LDR r1, =rt_thread_switch_interrupt_flag
+ MOVS r0, #1
+ STR r0, [r1]
+
+ ; set the PendSV and SysTick exception priority
+ LDR r0, =NVIC_SHPR3
+ LDR r1, =NVIC_PENDSV_PRI
+ LDR r2, [r0,#0x00] ; read
+ ORRS r1,r1,r2 ; modify
+ STR r1, [r0] ; write-back
+
+ ; trigger the PendSV exception (causes context switch)
+ LDR r0, =NVIC_INT_CTRL
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ NOP
+
+ ; restore MSP
+ LDR r0, =SCB_VTOR
+ LDR r0, [r0]
+ LDR r0, [r0]
+ NOP
+ MSR msp, r0
+
+ ; enable interrupts at processor level
+ CPSIE I
+
+ ; never reach here!
+
+; compatible with old version
+ EXPORT rt_hw_interrupt_thread_switch
+rt_hw_interrupt_thread_switch:
+ BX lr
+
+ IMPORT rt_hw_hard_fault_exception
+ EXPORT HardFault_Handler
+HardFault_Handler:
+
+ ; get current context
+ MRS r0, psp ; get fault thread stack pointer
+ PUSH {lr}
+ BL rt_hw_hard_fault_exception
+ POP {pc}
+
+ END
diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S
new file mode 100644
index 0000000000..ca381d0f8f
--- /dev/null
+++ b/libcpu/arm/cortex-m23/context_rvds.S
@@ -0,0 +1,216 @@
+;/*
+; * Copyright (c) 2006-2019, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2010-01-25 Bernard first version
+; * 2012-06-01 aozima set pendsv priority to 0xFF.
+; * 2012-08-17 aozima fixed bug: store r8 - r11.
+; * 2013-06-18 aozima add restore MSP feature.
+; * 2019-03-31 xuzhuoyi port to Cortex-M23.
+; */
+
+;/**
+; * @addtogroup CORTEX-M23
+; */
+;/*@{*/
+
+SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrupt_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable PROC
+ EXPORT rt_hw_interrupt_disable
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable PROC
+ EXPORT rt_hw_interrupt_enable
+ MSR PRIMASK, r0
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch_interrupt
+ EXPORT rt_hw_context_switch_interrupt
+rt_hw_context_switch PROC
+ EXPORT rt_hw_context_switch
+
+ ; set rt_thread_switch_interrupt_flag to 1
+ LDR r2, =rt_thread_switch_interrupt_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOVS r3, #0x01
+ STR r3, [r2]
+
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+
+_reswitch
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ BX LR
+ ENDP
+
+; r0 --> switch from thread stack
+; r1 --> switch to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+PendSV_Handler PROC
+ EXPORT PendSV_Handler
+
+ ; disable interrupt to protect context switch
+ MRS r2, PRIMASK
+ CPSID I
+
+ ; get rt_thread_switch_interrupt_flag
+ LDR r0, =rt_thread_switch_interrupt_flag
+ LDR r1, [r0]
+ CMP r1, #0x00
+ BEQ pendsv_exit ; pendsv already handled
+
+ ; clear rt_thread_switch_interrupt_flag to 0
+ MOVS r1, #0x00
+ STR r1, [r0]
+
+ LDR r0, =rt_interrupt_from_thread
+ LDR r1, [r0]
+ CMP r1, #0x00
+ BEQ switch_to_thread ; skip register save at the first time
+
+ MRS r1, psp ; get from thread stack pointer
+
+ SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11}
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+ STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack
+
+ MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7}
+ MOV r5, r9
+ MOV r6, r10
+ MOV r7, r11
+ STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack
+
+switch_to_thread
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack
+ PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11}
+
+ LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7}
+ MOV r8, r4 ; mov {r4 - r7} to {r8 - r11}
+ MOV r9, r5
+ MOV r10, r6
+ MOV r11, r7
+
+ POP {r4 - r7} ; pop {r4 - r7} from MSP
+
+ MSR psp, r1 ; update stack pointer
+
+pendsv_exit
+ ; restore interrupt
+ MSR PRIMASK, r2
+
+ MOVS r0, #0x03
+ RSBS r0, r0, #0x00
+ BX r0
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; * this fucntion is used to perform the first thread switch
+; */
+rt_hw_context_switch_to PROC
+ EXPORT rt_hw_context_switch_to
+ ; set to thread
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOVS r0, #0x0
+ STR r0, [r1]
+
+ ; set interrupt flag to 1
+ LDR r1, =rt_thread_switch_interrupt_flag
+ MOVS r0, #1
+ STR r0, [r1]
+
+ ; set the PendSV and SysTick exception priority
+ LDR r0, =NVIC_SHPR3
+ LDR r1, =NVIC_PENDSV_PRI
+ LDR r2, [r0,#0x00] ; read
+ ORRS r1,r1,r2 ; modify
+ STR r1, [r0] ; write-back
+
+ ; trigger the PendSV exception (causes context switch)
+ LDR r0, =NVIC_INT_CTRL
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ ; restore MSP
+ LDR r0, =SCB_VTOR
+ LDR r0, [r0]
+ LDR r0, [r0]
+ MSR msp, r0
+
+ ; enable interrupts at processor level
+ CPSIE I
+
+ ; never reach here!
+ ENDP
+
+; compatible with old version
+rt_hw_interrupt_thread_switch PROC
+ EXPORT rt_hw_interrupt_thread_switch
+ BX lr
+ ENDP
+
+ IMPORT rt_hw_hard_fault_exception
+
+HardFault_Handler PROC
+ EXPORT HardFault_Handler
+
+ ; get current context
+ MRS r0, psp ; get fault thread stack pointer
+ PUSH {lr}
+ BL rt_hw_hard_fault_exception
+ POP {pc}
+ ENDP
+
+ ALIGN 4
+
+ END
diff --git a/libcpu/arm/cortex-m23/cpuport.c b/libcpu/arm/cortex-m23/cpuport.c
new file mode 100644
index 0000000000..842802c866
--- /dev/null
+++ b/libcpu/arm/cortex-m23/cpuport.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-25 Bernard first version
+ * 2012-05-31 aozima Merge all of the C source code into cpuport.c
+ * 2012-08-17 aozima fixed bug: store r8 - r11.
+ * 2012-12-23 aozima stack addr align to 8byte.
+ * 2019-03-31 xuzhuoyi port to Cortex-M23.
+ */
+
+#include <rtthread.h>
+
+struct exception_stack_frame
+{
+ rt_uint32_t r0;
+ rt_uint32_t r1;
+ rt_uint32_t r2;
+ rt_uint32_t r3;
+ rt_uint32_t r12;
+ rt_uint32_t lr;
+ rt_uint32_t pc;
+ rt_uint32_t psr;
+};
+
+struct stack_frame
+{
+ /* r4 ~ r7 low register */
+ rt_uint32_t r4;
+ rt_uint32_t r5;
+ rt_uint32_t r6;
+ rt_uint32_t r7;
+
+ /* r8 ~ r11 high register */
+ rt_uint32_t r8;
+ rt_uint32_t r9;
+ rt_uint32_t r10;
+ rt_uint32_t r11;
+
+ struct exception_stack_frame exception_stack_frame;
+};
+
+/* flag in interrupt handling */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+/**
+ * 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)
+{
+ struct stack_frame *stack_frame;
+ rt_uint8_t *stk;
+ unsigned long i;
+
+ stk = stack_addr + sizeof(rt_uint32_t);
+ stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
+ stk -= sizeof(struct stack_frame);
+
+ stack_frame = (struct stack_frame *)stk;
+
+ /* init all register */
+ for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
+ {
+ ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
+ }
+
+ stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */
+ stack_frame->exception_stack_frame.r1 = 0; /* r1 */
+ stack_frame->exception_stack_frame.r2 = 0; /* r2 */
+ stack_frame->exception_stack_frame.r3 = 0; /* r3 */
+ stack_frame->exception_stack_frame.r12 = 0; /* r12 */
+ stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */
+ stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
+ stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
+
+ /* return task's current stack address */
+ return stk;
+}
+
+extern long list_thread(void);
+extern rt_thread_t rt_current_thread;
+/**
+ * fault exception handling
+ */
+void rt_hw_hard_fault_exception(struct exception_stack_frame *contex)
+{
+ rt_kprintf("psr: 0x%08x\n", contex->psr);
+ rt_kprintf(" pc: 0x%08x\n", contex->pc);
+ rt_kprintf(" lr: 0x%08x\n", contex->lr);
+ rt_kprintf("r12: 0x%08x\n", contex->r12);
+ rt_kprintf("r03: 0x%08x\n", contex->r3);
+ rt_kprintf("r02: 0x%08x\n", contex->r2);
+ rt_kprintf("r01: 0x%08x\n", contex->r1);
+ rt_kprintf("r00: 0x%08x\n", contex->r0);
+
+ rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+
+ while (1);
+}
+
+#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
+#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
+#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
+#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED00) /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
+
+#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
+#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
+#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
+
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+ SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk);
+}
diff --git a/libcpu/arm/cortex-m3/SConscript b/libcpu/arm/cortex-m3/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-m3/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-m3/context_gcc.S b/libcpu/arm/cortex-m3/context_gcc.S
index d17a8aa12c..2878d20082 100644
--- a/libcpu/arm/cortex-m3/context_gcc.S
+++ b/libcpu/arm/cortex-m3/context_gcc.S
@@ -24,7 +24,7 @@
.equ PENDSVSET_BIT, 0x10000000 /* value to trigger PendSV exception */
.equ SHPR3, 0xE000ED20 /* system priority register (3) */
- .equ PENDSV_PRI_LOWEST, 0x00FF0000 /* PendSV priority value (lowest) */
+ .equ PENDSV_PRI_LOWEST, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
/*
* rt_base_t rt_hw_interrupt_disable();
@@ -140,7 +140,7 @@ rt_hw_context_switch_to:
MOV R0, #1
STR R0, [R1]
- /* set the PendSV exception priority */
+ /* set the PendSV and SysTick exception priority */
LDR R0, =SHPR3
LDR R1, =PENDSV_PRI_LOWEST
LDR.W R2, [R0,#0] /* read */
diff --git a/libcpu/arm/cortex-m3/context_iar.S b/libcpu/arm/cortex-m3/context_iar.S
index 95dee8062d..7c0e69bf59 100644
--- a/libcpu/arm/cortex-m3/context_iar.S
+++ b/libcpu/arm/cortex-m3/context_iar.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_iar.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006 - 2013, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -23,7 +19,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
@@ -143,7 +139,7 @@ rt_hw_context_switch_to:
MOV r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m3/context_rvds.S b/libcpu/arm/cortex-m3/context_rvds.S
index 9a7ff10abe..a661430499 100644
--- a/libcpu/arm/cortex-m3/context_rvds.S
+++ b/libcpu/arm/cortex-m3/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -22,7 +18,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
@@ -149,7 +145,7 @@ rt_hw_context_switch_to PROC
MOV r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m3/cpuport.c b/libcpu/arm/cortex-m3/cpuport.c
index a386747750..d58782e2c5 100644
--- a/libcpu/arm/cortex-m3/cpuport.c
+++ b/libcpu/arm/cortex-m3/cpuport.c
@@ -11,6 +11,7 @@
* 2012-12-23 aozima stack addr align to 8byte.
* 2012-12-29 Bernard Add exception hook.
* 2013-07-09 aozima enhancement hard fault exception handler.
+ * 2019-07-03 yangjie add __rt_ffs() for armclang.
*/
#include <rtthread.h>
@@ -382,6 +383,24 @@ __asm int __rt_ffs(int value)
exit
BX lr
}
+#elif defined(__CLANG_ARM)
+int __rt_ffs(int value)
+{
+ __asm volatile(
+ "CMP r0, #0x00 \n"
+ "BEQ 1f \n"
+
+ "RBIT r0, r0 \n"
+ "CLZ r0, r0 \n"
+ "ADDS r0, r0, #0x01 \n"
+
+ "1: \n"
+
+ : "=r"(value)
+ : "r"(value)
+ );
+ return value;
+}
#elif defined(__IAR_SYSTEMS_ICC__)
int __rt_ffs(int value)
{
diff --git a/libcpu/arm/cortex-m33/SConscript b/libcpu/arm/cortex-m33/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-m33/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-m33/context_gcc.S b/libcpu/arm/cortex-m33/context_gcc.S
new file mode 100644
index 0000000000..27596bf787
--- /dev/null
+++ b/libcpu/arm/cortex-m33/context_gcc.S
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-10-11 Bernard first version
+ * 2012-01-01 aozima support context switch load/store FPU register.
+ * 2013-06-18 aozima add restore MSP feature.
+ * 2013-06-23 aozima support lazy stack optimized.
+ * 2018-07-24 aozima enhancement hard fault exception handler.
+ */
+
+/**
+ * @addtogroup cortex-m4
+ */
+/*@{*/
+
+.cpu cortex-m4
+.syntax unified
+.thumb
+.text
+
+.equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */
+.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
+.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
+.equ NVIC_PENDSV_PRI, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
+.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.global rt_hw_interrupt_disable
+.type rt_hw_interrupt_disable, %function
+rt_hw_interrupt_disable:
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.global rt_hw_interrupt_enable
+.type rt_hw_interrupt_enable, %function
+rt_hw_interrupt_enable:
+ MSR PRIMASK, r0
+ BX LR
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.global rt_hw_context_switch_interrupt
+.type rt_hw_context_switch_interrupt, %function
+.global rt_hw_context_switch
+.type rt_hw_context_switch, %function
+
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+ /* set rt_thread_switch_interrupt_flag to 1 */
+ LDR r2, =rt_thread_switch_interrupt_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1
+ STR r3, [r2]
+
+ LDR r2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */
+ STR r0, [r2]
+
+_reswitch:
+ LDR r2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ BX LR
+
+/* r0 --> switch from thread stack
+ * r1 --> switch to thread stack
+ * psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+ */
+.global PendSV_Handler
+.type PendSV_Handler, %function
+PendSV_Handler:
+ /* disable interrupt to protect context switch */
+ MRS r2, PRIMASK
+ CPSID I
+
+ /* get rt_thread_switch_interrupt_flag */
+ LDR r0, =rt_thread_switch_interrupt_flag /* r0 = &rt_thread_switch_interrupt_flag */
+ LDR r1, [r0] /* r1 = *r1 */
+ CMP r1, #0x00 /* compare r1 == 0x00 */
+ BNE schedule
+ MSR PRIMASK, r2 /* if r1 == 0x00, do msr PRIMASK, r2 */
+ BX lr /* if r1 == 0x00, do bx lr */
+
+schedule:
+ PUSH {r2} /* store interrupt state */
+
+ /* clear rt_thread_switch_interrupt_flag to 0 */
+ MOV r1, #0x00 /* r1 = 0x00 */
+ STR r1, [r0] /* *r0 = r1 */
+
+ /* skip register save at the first time */
+ LDR r0, =rt_interrupt_from_thread /* r0 = &rt_interrupt_from_thread */
+ LDR r1, [r0] /* r1 = *r0 */
+ CBZ r1, switch_to_thread /* if r1 == 0, goto switch_to_thread */
+
+ /* Whether TrustZone thread stack exists */
+ LDR r1, =rt_trustzone_current_context /* r1 = &rt_secure_current_context */
+ LDR r1, [r1] /* r1 = *r1 */
+ CBZ r1, contex_ns_store /* if r1 == 0, goto contex_ns_store */
+
+ /*call TrustZone fun, Save TrustZone stack */
+ STMFD sp!, {r0-r1, lr} /* push register */
+ MOV r0, r1 /* r0 = rt_secure_current_context */
+ BL rt_trustzone_context_store /* call TrustZone store fun */
+ LDMFD sp!, {r0-r1, lr} /* pop register */
+
+ /* check break from TrustZone */
+ MOV r2, lr /* r2 = lr */
+ TST r2, #0x40 /* if EXC_RETURN[6] is 1, TrustZone stack was used */
+ BEQ contex_ns_store /* if r2 & 0x40 == 0, goto contex_ns_store */
+
+ /* push PSPLIM CONTROL PSP LR current_context to stack */
+ MRS r3, psplim /* r3 = psplim */
+ MRS r4, control /* r4 = control */
+ MRS r5, psp /* r5 = psp */
+ STMFD r5!, {r1-r4} /* push to thread stack */
+
+ /* update from thread stack pointer */
+ LDR r0, [r0] /* r0 = rt_thread_switch_interrupt_flag */
+ STR r5, [r0] /* *r0 = r5 */
+ b switch_to_thread /* goto switch_to_thread */
+
+contex_ns_store:
+
+ MRS r1, psp /* get from thread stack pointer */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ TST lr, #0x10 /* if(!EXC_RETURN[4]) */
+ VSTMDBEQ r1!, {d8 - d15} /* push FPU register s16~s31 */
+#endif
+
+ STMFD r1!, {r4 - r11} /* push r4 - r11 register */
+
+ LDR r2, =rt_trustzone_current_context /* r2 = &rt_secure_current_context */
+ LDR r2, [r2] /* r2 = *r2 */
+ MOV r3, lr /* r3 = lr */
+ MRS r4, psplim /* r4 = psplim */
+ MRS r5, control /* r5 = control */
+ STMFD r1!, {r2-r5} /* push to thread stack */
+
+ LDR r0, [r0]
+ STR r1, [r0] /* update from thread stack pointer */
+
+switch_to_thread:
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] /* load thread stack pointer */
+
+ /* update current TrustZone context */
+ LDMFD r1!, {r2-r5} /* pop thread stack */
+ MSR psplim, r4 /* psplim = r4 */
+ MSR control, r5 /* control = r5 */
+ MOV lr, r3 /* lr = r3 */
+ LDR r6, =rt_trustzone_current_context /* r6 = &rt_secure_current_context */
+ STR r2, [r6] /* *r6 = r2 */
+ MOV r0, r2 /* r0 = r2 */
+
+ /* Whether TrustZone thread stack exists */
+ CBZ r0, contex_ns_load /* if r0 == 0, goto contex_ns_load */
+ PUSH {r1, r3} /* push lr, thread_stack */
+ BL rt_trustzone_context_load /* call TrustZone load fun */
+ POP {r1, r3} /* pop lr, thread_stack */
+ MOV lr, r3 /* lr = r1 */
+ TST r3, #0x40 /* if EXC_RETURN[6] is 1, TrustZone stack was used */
+ BEQ contex_ns_load /* if r1 & 0x40 == 0, goto contex_ns_load */
+ B pendsv_exit
+
+contex_ns_load:
+ LDMFD r1!, {r4 - r11} /* pop r4 - r11 register */
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ TST lr, #0x10 /* if(!EXC_RETURN[4]) */
+ VLDMIAEQ r1!, {d8 - d15} /* pop FPU register s16~s31 */
+#endif
+
+pendsv_exit:
+ MSR psp, r1 /* update stack pointer */
+ /* restore interrupt */
+ POP {r2}
+ MSR PRIMASK, r2
+
+ BX lr
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.global rt_hw_context_switch_to
+.type rt_hw_context_switch_to, %function
+rt_hw_context_switch_to:
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+#if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ /* CLEAR CONTROL.FPCA */
+ MRS r2, CONTROL /* read */
+ BIC r2, #0x04 /* modify */
+ MSR CONTROL, r2 /* write-back */
+#endif
+
+ /* set from thread to 0 */
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ /* set interrupt flag to 1 */
+ LDR r1, =rt_thread_switch_interrupt_flag
+ MOV r0, #1
+ STR r0, [r1]
+
+ /* set the PendSV and SysTick exception priority */
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ LDR.W r2, [r0,#0x00] /* read */
+ ORR r1,r1,r2 /* modify */
+ STR r1, [r0] /* write-back */
+
+ LDR r0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ /* restore MSP */
+ LDR r0, =SCB_VTOR
+ LDR r0, [r0]
+ LDR r0, [r0]
+ NOP
+ MSR msp, r0
+
+ /* enable interrupts at processor level */
+ CPSIE F
+ CPSIE I
+
+ /* never reach here! */
+
+/* compatible with old version */
+.global rt_hw_interrupt_thread_switch
+.type rt_hw_interrupt_thread_switch, %function
+rt_hw_interrupt_thread_switch:
+ BX lr
+ NOP
+
+.global HardFault_Handler
+.type HardFault_Handler, %function
+HardFault_Handler:
+ /* get current context */
+ MRS r0, msp /* get fault context from handler. */
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ get_sp_done
+ MRS r0, psp /* get fault context from thread. */
+get_sp_done:
+
+ STMFD r0!, {r4 - r11} /* push r4 - r11 register */
+
+ LDR r2, =rt_trustzone_current_context /* r2 = &rt_secure_current_context */
+ LDR r2, [r2] /* r2 = *r2 */
+ MOV r3, lr /* r3 = lr */
+ MRS r4, psplim /* r4 = psplim */
+ MRS r5, control /* r5 = control */
+ STMFD r0!, {r2-r5} /* push to thread stack */
+
+ STMFD r0!, {lr} /* push exec_return register */
+
+ TST lr, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ update_msp
+ MSR psp, r0 /* update stack pointer to PSP. */
+ B update_done
+update_msp:
+ MSR msp, r0 /* update stack pointer to MSP. */
+update_done:
+
+ PUSH {LR}
+ BL rt_hw_hard_fault_exception
+ POP {LR}
+
+ ORR lr, lr, #0x04
+ BX lr
diff --git a/libcpu/arm/cortex-m33/context_iar.S b/libcpu/arm/cortex-m33/context_iar.S
new file mode 100644
index 0000000000..67cf2727a2
--- /dev/null
+++ b/libcpu/arm/cortex-m33/context_iar.S
@@ -0,0 +1,300 @@
+;/*
+; * Copyright (c) 2006-2018, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-17 Bernard first version
+; * 2009-09-27 Bernard add protect when contex switch occurs
+; * 2012-01-01 aozima support context switch load/store FPU register.
+; * 2013-06-18 aozima add restore MSP feature.
+; * 2013-06-23 aozima support lazy stack optimized.
+; * 2018-07-24 aozima enhancement hard fault exception handler.
+; */
+
+;/**
+; * @addtogroup cortex-m33
+; */
+;/*@{*/
+
+SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ SECTION .text:CODE(2)
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrupt_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_trustzone_current_context
+ IMPORT rt_trustzone_context_load
+ IMPORT rt_trustzone_context_store
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+ EXPORT rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+ EXPORT rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+ MSR PRIMASK, r0
+ BX LR
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+ EXPORT rt_hw_context_switch_interrupt
+ EXPORT rt_hw_context_switch
+rt_hw_context_switch_interrupt:
+rt_hw_context_switch:
+ ; set rt_thread_switch_interrupt_flag to 1
+ LDR r2, =rt_thread_switch_interrupt_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1
+ STR r3, [r2]
+
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+
+_reswitch
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ BX LR
+
+; r0 --> switch from thread stack
+; r1 --> switch to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+ EXPORT PendSV_Handler
+PendSV_Handler:
+
+ ; disable interrupt to protect context switch
+ MRS r2, PRIMASK
+ CPSID I
+
+ ; get rt_thread_switch_interrupt_flag
+ LDR r0, =rt_thread_switch_interrupt_flag ; r0 = &rt_thread_switch_interrupt_flag
+ LDR r1, [r0] ; r1 = *r1
+ CMP r1, #0x00 ; compare r1 == 0x00
+ BNE schedule
+ MSR PRIMASK, r2 ; if r1 == 0x00, do msr PRIMASK, r2
+ BX lr ; if r1 == 0x00, do bx lr
+
+schedule
+ PUSH {r2} ; store interrupt state
+
+ ; clear rt_thread_switch_interrupt_flag to 0
+ MOV r1, #0x00 ; r1 = 0x00
+ STR r1, [r0] ; *r0 = r1
+
+ ; skip register save at the first time
+ LDR r0, =rt_interrupt_from_thread ; r0 = &rt_interrupt_from_thread
+ LDR r1, [r0] ; r1 = *r0
+ CBZ r1, switch_to_thread ; if r1 == 0, goto switch_to_thread
+
+ ; Whether TrustZone thread stack exists
+ LDR r1, =rt_trustzone_current_context ; r1 = &rt_secure_current_context
+ LDR r1, [r1] ; r1 = *r1
+ CBZ r1, contex_ns_store ; if r1 == 0, goto contex_ns_store
+
+ ;call TrustZone fun, Save TrustZone stack
+ STMFD sp!, {r0-r1, lr} ; push register
+ MOV r0, r1 ; r0 = rt_secure_current_context
+ BL rt_trustzone_context_store ; call TrustZone store fun
+ LDMFD sp!, {r0-r1, lr} ; pop register
+
+ ; check break from TrustZone
+ MOV r2, lr ; r2 = lr
+ TST r2, #0x40 ; if EXC_RETURN[6] is 1, TrustZone stack was used
+ BEQ contex_ns_store ; if r2 & 0x40 == 0, goto contex_ns_store
+
+ ; push PSPLIM CONTROL PSP LR current_context to stack
+ MRS r3, psplim ; r3 = psplim
+ MRS r4, control ; r4 = control
+ MRS r5, psp ; r5 = psp
+ STMFD r5!, {r1-r4} ; push to thread stack
+
+ ; update from thread stack pointer
+ LDR r0, [r0] ; r0 = rt_thread_switch_interrupt_flag
+ STR r5, [r0] ; *r0 = r5
+ b switch_to_thread ; goto switch_to_thread
+
+contex_ns_store
+
+ MRS r1, psp ; get from thread stack pointer
+
+#if defined ( __ARMVFP__ )
+ TST lr, #0x10 ; if(!EXC_RETURN[4])
+ BNE skip_push_fpu
+ VSTMDB r1!, {d8 - d15} ; push FPU register s16~s31
+skip_push_fpu
+#endif
+
+ STMFD r1!, {r4 - r11} ; push r4 - r11 register
+
+ LDR r2, =rt_trustzone_current_context ; r2 = &rt_secure_current_context
+ LDR r2, [r2] ; r2 = *r2
+ MOV r3, lr ; r3 = lr
+ MRS r4, psplim ; r4 = psplim
+ MRS r5, control ; r5 = control
+ STMFD r1!, {r2-r5} ; push to thread stack
+
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+switch_to_thread
+
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ ; update current TrustZone context
+ LDMFD r1!, {r2-r5} ; pop thread stack
+ MSR psplim, r4 ; psplim = r4
+ MSR control, r5 ; control = r5
+ MOV lr, r3 ; lr = r3
+ LDR r6, =rt_trustzone_current_context ; r6 = &rt_secure_current_context
+ STR r2, [r6] ; *r6 = r2
+ MOV r0, r2 ; r0 = r2
+
+ ; Whether TrustZone thread stack exists
+ CBZ r0, contex_ns_load ; if r0 == 0, goto contex_ns_load
+ PUSH {r1, r3} ; push lr, thread_stack
+ BL rt_trustzone_context_load ; call TrustZone load fun
+ POP {r1, r3} ; pop lr, thread_stack
+ MOV lr, r3 ; lr = r1
+ TST r3, #0x40 ; if EXC_RETURN[6] is 1, TrustZone stack was used
+ BEQ contex_ns_load ; if r1 & 0x40 == 0, goto contex_ns_load
+ B pendsv_exit
+
+contex_ns_load
+ LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
+
+#if defined ( __ARMVFP__ )
+ TST lr, #0x10 ; if(!EXC_RETURN[4])
+ BNE skip_pop_fpu
+ VLDMIA r1!, {d8 - d15} ; pop FPU register s16~s31
+skip_pop_fpu
+#endif
+
+pendsv_exit
+ MSR psp, r1 ; update stack pointer
+ ; restore interrupt
+ POP {r2}
+ MSR PRIMASK, r2
+
+ BX lr
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+ EXPORT rt_hw_context_switch_to
+rt_hw_context_switch_to:
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+#if defined ( __ARMVFP__ )
+ ; CLEAR CONTROL.FPCA
+ MRS r2, CONTROL ; read
+ BIC r2, r2, #0x04 ; modify
+ MSR CONTROL, r2 ; write-back
+#endif
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ ; set interrupt flag to 1
+ LDR r1, =rt_thread_switch_interrupt_flag
+ MOV r0, #1
+ STR r0, [r1]
+
+ ; set the PendSV and SysTick exception priority
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ LDR.W r2, [r0,#0x00] ; read
+ ORR r1,r1,r2 ; modify
+ STR r1, [r0] ; write-back
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ ; restore MSP
+ LDR r0, =SCB_VTOR
+ LDR r0, [r0]
+ LDR r0, [r0]
+ NOP
+ MSR msp, r0
+
+ ; enable interrupts at processor level
+ CPSIE F
+ CPSIE I
+
+ ; never reach here!
+
+; compatible with old version
+ EXPORT rt_hw_interrupt_thread_switch
+rt_hw_interrupt_thread_switch:
+ BX lr
+
+ IMPORT rt_hw_hard_fault_exception
+ EXPORT HardFault_Handler
+HardFault_Handler:
+
+ ; get current context
+ MRS r0, msp ; get fault context from handler.
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ get_sp_done
+ MRS r0, psp ; get fault context from thread.
+get_sp_done
+
+ STMFD r0!, {r4 - r11} ; push r4 - r11 register
+
+ LDR r2, =rt_trustzone_current_context ; r2 = &rt_secure_current_context
+ LDR r2, [r2] ; r2 = *r2
+ MOV r3, lr ; r3 = lr
+ MRS r4, psplim ; r4 = psplim
+ MRS r5, control ; r5 = control
+ STMFD r0!, {r2-r5} ; push to thread stack
+
+ STMFD r0!, {lr} ; push exec_return register
+
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ update_msp
+ MSR psp, r0 ; update stack pointer to PSP.
+ B update_done
+update_msp
+ MSR msp, r0 ; update stack pointer to MSP.
+update_done
+
+ PUSH {lr}
+ BL rt_hw_hard_fault_exception
+ POP {lr}
+
+ ORR lr, lr, #0x04
+ BX lr
+
+ END
diff --git a/libcpu/arm/cortex-m33/context_rvds.S b/libcpu/arm/cortex-m33/context_rvds.S
new file mode 100644
index 0000000000..dc22ead7c5
--- /dev/null
+++ b/libcpu/arm/cortex-m33/context_rvds.S
@@ -0,0 +1,306 @@
+;/*
+;* Copyright (c) 2006-2018, RT-Thread Development Team
+;*
+;* SPDX-License-Identifier: Apache-2.0
+;*
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-17 Bernard first version.
+; * 2012-01-01 aozima support context switch load/store FPU register.
+; * 2013-06-18 aozima add restore MSP feature.
+; * 2013-06-23 aozima support lazy stack optimized.
+; * 2018-07-24 aozima enhancement hard fault exception handler.
+; */
+
+;/**
+; * @addtogroup cortex-m33
+; */
+;/*@{*/
+
+SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
+NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
+NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
+NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_thread_switch_interrupt_flag
+ IMPORT rt_interrupt_from_thread
+ IMPORT rt_interrupt_to_thread
+ IMPORT rt_trustzone_current_context
+ IMPORT rt_trustzone_context_load
+ IMPORT rt_trustzone_context_store
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+rt_hw_interrupt_disable PROC
+ EXPORT rt_hw_interrupt_disable
+ MRS r0, PRIMASK
+ CPSID I
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+rt_hw_interrupt_enable PROC
+ EXPORT rt_hw_interrupt_enable
+ MSR PRIMASK, r0
+ BX LR
+ ENDP
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+rt_hw_context_switch_interrupt
+ EXPORT rt_hw_context_switch_interrupt
+rt_hw_context_switch PROC
+ EXPORT rt_hw_context_switch
+
+ ; set rt_thread_switch_interrupt_flag to 1
+ LDR r2, =rt_thread_switch_interrupt_flag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1
+ STR r3, [r2]
+
+ LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+
+_reswitch
+ LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+
+ LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+ BX LR
+ ENDP
+
+; r0 --> switch from thread stack
+; r1 --> switch to thread stack
+; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
+PendSV_Handler PROC
+ EXPORT PendSV_Handler
+
+ ; disable interrupt to protect context switch
+ MRS r2, PRIMASK ; R2 = PRIMASK
+ CPSID I ; disable all interrupt
+
+ ; get rt_thread_switch_interrupt_flag
+ LDR r0, =rt_thread_switch_interrupt_flag ; r0 = &rt_thread_switch_interrupt_flag
+ LDR r1, [r0] ; r1 = *r1
+ CMP r1, #0x00 ; compare r1 == 0x00
+ BNE schedule
+ MSR PRIMASK, r2 ; if r1 == 0x00, do msr PRIMASK, r2
+ BX lr ; if r1 == 0x00, do bx lr
+
+schedule
+ PUSH {r2} ; store interrupt state
+
+ ; clear rt_thread_switch_interrupt_flag to 0
+ MOV r1, #0x00 ; r1 = 0x00
+ STR r1, [r0] ; *r0 = r1
+
+ ; skip register save at the first time
+ LDR r0, =rt_interrupt_from_thread ; r0 = &rt_interrupt_from_thread
+ LDR r1, [r0] ; r1 = *r0
+ CBZ r1, switch_to_thread ; if r1 == 0, goto switch_to_thread
+
+ ; Whether TrustZone thread stack exists
+ LDR r1, =rt_trustzone_current_context ; r1 = &rt_secure_current_context
+ LDR r1, [r1] ; r1 = *r1
+ CBZ r1, contex_ns_store ; if r1 == 0, goto contex_ns_store
+
+ ;call TrustZone fun, Save TrustZone stack
+ STMFD sp!, {r0-r1, lr} ; push register
+ MOV r0, r1 ; r0 = rt_secure_current_context
+ BL rt_trustzone_context_store ; call TrustZone store fun
+ LDMFD sp!, {r0-r1, lr} ; pop register
+
+ ; check break from TrustZone
+ MOV r2, lr ; r2 = lr
+ TST r2, #0x40 ; if EXC_RETURN[6] is 1, TrustZone stack was used
+ BEQ contex_ns_store ; if r2 & 0x40 == 0, goto contex_ns_store
+
+ ; push PSPLIM CONTROL PSP LR current_context to stack
+ MRS r3, psplim ; r3 = psplim
+ MRS r4, control ; r4 = control
+ MRS r5, psp ; r5 = psp
+ STMFD r5!, {r1-r4} ; push to thread stack
+
+ ; update from thread stack pointer
+ LDR r0, [r0] ; r0 = rt_thread_switch_interrupt_flag
+ STR r5, [r0] ; *r0 = r5
+ b switch_to_thread ; goto switch_to_thread
+
+contex_ns_store
+
+ MRS r1, psp ; get from thread stack pointer
+
+ IF {FPU} != "SoftVFP"
+ TST lr, #0x10 ; if(!EXC_RETURN[4])
+ VSTMFDEQ r1!, {d8 - d15} ; push FPU register s16~s31
+ ENDIF
+
+ STMFD r1!, {r4 - r11} ; push r4 - r11 register
+
+ LDR r2, =rt_trustzone_current_context ; r2 = &rt_secure_current_context
+ LDR r2, [r2] ; r2 = *r2
+ MOV r3, lr ; r3 = lr
+ MRS r4, psplim ; r4 = psplim
+ MRS r5, control ; r5 = control
+ STMFD r1!, {r2-r5} ; push to thread stack
+
+ LDR r0, [r0]
+ STR r1, [r0] ; update from thread stack pointer
+
+switch_to_thread
+ LDR r1, =rt_interrupt_to_thread
+ LDR r1, [r1]
+ LDR r1, [r1] ; load thread stack pointer
+
+ ; update current TrustZone context
+ LDMFD r1!, {r2-r5} ; pop thread stack
+ MSR psplim, r4 ; psplim = r4
+ MSR control, r5 ; control = r5
+ MOV lr, r3 ; lr = r3
+ LDR r6, =rt_trustzone_current_context ; r6 = &rt_secure_current_context
+ STR r2, [r6] ; *r6 = r2
+ MOV r0, r2 ; r0 = r2
+
+ ; Whether TrustZone thread stack exists
+ CBZ r0, contex_ns_load ; if r0 == 0, goto contex_ns_load
+ PUSH {r1, r3} ; push lr, thread_stack
+ BL rt_trustzone_context_load ; call TrustZone load fun
+ POP {r1, r3} ; pop lr, thread_stack
+ MOV lr, r3 ; lr = r1
+ TST r3, #0x40 ; if EXC_RETURN[6] is 1, TrustZone stack was used
+ BEQ contex_ns_load ; if r1 & 0x40 == 0, goto contex_ns_load
+ B pendsv_exit
+
+contex_ns_load
+ LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
+
+ IF {FPU} != "SoftVFP"
+ TST lr, #0x10 ; if(!EXC_RETURN[4])
+ VLDMFDEQ r1!, {d8 - d15} ; pop FPU register s16~s31
+ ENDIF
+
+pendsv_exit
+ MSR psp, r1 ; update stack pointer
+ ; restore interrupt
+ POP {r2}
+ MSR PRIMASK, r2
+
+ BX lr
+ ENDP
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; * this fucntion is used to perform the first thread switch
+; */
+rt_hw_context_switch_to PROC
+ EXPORT rt_hw_context_switch_to
+ ; set to thread
+ LDR r1, =rt_interrupt_to_thread
+ STR r0, [r1]
+
+ IF {FPU} != "SoftVFP"
+ ; CLEAR CONTROL.FPCA
+ MRS r2, CONTROL ; read
+ BIC r2, #0x04 ; modify
+ MSR CONTROL, r2 ; write-back
+ ENDIF
+
+ ; set from thread to 0
+ LDR r1, =rt_interrupt_from_thread
+ MOV r0, #0x0
+ STR r0, [r1]
+
+ ; set interrupt flag to 1
+ LDR r1, =rt_thread_switch_interrupt_flag
+ MOV r0, #1
+ STR r0, [r1]
+
+ ; set the PendSV and SysTick exception priority
+ LDR r0, =NVIC_SYSPRI2
+ LDR r1, =NVIC_PENDSV_PRI
+ LDR.W r2, [r0,#0x00] ; read
+ ORR r1,r1,r2 ; modify
+ STR r1, [r0] ; write-back
+
+ ; trigger the PendSV exception (causes context switch)
+ LDR r0, =NVIC_INT_CTRL
+ LDR r1, =NVIC_PENDSVSET
+ STR r1, [r0]
+
+ ; restore MSP
+ LDR r0, =SCB_VTOR
+ LDR r0, [r0]
+ LDR r0, [r0]
+ MSR msp, r0
+
+ ; enable interrupts at processor level
+ CPSIE F
+ CPSIE I
+
+ ; never reach here!
+ ENDP
+
+; compatible with old version
+rt_hw_interrupt_thread_switch PROC
+ EXPORT rt_hw_interrupt_thread_switch
+ BX lr
+ ENDP
+
+ IMPORT rt_hw_hard_fault_exception
+ EXPORT HardFault_Handler
+HardFault_Handler PROC
+
+ ; get current context
+ MRS r0, msp ;get fault context from handler
+ TST lr, #0x04 ;if(!EXC_RETURN[2])
+ BEQ get_sp_done
+ MRS r0, psp ;get fault context from thread
+get_sp_done
+
+ STMFD r0!, {r4 - r11} ; push r4 - r11 register
+
+ LDR r2, =rt_trustzone_current_context ; r2 = &rt_secure_current_context
+ LDR r2, [r2] ; r2 = *r2
+ MOV r3, lr ; r3 = lr
+ MRS r4, psplim ; r4 = psplim
+ MRS r5, control ; r5 = control
+ STMFD r0!, {r2-r5} ; push to thread stack
+
+ STMFD r0!, {lr} ; push exec_return register
+
+ TST lr, #0x04 ; if(!EXC_RETURN[2])
+ BEQ update_msp
+ MSR psp, r0 ; update stack pointer to PSP
+ B update_done
+update_msp
+ MSR msp, r0 ; update stack pointer to MSP
+update_done
+
+ PUSH {lr}
+ BL rt_hw_hard_fault_exception
+ POP {lr}
+
+ ORR lr, lr, #0x04
+ BX lr
+ ENDP
+
+ ALIGN 4
+
+ END
diff --git a/libcpu/arm/cortex-m33/cpuport.c b/libcpu/arm/cortex-m33/cpuport.c
new file mode 100644
index 0000000000..a589ba3462
--- /dev/null
+++ b/libcpu/arm/cortex-m33/cpuport.c
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-10-21 Bernard the first version.
+ * 2011-10-27 aozima update for cortex-M4 FPU.
+ * 2011-12-31 aozima fixed stack align issues.
+ * 2012-01-01 aozima support context switch load/store FPU register.
+ * 2012-12-11 lgnq fixed the coding style.
+ * 2012-12-23 aozima stack addr align to 8byte.
+ * 2012-12-29 Bernard Add exception hook.
+ * 2013-06-23 aozima support lazy stack optimized.
+ * 2018-07-24 aozima enhancement hard fault exception handler.
+ * 2019-07-03 yangjie add __rt_ffs() for armclang.
+ */
+
+#include <rtthread.h>
+
+#if /* ARMCC */ ( (defined ( __CC_ARM ) && defined ( __TARGET_FPU_VFP )) \
+ /* Clang */ || (defined ( __CLANG_ARM ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__)) \
+ /* IAR */ || (defined ( __ICCARM__ ) && defined ( __ARMVFP__ )) \
+ /* GNU */ || (defined ( __GNUC__ ) && defined ( __VFP_FP__ ) && !defined(__SOFTFP__)) )
+#define USE_FPU 1
+#else
+#define USE_FPU 0
+#endif
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread;
+rt_uint32_t rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+/* exception hook */
+static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
+
+struct exception_stack_frame
+{
+ rt_uint32_t r0;
+ rt_uint32_t r1;
+ rt_uint32_t r2;
+ rt_uint32_t r3;
+ rt_uint32_t r12;
+ rt_uint32_t lr;
+ rt_uint32_t pc;
+ rt_uint32_t psr;
+};
+
+struct stack_frame
+{
+ rt_uint32_t tz;
+ rt_uint32_t lr;
+ rt_uint32_t psplim;
+ rt_uint32_t control;
+
+ /* r4 ~ r11 register */
+ rt_uint32_t r4;
+ rt_uint32_t r5;
+ rt_uint32_t r6;
+ rt_uint32_t r7;
+ rt_uint32_t r8;
+ rt_uint32_t r9;
+ rt_uint32_t r10;
+ rt_uint32_t r11;
+
+ struct exception_stack_frame exception_stack_frame;
+};
+
+struct exception_stack_frame_fpu
+{
+ rt_uint32_t r0;
+ rt_uint32_t r1;
+ rt_uint32_t r2;
+ rt_uint32_t r3;
+ rt_uint32_t r12;
+ rt_uint32_t lr;
+ rt_uint32_t pc;
+ rt_uint32_t psr;
+
+#if USE_FPU
+ /* FPU register */
+ rt_uint32_t S0;
+ rt_uint32_t S1;
+ rt_uint32_t S2;
+ rt_uint32_t S3;
+ rt_uint32_t S4;
+ rt_uint32_t S5;
+ rt_uint32_t S6;
+ rt_uint32_t S7;
+ rt_uint32_t S8;
+ rt_uint32_t S9;
+ rt_uint32_t S10;
+ rt_uint32_t S11;
+ rt_uint32_t S12;
+ rt_uint32_t S13;
+ rt_uint32_t S14;
+ rt_uint32_t S15;
+ rt_uint32_t FPSCR;
+ rt_uint32_t NO_NAME;
+#endif
+};
+
+struct stack_frame_fpu
+{
+ rt_uint32_t flag;
+
+ /* r4 ~ r11 register */
+ rt_uint32_t r4;
+ rt_uint32_t r5;
+ rt_uint32_t r6;
+ rt_uint32_t r7;
+ rt_uint32_t r8;
+ rt_uint32_t r9;
+ rt_uint32_t r10;
+ rt_uint32_t r11;
+
+#if USE_FPU
+ /* FPU register s16 ~ s31 */
+ rt_uint32_t s16;
+ rt_uint32_t s17;
+ rt_uint32_t s18;
+ rt_uint32_t s19;
+ rt_uint32_t s20;
+ rt_uint32_t s21;
+ rt_uint32_t s22;
+ rt_uint32_t s23;
+ rt_uint32_t s24;
+ rt_uint32_t s25;
+ rt_uint32_t s26;
+ rt_uint32_t s27;
+ rt_uint32_t s28;
+ rt_uint32_t s29;
+ rt_uint32_t s30;
+ rt_uint32_t s31;
+#endif
+
+ struct exception_stack_frame_fpu exception_stack_frame;
+};
+
+rt_uint8_t *rt_hw_stack_init(void *tentry,
+ void *parameter,
+ rt_uint8_t *stack_addr,
+ void *texit)
+{
+ struct stack_frame *stack_frame;
+ rt_uint8_t *stk;
+ unsigned long i;
+
+ stk = stack_addr + sizeof(rt_uint32_t);
+ stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8);
+ stk -= sizeof(struct stack_frame);
+
+ stack_frame = (struct stack_frame *)stk;
+
+ /* init all register */
+ for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++)
+ {
+ ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef;
+ }
+
+ stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */
+ stack_frame->exception_stack_frame.r1 = 0; /* r1 */
+ stack_frame->exception_stack_frame.r2 = 0; /* r2 */
+ stack_frame->exception_stack_frame.r3 = 0; /* r3 */
+ stack_frame->exception_stack_frame.r12 = 0; /* r12 */
+ stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */
+ stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */
+ stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */
+
+ stack_frame->tz = 0x00;
+ stack_frame->lr = 0xFFFFFFBC;
+ stack_frame->psplim = 0x00;
+ stack_frame->control = 0x00;
+
+ /* return task's current stack address */
+ return stk;
+}
+
+/**
+ * This function set the hook, which is invoked on fault exception handling.
+ *
+ * @param exception_handle the exception handling hook function.
+ */
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
+{
+ rt_exception_hook = exception_handle;
+}
+
+#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */
+#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */
+#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */
+#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */
+#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED0C) /* Reset control Address Register */
+#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */
+
+#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */
+#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */
+#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */
+
+#ifdef RT_USING_FINSH
+static void usage_fault_track(void)
+{
+ rt_kprintf("usage fault:\n");
+ rt_kprintf("SCB_CFSR_UFSR:0x%02X ", SCB_CFSR_UFSR);
+
+ if(SCB_CFSR_UFSR & (1<<0))
+ {
+ /* [0]:UNDEFINSTR */
+ rt_kprintf("UNDEFINSTR ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<1))
+ {
+ /* [1]:INVSTATE */
+ rt_kprintf("INVSTATE ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<2))
+ {
+ /* [2]:INVPC */
+ rt_kprintf("INVPC ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<3))
+ {
+ /* [3]:NOCP */
+ rt_kprintf("NOCP ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<8))
+ {
+ /* [8]:UNALIGNED */
+ rt_kprintf("UNALIGNED ");
+ }
+
+ if(SCB_CFSR_UFSR & (1<<9))
+ {
+ /* [9]:DIVBYZERO */
+ rt_kprintf("DIVBYZERO ");
+ }
+
+ rt_kprintf("\n");
+}
+
+static void bus_fault_track(void)
+{
+ rt_kprintf("bus fault:\n");
+ rt_kprintf("SCB_CFSR_BFSR:0x%02X ", SCB_CFSR_BFSR);
+
+ if(SCB_CFSR_BFSR & (1<<0))
+ {
+ /* [0]:IBUSERR */
+ rt_kprintf("IBUSERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<1))
+ {
+ /* [1]:PRECISERR */
+ rt_kprintf("PRECISERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<2))
+ {
+ /* [2]:IMPRECISERR */
+ rt_kprintf("IMPRECISERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<3))
+ {
+ /* [3]:UNSTKERR */
+ rt_kprintf("UNSTKERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<4))
+ {
+ /* [4]:STKERR */
+ rt_kprintf("STKERR ");
+ }
+
+ if(SCB_CFSR_BFSR & (1<<7))
+ {
+ rt_kprintf("SCB->BFAR:%08X\n", SCB_BFAR);
+ }
+ else
+ {
+ rt_kprintf("\n");
+ }
+}
+
+static void mem_manage_fault_track(void)
+{
+ rt_kprintf("mem manage fault:\n");
+ rt_kprintf("SCB_CFSR_MFSR:0x%02X ", SCB_CFSR_MFSR);
+
+ if(SCB_CFSR_MFSR & (1<<0))
+ {
+ /* [0]:IACCVIOL */
+ rt_kprintf("IACCVIOL ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<1))
+ {
+ /* [1]:DACCVIOL */
+ rt_kprintf("DACCVIOL ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<3))
+ {
+ /* [3]:MUNSTKERR */
+ rt_kprintf("MUNSTKERR ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<4))
+ {
+ /* [4]:MSTKERR */
+ rt_kprintf("MSTKERR ");
+ }
+
+ if(SCB_CFSR_MFSR & (1<<7))
+ {
+ /* [7]:MMARVALID */
+ rt_kprintf("SCB->MMAR:%08X\n", SCB_MMAR);
+ }
+ else
+ {
+ rt_kprintf("\n");
+ }
+}
+
+static void hard_fault_track(void)
+{
+ if(SCB_HFSR & (1UL<<1))
+ {
+ /* [1]:VECTBL, Indicates hard fault is caused by failed vector fetch. */
+ rt_kprintf("failed vector fetch\n");
+ }
+
+ if(SCB_HFSR & (1UL<<30))
+ {
+ /* [30]:FORCED, Indicates hard fault is taken because of bus fault,
+ memory management fault, or usage fault. */
+ if(SCB_CFSR_BFSR)
+ {
+ bus_fault_track();
+ }
+
+ if(SCB_CFSR_MFSR)
+ {
+ mem_manage_fault_track();
+ }
+
+ if(SCB_CFSR_UFSR)
+ {
+ usage_fault_track();
+ }
+ }
+
+ if(SCB_HFSR & (1UL<<31))
+ {
+ /* [31]:DEBUGEVT, Indicates hard fault is triggered by debug event. */
+ rt_kprintf("debug event\n");
+ }
+}
+#endif /* RT_USING_FINSH */
+
+struct exception_info
+{
+ rt_uint32_t exc_return;
+ struct stack_frame stack_frame;
+};
+
+void rt_hw_hard_fault_exception(struct exception_info *exception_info)
+{
+ extern long list_thread(void);
+ struct exception_stack_frame *exception_stack = &exception_info->stack_frame.exception_stack_frame;
+ struct stack_frame *context = &exception_info->stack_frame;
+
+ if (rt_exception_hook != RT_NULL)
+ {
+ rt_err_t result;
+
+ result = rt_exception_hook(exception_stack);
+ if (result == RT_EOK) return;
+ }
+
+ rt_kprintf("psr: 0x%08x\n", context->exception_stack_frame.psr);
+
+ rt_kprintf("r00: 0x%08x\n", context->exception_stack_frame.r0);
+ rt_kprintf("r01: 0x%08x\n", context->exception_stack_frame.r1);
+ rt_kprintf("r02: 0x%08x\n", context->exception_stack_frame.r2);
+ rt_kprintf("r03: 0x%08x\n", context->exception_stack_frame.r3);
+ rt_kprintf("r04: 0x%08x\n", context->r4);
+ rt_kprintf("r05: 0x%08x\n", context->r5);
+ rt_kprintf("r06: 0x%08x\n", context->r6);
+ rt_kprintf("r07: 0x%08x\n", context->r7);
+ rt_kprintf("r08: 0x%08x\n", context->r8);
+ rt_kprintf("r09: 0x%08x\n", context->r9);
+ rt_kprintf("r10: 0x%08x\n", context->r10);
+ rt_kprintf("r11: 0x%08x\n", context->r11);
+ rt_kprintf("r12: 0x%08x\n", context->exception_stack_frame.r12);
+ rt_kprintf(" lr: 0x%08x\n", context->exception_stack_frame.lr);
+ rt_kprintf(" pc: 0x%08x\n", context->exception_stack_frame.pc);
+
+ if (exception_info->exc_return & (1 << 2))
+ {
+ rt_kprintf("hard fault on thread: %s\r\n\r\n", rt_thread_self()->name);
+
+#ifdef RT_USING_FINSH
+ list_thread();
+#endif
+ }
+ else
+ {
+ rt_kprintf("hard fault on handler\r\n\r\n");
+ }
+
+ if ( (exception_info->exc_return & 0x10) == 0)
+ {
+ rt_kprintf("FPU active!\r\n");
+ }
+
+#ifdef RT_USING_FINSH
+ hard_fault_track();
+#endif /* RT_USING_FINSH */
+
+ while (1);
+}
+
+/**
+ * shutdown CPU
+ */
+void rt_hw_cpu_shutdown(void)
+{
+ rt_kprintf("shutdown...\n");
+
+ RT_ASSERT(0);
+}
+
+/**
+ * reset CPU
+ */
+RT_WEAK void rt_hw_cpu_reset(void)
+{
+ SCB_AIRCR = SCB_RESET_VALUE;
+}
+
+#ifdef RT_USING_CPU_FFS
+/**
+ * This function finds the first bit set (beginning with the least significant bit)
+ * in value and return the index of that bit.
+ *
+ * Bits are numbered starting at 1 (the least significant bit). A return value of
+ * zero from any of these functions means that the argument was zero.
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
+ * shall return 0.
+ */
+#if defined(__CC_ARM)
+__asm int __rt_ffs(int value)
+{
+ CMP r0, #0x00
+ BEQ exit
+
+ RBIT r0, r0
+ CLZ r0, r0
+ ADDS r0, r0, #0x01
+
+exit
+ BX lr
+}
+#elif defined(__CLANG_ARM)
+int __rt_ffs(int value)
+{
+ __asm volatile(
+ "CMP r0, #0x00 \n"
+ "BEQ 1f \n"
+
+ "RBIT r0, r0 \n"
+ "CLZ r0, r0 \n"
+ "ADDS r0, r0, #0x01 \n"
+
+ "1: \n"
+ "BX lr \n"
+
+ : "=r"(value)
+ : "r"(value)
+ );
+ return value;
+}
+#elif defined(__IAR_SYSTEMS_ICC__)
+int __rt_ffs(int value)
+{
+ if (value == 0) return value;
+
+ asm("RBIT %0, %1" : "=r"(value) : "r"(value));
+ asm("CLZ %0, %1" : "=r"(value) : "r"(value));
+ asm("ADDS %0, %1, #0x01" : "=r"(value) : "r"(value));
+
+ return value;
+}
+#elif defined(__GNUC__)
+int __rt_ffs(int value)
+{
+ return __builtin_ffs(value);
+}
+#endif
+
+#endif
diff --git a/libcpu/arm/cortex-m33/syscall_gcc.S b/libcpu/arm/cortex-m33/syscall_gcc.S
new file mode 100644
index 0000000000..d7d16fb8a0
--- /dev/null
+++ b/libcpu/arm/cortex-m33/syscall_gcc.S
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-10-25 tyx first version
+ */
+
+.cpu cortex-m4
+.syntax unified
+.thumb
+.text
+
+/*
+ * int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2);
+ */
+.global tzcall
+.type tzcall, %function
+tzcall:
+ SVC 1 /* call SVC 1 */
+ BX LR
+
+tzcall_entry:
+ PUSH {R1, R4, LR}
+ MOV R4, R1 /* copy thread SP to R4 */
+ LDMFD R4!, {r0 - r3} /* pop user stack, get input arg0, arg1, arg2 */
+ STMFD R4!, {r0 - r3} /* push stack, user stack recovery */
+ BL rt_secure_svc_handle /* call fun */
+ POP {R1, R4, LR}
+ STR R0, [R1] /* update return value */
+ BX LR /* return to thread */
+
+syscall_entry:
+ BX LR /* return to user app */
+
+.global SVC_Handler
+.type SVC_Handler, %function
+SVC_Handler:
+
+ /* get SP, save to R1 */
+ MRS R1, MSP /* get fault context from handler. */
+ TST LR, #0x04 /* if(!EXC_RETURN[2]) */
+ BEQ get_sp_done
+ MRS R1, PSP /* get fault context from thread. */
+get_sp_done:
+
+ /* get svc index */
+ LDR R0, [R1, #24]
+ LDRB R0, [R0, #-2]
+
+ /* if svc == 0, do system call */
+ CMP R0, #0x0
+ BEQ syscall_entry
+
+ /* if svc == 1, do TrustZone call */
+ CMP R0, #0x1
+ BEQ tzcall_entry
diff --git a/libcpu/arm/cortex-m33/syscall_iar.S b/libcpu/arm/cortex-m33/syscall_iar.S
new file mode 100644
index 0000000000..aa30ead9e3
--- /dev/null
+++ b/libcpu/arm/cortex-m33/syscall_iar.S
@@ -0,0 +1,63 @@
+;/*
+; * Copyright (c) 2006-2018, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2019-10-25 tyx first version
+; */
+
+;/*
+; * @addtogroup cortex-m33
+; */
+
+ SECTION .text:CODE(2)
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+;/*
+; * int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2);
+; */
+.global tzcall
+.type tzcall, %function
+tzcall:
+ SVC 1 ;/* call SVC 1 */
+ BX LR
+
+tzcall_entry:
+ PUSH {R1, R4, LR}
+ MOV R4, R1 ;/* copy thread SP to R4 */
+ LDMFD R4!, {r0 - r3} ;/* pop user stack, get input arg0, arg1, arg2 */
+ STMFD R4!, {r0 - r3} ;/* push stack, user stack recovery */
+ BL rt_secure_svc_handle ;/* call fun */
+ POP {R1, R4, LR}
+ STR R0, [R1] ;/* update return value */
+ BX LR ;/* return to thread */
+
+syscall_entry:
+ BX LR ;/* return to user app */
+
+.global SVC_Handler
+.type SVC_Handler, %function
+SVC_Handler:
+
+ ;/* get SP, save to R1 */
+ MRS R1, MSP ;/* get fault context from handler. */
+ TST LR, #0x04 ;/* if(!EXC_RETURN[2]) */
+ BEQ get_sp_done
+ MRS R1, PSP ;/* get fault context from thread. */
+get_sp_done:
+
+ ;/* get svc index */
+ LDR R0, [R1, #24]
+ LDRB R0, [R0, #-2]
+
+ ;/* if svc == 0, do system call */
+ CMP R0, #0x0
+ BEQ syscall_entry
+
+ ;/* if svc == 1, do TrustZone call */
+ CMP R0, #0x1
+ BEQ tzcall_entry
diff --git a/libcpu/arm/cortex-m33/syscall_rvds.S b/libcpu/arm/cortex-m33/syscall_rvds.S
new file mode 100644
index 0000000000..95ee247ee5
--- /dev/null
+++ b/libcpu/arm/cortex-m33/syscall_rvds.S
@@ -0,0 +1,74 @@
+;/*
+; * Copyright (c) 2006-2018, RT-Thread Development Team
+; *
+; * SPDX-License-Identifier: Apache-2.0
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2019-10-25 tyx first version
+; */
+
+ AREA |.text|, CODE, READONLY, ALIGN=2
+ THUMB
+ REQUIRE8
+ PRESERVE8
+
+ IMPORT rt_secure_svc_handle
+
+;/*
+; * int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2);
+; */
+tzcall PROC
+ EXPORT tzcall
+ SVC 1 ;call SVC 1
+ BX LR
+
+ ENDP
+
+tzcall_entry PROC
+ PUSH {R1, R4, LR}
+ MOV R4, R1 ; copy thread SP to R4
+ LDMFD R4!, {r0 - r3} ; pop user stack, get input arg0, arg1, arg2
+ STMFD R4!, {r0 - r3} ; push stack, user stack recovery
+ BL rt_secure_svc_handle ; call fun
+ POP {R1, R4, LR}
+ STR R0, [R1] ; update return value
+ BX LR ; return to thread
+
+ ENDP
+
+syscall_entry PROC
+ BX LR ; return to user app
+
+ ENDP
+
+;/*
+; * void SVC_Handler(void);
+; */
+SVC_Handler PROC
+ EXPORT SVC_Handler
+
+ ; get SP, save to R1
+ MRS R1, MSP ;get fault context from handler
+ TST LR, #0x04 ;if(!EXC_RETURN[2])
+ BEQ get_sp_done
+ MRS R1, PSP ;get fault context from thread
+get_sp_done
+
+ ; get svc index
+ LDR R0, [R1, #24]
+ LDRB R0, [R0, #-2]
+
+ ;if svc == 0, do system call
+ CMP R0, #0x0
+ BEQ syscall_entry
+
+ ;if svc == 1, do TrustZone call
+ CMP R0, #0x1
+ BEQ tzcall_entry
+
+ ENDP
+
+ ALIGN
+
+ END \ No newline at end of file
diff --git a/libcpu/arm/cortex-m33/trustzone.c b/libcpu/arm/cortex-m33/trustzone.c
new file mode 100644
index 0000000000..86654a7199
--- /dev/null
+++ b/libcpu/arm/cortex-m33/trustzone.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-10-28 tyx the first version.
+ */
+
+#include <rtthread.h>
+
+extern void TZ_InitContextSystem_S(void);
+extern rt_uint32_t TZ_AllocModuleContext_S (rt_uint32_t module);
+extern rt_uint32_t TZ_FreeModuleContext_S(rt_uint32_t id);
+extern rt_uint32_t TZ_LoadContext_S(rt_uint32_t id);
+extern rt_uint32_t TZ_StoreContext_S(rt_uint32_t id);
+extern int tzcall(int id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2);
+
+#define TZ_INIT_CONTEXT_ID (0x1001)
+#define TZ_ALLOC_CONTEXT_ID (0x1002)
+#define TZ_FREE_CONTEXT_ID (0x1003)
+
+rt_ubase_t rt_trustzone_current_context;
+
+#if defined(__CC_ARM)
+static __inline rt_uint32_t __get_IPSR(void)
+{
+ register rt_uint32_t result __asm("ipsr");
+ return(result);
+}
+#elif defined(__CLANG_ARM)
+__attribute__((always_inline)) static __inline rt_uint32_t __get_IPSR(void)
+{
+ rt_uint32_t result;
+
+ __asm volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+#elif defined(__IAR_SYSTEMS_ICC__)
+_Pragma("inline=forced") static inline int __get_IPSR(int value)
+{
+ rt_uint32_t result;
+
+ asm("MRS %0, ipsr" : "=r"(result));
+ return result;
+}
+#elif defined(__GNUC__)
+__attribute__((always_inline)) static inline rt_uint32_t __get_IPSR(void)
+{
+ rt_uint32_t result;
+
+ __asm volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+#endif
+
+void rt_trustzone_init(void)
+{
+ static rt_uint8_t _init;
+
+ if (_init)
+ return;
+ tzcall(TZ_INIT_CONTEXT_ID, 0, 0, 0);
+ _init = 1;
+}
+
+rt_err_t rt_trustzone_enter(rt_ubase_t module)
+{
+ rt_trustzone_init();
+ if (tzcall(TZ_ALLOC_CONTEXT_ID, module, 0, 0))
+ {
+ return RT_EOK;
+ }
+ return -RT_ERROR;
+}
+
+rt_err_t rt_trustzone_exit(void)
+{
+ tzcall(TZ_FREE_CONTEXT_ID, 0, 0, 0);
+ return RT_EOK;
+}
+
+void rt_trustzone_context_store(rt_ubase_t context)
+{
+ TZ_StoreContext_S(context);
+}
+
+void rt_trustzone_context_load(rt_ubase_t context)
+{
+ TZ_LoadContext_S(context);
+}
+
+int rt_secure_svc_handle(int svc_id, rt_ubase_t arg0, rt_ubase_t arg1, rt_ubase_t arg2)
+{
+ rt_ubase_t tmp;
+ int res = 0;
+
+ switch (svc_id)
+ {
+ case TZ_INIT_CONTEXT_ID:
+ TZ_InitContextSystem_S();
+ break;
+ case TZ_ALLOC_CONTEXT_ID:
+ res = TZ_AllocModuleContext_S(arg0);
+ if (res <= 0)
+ {
+ rt_kprintf("Alloc Context Failed\n");
+ }
+ else
+ {
+ rt_trustzone_current_context = res;
+ TZ_LoadContext_S(res);
+ }
+ break;
+ case TZ_FREE_CONTEXT_ID:
+ TZ_FreeModuleContext_S(rt_trustzone_current_context);
+ rt_trustzone_current_context = 0;
+ break;
+ }
+ return res;
+}
+
diff --git a/libcpu/arm/cortex-m4/SConscript b/libcpu/arm/cortex-m4/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-m4/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-m4/context_gcc.S b/libcpu/arm/cortex-m4/context_gcc.S
index 420f4f8ae3..f569a35863 100644
--- a/libcpu/arm/cortex-m4/context_gcc.S
+++ b/libcpu/arm/cortex-m4/context_gcc.S
@@ -25,7 +25,7 @@
.equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
-.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
+.equ NVIC_PENDSV_PRI, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
/*
@@ -182,7 +182,7 @@ rt_hw_context_switch_to:
MOV r0, #1
STR r0, [r1]
- /* set the PendSV exception priority */
+ /* set the PendSV and SysTick exception priority */
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] /* read */
diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S
index bf707d0d53..18d6a3f784 100644
--- a/libcpu/arm/cortex-m4/context_iar.S
+++ b/libcpu/arm/cortex-m4/context_iar.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_iar.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -25,7 +21,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
@@ -190,7 +186,7 @@ rt_hw_context_switch_to:
MOV r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m4/context_rvds.S b/libcpu/arm/cortex-m4/context_rvds.S
index f6d2447c5e..3f948bc349 100644
--- a/libcpu/arm/cortex-m4/context_rvds.S
+++ b/libcpu/arm/cortex-m4/context_rvds.S
@@ -20,7 +20,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
@@ -186,7 +186,7 @@ rt_hw_context_switch_to PROC
MOV r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c
index 18f027895b..dc8a9aab59 100644
--- a/libcpu/arm/cortex-m4/cpuport.c
+++ b/libcpu/arm/cortex-m4/cpuport.c
@@ -14,6 +14,7 @@
* 2012-12-29 Bernard Add exception hook.
* 2013-06-23 aozima support lazy stack optimized.
* 2018-07-24 aozima enhancement hard fault exception handler.
+ * 2019-07-03 yangjie add __rt_ffs() for armclang.
*/
#include <rtthread.h>
@@ -453,7 +454,7 @@ RT_WEAK void rt_hw_cpu_reset(void)
* @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
-#if defined(__CC_ARM) || defined(__CLANG_ARM)
+#if defined(__CC_ARM)
__asm int __rt_ffs(int value)
{
CMP r0, #0x00
@@ -466,6 +467,24 @@ __asm int __rt_ffs(int value)
exit
BX lr
}
+#elif defined(__CLANG_ARM)
+int __rt_ffs(int value)
+{
+ __asm volatile(
+ "CMP r0, #0x00 \n"
+ "BEQ 1f \n"
+
+ "RBIT r0, r0 \n"
+ "CLZ r0, r0 \n"
+ "ADDS r0, r0, #0x01 \n"
+
+ "1: \n"
+
+ : "=r"(value)
+ : "r"(value)
+ );
+ return value;
+}
#elif defined(__IAR_SYSTEMS_ICC__)
int __rt_ffs(int value)
{
diff --git a/libcpu/arm/cortex-m7/SConscript b/libcpu/arm/cortex-m7/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-m7/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-m7/context_gcc.S b/libcpu/arm/cortex-m7/context_gcc.S
index 420f4f8ae3..f569a35863 100644
--- a/libcpu/arm/cortex-m7/context_gcc.S
+++ b/libcpu/arm/cortex-m7/context_gcc.S
@@ -25,7 +25,7 @@
.equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */
.equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */
.equ NVIC_SYSPRI2, 0xE000ED20 /* system priority register (2) */
-.equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */
+.equ NVIC_PENDSV_PRI, 0xFFFF0000 /* PendSV and SysTick priority value (lowest) */
.equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */
/*
@@ -182,7 +182,7 @@ rt_hw_context_switch_to:
MOV r0, #1
STR r0, [r1]
- /* set the PendSV exception priority */
+ /* set the PendSV and SysTick exception priority */
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] /* read */
diff --git a/libcpu/arm/cortex-m7/context_iar.S b/libcpu/arm/cortex-m7/context_iar.S
index bf707d0d53..18d6a3f784 100644
--- a/libcpu/arm/cortex-m7/context_iar.S
+++ b/libcpu/arm/cortex-m7/context_iar.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_iar.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -25,7 +21,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
SECTION .text:CODE(2)
@@ -190,7 +186,7 @@ rt_hw_context_switch_to:
MOV r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m7/context_rvds.S b/libcpu/arm/cortex-m7/context_rvds.S
index 1abe477eab..d051f819c1 100644
--- a/libcpu/arm/cortex-m7/context_rvds.S
+++ b/libcpu/arm/cortex-m7/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
@@ -24,7 +20,7 @@
SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
-NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
+NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV and SysTick priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
@@ -190,7 +186,7 @@ rt_hw_context_switch_to PROC
MOV r0, #1
STR r0, [r1]
- ; set the PendSV exception priority
+ ; set the PendSV and SysTick exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
diff --git a/libcpu/arm/cortex-m7/cpu_cache.c b/libcpu/arm/cortex-m7/cpu_cache.c
new file mode 100644
index 0000000000..350b819c00
--- /dev/null
+++ b/libcpu/arm/cortex-m7/cpu_cache.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-04-02 tanek first implementation
+ * 2019-04-27 misonyo update to cortex-m7 series
+ */
+
+#include <rthw.h>
+#include <rtdef.h>
+#include <board.h>
+
+/* The L1-caches on all Cortex®-M7s are divided into lines of 32 bytes. */
+#define L1CACHE_LINESIZE_BYTE (32)
+
+void rt_hw_cpu_icache_enable(void)
+{
+ SCB_EnableICache();
+}
+
+void rt_hw_cpu_icache_disable(void)
+{
+ SCB_DisableICache();
+}
+
+rt_base_t rt_hw_cpu_icache_status(void)
+{
+ return 0;
+}
+
+void rt_hw_cpu_icache_ops(int ops, void* addr, int size)
+{
+ rt_uint32_t address = (rt_uint32_t)addr & (rt_uint32_t) ~(L1CACHE_LINESIZE_BYTE - 1);
+ rt_int32_t size_byte = size + address - (rt_uint32_t)addr;
+ rt_uint32_t linesize = 32U;
+ if (ops & RT_HW_CACHE_INVALIDATE)
+ {
+ __DSB();
+ while (size_byte > 0)
+ {
+ SCB->ICIMVAU = address;
+ address += linesize;
+ size_byte -= linesize;
+ }
+ __DSB();
+ __ISB();
+ }
+}
+
+void rt_hw_cpu_dcache_enable(void)
+{
+ SCB_EnableDCache();
+}
+
+void rt_hw_cpu_dcache_disable(void)
+{
+ SCB_DisableDCache();
+}
+
+rt_base_t rt_hw_cpu_dcache_status(void)
+{
+ return 0;
+}
+
+void rt_hw_cpu_dcache_ops(int ops, void* addr, int size)
+{
+ rt_uint32_t startAddr = (rt_uint32_t)addr & (rt_uint32_t)~(L1CACHE_LINESIZE_BYTE - 1);
+ rt_uint32_t size_byte = size + (rt_uint32_t)addr - startAddr;
+
+ if (ops & (RT_HW_CACHE_FLUSH | RT_HW_CACHE_INVALIDATE))
+ {
+ SCB_CleanInvalidateDCache_by_Addr((uint32_t *)startAddr, size_byte);
+ }
+ else if (ops & RT_HW_CACHE_FLUSH)
+ {
+ SCB_CleanDCache_by_Addr((uint32_t *)startAddr, size_byte);
+ }
+ else if (ops & RT_HW_CACHE_INVALIDATE)
+ {
+ SCB_InvalidateDCache_by_Addr((uint32_t *)startAddr, size_byte);
+ }
+ else
+ {
+ RT_ASSERT(0);
+ }
+}
diff --git a/libcpu/arm/cortex-m7/cpuport.c b/libcpu/arm/cortex-m7/cpuport.c
index 18f027895b..e701a52307 100644
--- a/libcpu/arm/cortex-m7/cpuport.c
+++ b/libcpu/arm/cortex-m7/cpuport.c
@@ -14,6 +14,7 @@
* 2012-12-29 Bernard Add exception hook.
* 2013-06-23 aozima support lazy stack optimized.
* 2018-07-24 aozima enhancement hard fault exception handler.
+ * 2019-07-03 yangjie add __rt_ffs() for armclang.
*/
#include <rtthread.h>
@@ -453,7 +454,7 @@ RT_WEAK void rt_hw_cpu_reset(void)
* @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
-#if defined(__CC_ARM) || defined(__CLANG_ARM)
+#if defined(__CC_ARM)
__asm int __rt_ffs(int value)
{
CMP r0, #0x00
@@ -466,6 +467,24 @@ __asm int __rt_ffs(int value)
exit
BX lr
}
+#elif defined(__CLANG_ARM)
+int __rt_ffs(int value)
+{
+ __asm volatile(
+ "CMP r0, #0x00 \n"
+ "BEQ 1f \n"
+
+ "RBIT r0, r0 \n"
+ "CLZ r0, r0 \n"
+ "ADDS r0, r0, #0x01 \n"
+
+ "1: \n"
+
+ : "=r"(value)
+ : "r"(value)
+ );
+ return value;
+}
#elif defined(__IAR_SYSTEMS_ICC__)
int __rt_ffs(int value)
{
diff --git a/libcpu/arm/cortex-r4/SConscript b/libcpu/arm/cortex-r4/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/cortex-r4/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/cortex-r4/context_ccs.asm b/libcpu/arm/cortex-r4/context_ccs.asm
index 2b459f8238..9463556743 100644
--- a/libcpu/arm/cortex-r4/context_ccs.asm
+++ b/libcpu/arm/cortex-r4/context_ccs.asm
@@ -1,14 +1,10 @@
;/*
-; * File : context_ccs.asm
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
-; * Date Author Notes
+; * Date Author Notes
; * 2009-01-20 Bernard first version
; * 2011-07-22 Bernard added thumb mode porting
; * 2013-05-24 Grissiom port to CCS
diff --git a/libcpu/arm/cortex-r4/start_gcc.S b/libcpu/arm/cortex-r4/start_gcc.S
index ab77b98781..a347503ec0 100644
--- a/libcpu/arm/cortex-r4/start_gcc.S
+++ b/libcpu/arm/cortex-r4/start_gcc.S
@@ -36,6 +36,7 @@
.globl stack_start
.globl stack_top
+.align 3
stack_start:
.rept (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size)
.byte 0
diff --git a/libcpu/arm/dm36x/SConscript b/libcpu/arm/dm36x/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/dm36x/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/dm36x/context_rvds.S b/libcpu/arm/dm36x/context_rvds.S
index 631da83372..8e0fc4465b 100644
--- a/libcpu/arm/dm36x/context_rvds.S
+++ b/libcpu/arm/dm36x/context_rvds.S
@@ -1,21 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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.
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/lpc214x/SConscript b/libcpu/arm/lpc214x/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/lpc214x/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/lpc214x/context_rvds.S b/libcpu/arm/lpc214x/context_rvds.S
index 762b67d42e..47ca31cd1f 100644
--- a/libcpu/arm/lpc214x/context_rvds.S
+++ b/libcpu/arm/lpc214x/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/lpc24xx/SConscript b/libcpu/arm/lpc24xx/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/lpc24xx/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/lpc24xx/context_rvds.S b/libcpu/arm/lpc24xx/context_rvds.S
index ecd20e4bbe..0d9915f4f1 100644
--- a/libcpu/arm/lpc24xx/context_rvds.S
+++ b/libcpu/arm/lpc24xx/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/realview-a8-vmm/SConscript b/libcpu/arm/realview-a8-vmm/SConscript
index 61057c04cc..9ff30a796b 100644
--- a/libcpu/arm/realview-a8-vmm/SConscript
+++ b/libcpu/arm/realview-a8-vmm/SConscript
@@ -1,17 +1,23 @@
-Import('rtconfig')
+# RT-Thread building script for component
+
from building import *
+Import('rtconfig')
+
cwd = GetCurrentDir()
-src = Glob('*.c')
+src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
if rtconfig.PLATFORM == 'iar':
- src += Glob('*_iar.S')
-elif rtconfig.PLATFORM == 'gcc':
- src += Glob('*_gcc.S')
-elif rtconfig.PLATFORM == 'armcc':
- src += Glob('*_rvds.S')
+ src += Glob('*_iar.S')
-group = DefineGroup('AM335x', src, depend = [''], CPPPATH = CPPPATH)
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
diff --git a/libcpu/arm/realview-a8-vmm/start_gcc.S b/libcpu/arm/realview-a8-vmm/start_gcc.S
index 2ec7fe6c86..879cf992a8 100644
--- a/libcpu/arm/realview-a8-vmm/start_gcc.S
+++ b/libcpu/arm/realview-a8-vmm/start_gcc.S
@@ -47,6 +47,7 @@
.globl stack_start
.globl stack_top
+.align 3
stack_start:
.rept ISR_Stack_Size
.byte 0
diff --git a/libcpu/arm/s3c24x0/SConscript b/libcpu/arm/s3c24x0/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/s3c24x0/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/s3c24x0/context_rvds.S b/libcpu/arm/s3c24x0/context_rvds.S
index 54d655afe1..9078f6173a 100644
--- a/libcpu/arm/s3c24x0/context_rvds.S
+++ b/libcpu/arm/s3c24x0/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/s3c24x0/serial.c b/libcpu/arm/s3c24x0/serial.c
deleted file mode 100644
index 1eca1b1110..0000000000
--- a/libcpu/arm/s3c24x0/serial.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2006-03-13 Bernard first version
- * 2009-04-20 yi.qiu modified according bernard's stm32 version
- */
-
-#include <rtthread.h>
-
-#include "serial.h"
-
-/**
- * @addtogroup S3C24X0
- */
-/*@{*/
-
-/* RT-Thread Device Interface */
-/**
- * This function initializes serial
- */
-static rt_err_t rt_serial_init(rt_device_t dev)
-{
- struct serial_device* uart = (struct serial_device*) dev->user_data;
-
- if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
- {
-
- if (dev->flag & RT_DEVICE_FLAG_INT_RX)
- {
- rt_memset(uart->int_rx->rx_buffer, 0,
- sizeof(uart->int_rx->rx_buffer));
- uart->int_rx->read_index = uart->int_rx->save_index = 0;
- }
-
- if (dev->flag & RT_DEVICE_FLAG_INT_TX)
- {
- rt_memset(uart->int_tx->tx_buffer, 0,
- sizeof(uart->int_tx->tx_buffer));
- uart->int_tx->write_index = uart->int_tx->save_index = 0;
- }
-
- dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
- }
-
- return RT_EOK;
-}
-
-/* save a char to serial buffer */
-static void rt_serial_savechar(struct serial_device* uart, char ch)
-{
- rt_base_t level;
-
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
-
- uart->int_rx->rx_buffer[uart->int_rx->save_index] = ch;
- uart->int_rx->save_index ++;
- if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
- uart->int_rx->save_index = 0;
-
- /* if the next position is read index, discard this 'read char' */
- if (uart->int_rx->save_index == uart->int_rx->read_index)
- {
- uart->int_rx->read_index ++;
- if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
- uart->int_rx->read_index = 0;
- }
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
-}
-
-static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
-{
- RT_ASSERT(dev != RT_NULL);
-
- return RT_EOK;
-}
-
-static rt_err_t rt_serial_close(rt_device_t dev)
-{
- RT_ASSERT(dev != RT_NULL);
-
- return RT_EOK;
-}
-
-static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- rt_uint8_t* ptr;
- rt_err_t err_code;
- struct serial_device* uart;
-
- ptr = buffer;
- err_code = RT_EOK;
- uart = (struct serial_device*)dev->user_data;
-
- if (ptr == RT_NULL)
- {
- err_code = -RT_ENOMEM;
- rt_set_errno(err_code);
- return -RT_ENOMEM;
- }
- if (dev->flag & RT_DEVICE_FLAG_INT_RX)
- {
- rt_base_t level;
-
- /* interrupt mode Rx */
- while (size)
- {
- if (uart->int_rx->read_index != uart->int_rx->save_index)
- {
- *ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
- size --;
-
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
-
- uart->int_rx->read_index ++;
- if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
- uart->int_rx->read_index = 0;
-
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
- }
- else
- {
- /* set error code */
- err_code = -RT_EEMPTY;
- break;
- }
- }
- }
- else
- {
- /* polling mode */
- while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
- {
- while (uart->uart_device->ustat & USTAT_RCV_READY)
- {
- *ptr = uart->uart_device->urxh & 0xff;
- ptr ++;
- }
- }
- }
-
- /* set error code */
- rt_set_errno(err_code);
- return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
-}
-
-static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint8_t* ptr;
- rt_err_t err_code;
- struct serial_device* uart;
-
- err_code = RT_EOK;
- ptr = (rt_uint8_t*)buffer;
- uart = (struct serial_device*)dev->user_data;
-
- if (ptr == RT_NULL)
- {
- err_code = -RT_ENOMEM;
- rt_set_errno(err_code);
- return -RT_ENOMEM;
- }
- if (dev->flag & RT_DEVICE_FLAG_INT_TX)
- {
- /* interrupt mode Tx */
- while (uart->int_tx->save_index != uart->int_tx->write_index)
- {
- /* save on tx buffer */
- uart->int_tx->tx_buffer[uart->int_tx->save_index] = *ptr++;
-
- -- size;
-
- /* move to next position */
- uart->int_tx->save_index ++;
-
- /* wrap save index */
- if (uart->int_tx->save_index >= UART_TX_BUFFER_SIZE)
- uart->int_tx->save_index = 0;
- }
-
- /* set error code */
- if (size > 0)
- err_code = -RT_EFULL;
- }
- else
- {
- /* polling mode */
- while (size)
- {
- /*
- * to be polite with serial console add a line feed
- * to the carriage return character
- */
- if (*ptr == '\n' && (dev->flag & RT_DEVICE_FLAG_STREAM))
- {
- while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY));
- uart->uart_device->utxh = '\r';
- }
-
- while (!(uart->uart_device->ustat & USTAT_TXB_EMPTY));
- uart->uart_device->utxh = (*ptr & 0xFF);
-
- ++ptr;
- --size;
- }
- }
-
- /* set error code */
- rt_set_errno(err_code);
- return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
-}
-
-static rt_err_t rt_serial_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- switch (cmd)
- {
- case RT_DEVICE_CTRL_SUSPEND:
- /* suspend device */
- dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
- break;
-
- case RT_DEVICE_CTRL_RESUME:
- /* resume device */
- dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
- break;
- }
-
- return RT_EOK;
-}
-
-/*
- * serial register
- */
-rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial)
-{
- RT_ASSERT(device != RT_NULL);
-
- device->type = RT_Device_Class_Char;
- device->rx_indicate = RT_NULL;
- device->tx_complete = RT_NULL;
- device->init = rt_serial_init;
- device->open = rt_serial_open;
- device->close = rt_serial_close;
- device->read = rt_serial_read;
- device->write = rt_serial_write;
- device->control = rt_serial_control;
- device->user_data = serial;
-
- /* register a character device */
- return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
-}
-
-/* ISR for serial interrupt */
-void rt_hw_serial_isr(rt_device_t device)
-{
- struct serial_device* uart = (struct serial_device*) device->user_data;
-
- /* interrupt mode receive */
- RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
-
- /* save on rx buffer */
- while (uart->uart_device->ustat & USTAT_RCV_READY)
- {
- rt_serial_savechar(uart, uart->uart_device->urxh & 0xff);
- }
-
- /* invoke callback */
- if (device->rx_indicate != RT_NULL)
- {
- rt_size_t rx_length;
-
- /* get rx length */
- rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
- UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
- uart->int_rx->save_index - uart->int_rx->read_index;
-
- device->rx_indicate(device, rx_length);
- }
-}
-
-/*@}*/
diff --git a/libcpu/arm/s3c24x0/serial.h b/libcpu/arm/s3c24x0/serial.h
deleted file mode 100644
index 8a647ef35f..0000000000
--- a/libcpu/arm/s3c24x0/serial.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#ifndef __RT_HW_SERIAL_H__
-#define __RT_HW_SERIAL_H__
-
-#include <rthw.h>
-#include <rtthread.h>
-
-#include "s3c24x0.h"
-
-#define USTAT_RCV_READY 0x01 /* receive data ready */
-#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */
-#define BPS 115200 /* serial baudrate */
-
-#define UART_RX_BUFFER_SIZE 64
-#define UART_TX_BUFFER_SIZE 64
-
-struct serial_int_rx
-{
- rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
- rt_uint32_t read_index, save_index;
-};
-
-struct serial_int_tx
-{
- rt_uint8_t tx_buffer[UART_TX_BUFFER_SIZE];
- rt_uint32_t write_index, save_index;
-};
-
-typedef struct uartport
-{
- volatile rt_uint32_t ulcon;
- volatile rt_uint32_t ucon;
- volatile rt_uint32_t ufcon;
- volatile rt_uint32_t umcon;
- volatile rt_uint32_t ustat;
- volatile rt_uint32_t urxb;
- volatile rt_uint32_t ufstat;
- volatile rt_uint32_t umstat;
- volatile rt_uint32_t utxh;
- volatile rt_uint32_t urxh;
- volatile rt_uint32_t ubrd;
-}uartport;
-
-struct serial_device
-{
- uartport* uart_device;
-
- /* rx structure */
- struct serial_int_rx* int_rx;
-
- /* tx structure */
- struct serial_int_tx* int_tx;
-};
-
-rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial);
-
-void rt_hw_serial_isr(rt_device_t device);
-
-#endif
diff --git a/libcpu/arm/s3c24x0/start_gcc.S b/libcpu/arm/s3c24x0/start_gcc.S
index 4adc458094..cc2b2f6310 100644
--- a/libcpu/arm/s3c24x0/start_gcc.S
+++ b/libcpu/arm/s3c24x0/start_gcc.S
@@ -191,7 +191,7 @@ reset:
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
+ cmp r0, r2 /* until source end address [r2] */
ble copy_loop
/* setup stack */
diff --git a/libcpu/arm/s3c44b0/SConscript b/libcpu/arm/s3c44b0/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/s3c44b0/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/s3c44b0/context_rvds.S b/libcpu/arm/s3c44b0/context_rvds.S
index 641ec7a6b1..27ebf8f5e3 100644
--- a/libcpu/arm/s3c44b0/context_rvds.S
+++ b/libcpu/arm/s3c44b0/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/s3c44b0/start_gcc.S b/libcpu/arm/s3c44b0/start_gcc.S
index 65b3d422dd..4c448a344f 100644
--- a/libcpu/arm/s3c44b0/start_gcc.S
+++ b/libcpu/arm/s3c44b0/start_gcc.S
@@ -107,7 +107,7 @@ reset:
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
+ cmp r0, r2 /* until source end address [r2] */
ble copy_loop
#endif
diff --git a/libcpu/arm/sep4020/SConscript b/libcpu/arm/sep4020/SConscript
new file mode 100644
index 0000000000..9ff30a796b
--- /dev/null
+++ b/libcpu/arm/sep4020/SConscript
@@ -0,0 +1,23 @@
+# RT-Thread building script for component
+
+from building import *
+
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
+if rtconfig.PLATFORM == 'iar':
+ src += Glob('*_iar.S')
+
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/libcpu/arm/sep4020/context_rvds.S b/libcpu/arm/sep4020/context_rvds.S
index 641ec7a6b1..27ebf8f5e3 100644
--- a/libcpu/arm/sep4020/context_rvds.S
+++ b/libcpu/arm/sep4020/context_rvds.S
@@ -1,11 +1,7 @@
;/*
-; * File : context_rvds.S
-; * This file is part of RT-Thread RTOS
-; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; * Copyright (c) 2006-2018, 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
+; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
diff --git a/libcpu/arm/zynq7000/SConscript b/libcpu/arm/zynq7000/SConscript
index 2ad51b573e..9ff30a796b 100644
--- a/libcpu/arm/zynq7000/SConscript
+++ b/libcpu/arm/zynq7000/SConscript
@@ -1,17 +1,23 @@
-Import('rtconfig')
+# RT-Thread building script for component
+
from building import *
+Import('rtconfig')
+
cwd = GetCurrentDir()
-src = Glob('*.c')
+src = Glob('*.c') + Glob('*.cpp')
CPPPATH = [cwd]
+if rtconfig.PLATFORM == 'armcc':
+ src += Glob('*_rvds.S')
+
+if rtconfig.PLATFORM == 'gcc':
+ src += Glob('*_init.S')
+ src += Glob('*_gcc.S')
+
if rtconfig.PLATFORM == 'iar':
- src += Glob('*_iar.S')
-elif rtconfig.PLATFORM == 'gcc':
- src += Glob('*_gcc.S')
-elif rtconfig.PLATFORM == 'armcc':
- src += Glob('*_rvds.S')
+ src += Glob('*_iar.S')
-group = DefineGroup('AM1808', src, depend = [''], CPPPATH = CPPPATH)
+group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
diff --git a/libcpu/arm/zynq7000/context_gcc.S b/libcpu/arm/zynq7000/context_gcc.S
index 3dbf3c861d..98f98a0244 100644
--- a/libcpu/arm/zynq7000/context_gcc.S
+++ b/libcpu/arm/zynq7000/context_gcc.S
@@ -1,21 +1,11 @@
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
+ * Copyright (c) 2006-2018, Shanghai Real-Thread Technology Co., Ltd
*
- * All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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
+ * 2009-01-20 Bernard first version
*/
#define NOINT 0xc0
diff --git a/libcpu/arm/zynq7000/cp15.h b/libcpu/arm/zynq7000/cp15.h
index bd6a23f1b2..75d81736ab 100644
--- a/libcpu/arm/zynq7000/cp15.h
+++ b/libcpu/arm/zynq7000/cp15.h
@@ -1,25 +1,16 @@
-#ifndef __CP15_H__
-#define __CP15_H__
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
- *
- * All rights reserved.
- *
- * 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.
+ * Copyright (c) 2006-2018, RT-Thread Development Team
*
- * 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.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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-20 Bernard first version
*/
+#ifndef __CP15_H__
+#define __CP15_H__
+
unsigned long rt_cpu_get_smp_id(void);
void rt_cpu_mmu_disable(void);
diff --git a/libcpu/arm/zynq7000/gic.c b/libcpu/arm/zynq7000/gic.c
index 498446db43..76404d4c46 100644
--- a/libcpu/arm/zynq7000/gic.c
+++ b/libcpu/arm/zynq7000/gic.c
@@ -1,21 +1,11 @@
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
+ * Copyright (c) 2006-2018, RT-Thread Development Team
*
- * All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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-20 Bernard first version
*/
#include <rtthread.h>
@@ -47,7 +37,7 @@ static struct arm_gic _gic_table[ARM_GIC_MAX_NR];
#define GIC_DIST_ENABLE_SET(hw_base, n) __REG32((hw_base) + 0x100 + (n/32) * 4)
#define GIC_DIST_ENABLE_CLEAR(hw_base, n) __REG32((hw_base) + 0x180 + (n/32) * 4)
#define GIC_DIST_PENDING_SET(hw_base, n) __REG32((hw_base) + 0x200)
-#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280)
+#define GIC_DIST_PENDING_CLEAR(hw_base, n) __REG32((hw_base) + 0x280 + (n/32) * 4)
#define GIC_DIST_ACTIVE_BIT(hw_base) __REG32((hw_base) + 0x300)
#define GIC_DIST_PRI(hw_base, n) __REG32((hw_base) + 0x400 + (n/4) * 4)
#define GIC_DIST_TARGET(hw_base, n) __REG32((hw_base) + 0x800 + (n/4) * 4)
@@ -78,9 +68,8 @@ void arm_gic_ack(rt_uint32_t index, int irq)
irq = irq - _gic_table[index].offset;
RT_ASSERT(irq >= 0);
- GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
+ GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
GIC_CPU_EOI(_gic_table[index].cpu_hw_base) = irq;
- GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask;
}
void arm_gic_mask(rt_uint32_t index, int irq)
diff --git a/libcpu/arm/zynq7000/gic.h b/libcpu/arm/zynq7000/gic.h
index 4b89538948..8fcdf05f6f 100644
--- a/libcpu/arm/zynq7000/gic.h
+++ b/libcpu/arm/zynq7000/gic.h
@@ -1,21 +1,11 @@
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
+ * Copyright (c) 2006-2018, RT-Thread Development Team
*
- * All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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-20 Bernard first version
*/
#ifndef __GIC_H__
diff --git a/libcpu/arm/zynq7000/interrupt.h b/libcpu/arm/zynq7000/interrupt.h
index 07eafc84e5..da266c42a2 100644
--- a/libcpu/arm/zynq7000/interrupt.h
+++ b/libcpu/arm/zynq7000/interrupt.h
@@ -1,25 +1,16 @@
-#ifndef __INTERRUPT_H__
-#define __INTERRUPT_H__
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
- *
- * All rights reserved.
- *
- * 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.
+ * Copyright (c) 2006-2018, RT-Thread Development Team
*
- * 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.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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-20 Bernard first version
*/
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
void rt_hw_interrupt_clear(int vector);
#endif /* end of include guard: __INTERRUPT_H__ */
diff --git a/libcpu/arm/zynq7000/mmu.c b/libcpu/arm/zynq7000/mmu.c
index 2a58fabe4f..fbdacca10f 100644
--- a/libcpu/arm/zynq7000/mmu.c
+++ b/libcpu/arm/zynq7000/mmu.c
@@ -1,21 +1,11 @@
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
+ * Copyright (c) 2006-2018, RT-Thread Development Team
*
- * All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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-20 Bernard first version
*/
#include <rtthread.h>
diff --git a/libcpu/arm/zynq7000/start_gcc.S b/libcpu/arm/zynq7000/start_gcc.S
index 6904c45587..18056f0ad9 100644
--- a/libcpu/arm/zynq7000/start_gcc.S
+++ b/libcpu/arm/zynq7000/start_gcc.S
@@ -33,6 +33,7 @@
.globl stack_start
.globl stack_top
+.align 3
.bss
stack_start:
.rept ISR_Stack_Size
diff --git a/libcpu/arm/zynq7000/trap.c b/libcpu/arm/zynq7000/trap.c
index 9bf58f916c..6243ea82b4 100644
--- a/libcpu/arm/zynq7000/trap.c
+++ b/libcpu/arm/zynq7000/trap.c
@@ -1,21 +1,11 @@
/*
- * COPYRIGHT (C) 2013-2014, Shanghai Real-Thread Technology Co., Ltd
+ * Copyright (c) 2006-2018, RT-Thread Development Team
*
- * All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
*
- * 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-20 Bernard first version
*/
#include <rtthread.h>