summaryrefslogtreecommitdiff
path: root/libcpu/arm/armv6/arm_entry_gcc.S
blob: 3aa9930d2b6e25fed8dc398badf6ccb11ea5b770 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
 * File      : arm_entry_gcc.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
 * 2014-11-07     weety    first version
 */

#include <rtconfig.h>

#include "armv6.h"

//#define DEBUG

.macro	PRINT, str
#ifdef DEBUG
	stmfd	sp!, {r0-r3, ip, lr}
	add	r0, pc, #4
	bl	rt_kprintf
	b	1f
	.asciz  "UNDEF: \str\n"
	.balign 4
1:	ldmfd	sp!, {r0-r3, ip, lr}
#endif
	.endm

.macro  PRINT1, str, arg
#ifdef DEBUG
	stmfd	sp!, {r0-r3, ip, lr}
	mov	r1, \arg
	add	r0, pc, #4
	bl	rt_kprintf
	b	1f
	.asciz  "UNDEF: \str\n"
	.balign 4
1:	ldmfd	sp!, {r0-r3, ip, lr}
#endif
	.endm

.macro  PRINT3, str, arg1, arg2, arg3
#ifdef DEBUG
	stmfd	sp!, {r0-r3, ip, lr}
	mov	r3, \arg3
	mov	r2, \arg2
	mov	r1, \arg1
	add	r0, pc, #4
	bl	rt_kprintf
	b	1f
	.asciz  "UNDEF: \str\n"
	.balign 4
1:	ldmfd	sp!, {r0-r3, ip, lr}
#endif
	.endm

.macro	get_current_thread, rd
	ldr	\rd, .current_thread
	ldr	\rd, [\rd]
	.endm

.current_thread:
	.word	rt_current_thread

#ifdef RT_USING_NEON
	.align	6

/* is the neon instuction on arm mode? */
.neon_opcode:
	.word	0xfe000000			@ mask
	.word	0xf2000000			@ opcode

	.word	0xff100000			@ mask
	.word	0xf4000000			@ opcode

	.word	0x00000000			@ end mask
	.word	0x00000000			@ end opcode
#endif

/* undefined instruction exception processing */
.globl undef_entry
undef_entry:
	PRINT1 "r0=0x%08x", r0
	PRINT1 "r2=0x%08x", r2
	PRINT1 "r9=0x%08x", r9
	PRINT1 "sp=0x%08x", sp

#ifdef RT_USING_NEON
	ldr	r6, .neon_opcode
__check_neon_instruction:
	ldr	r7, [r6], #4		@ load mask value
	cmp	r7, #0				@ end mask?
	beq	__check_vfp_instruction
	and	r8, r0, r7
	ldr	r7, [r6], #4		@ load opcode value
	cmp	r8, r7				@ is NEON instruction?
	bne	__check_neon_instruction
	b	vfp_entry
__check_vfp_instruction:
#endif
	tst	r0, #0x08000000			@ only CDP/CPRT/LDC/STC instruction has bit 27
	tstne	r0, #0x04000000		@ bit 26 set on both ARM and Thumb-2 instruction
	moveq	pc, lr				@ no vfp coprocessor instruction, return
	get_current_thread r10
	and	r8, r0, #0x00000f00		@ get coprocessor number
	PRINT1 "CP=0x%08x", r8
	add	pc, pc, r8, lsr #6
	nop
	mov pc,	lr				@ CP0
	mov pc,	lr				@ CP1
	mov pc,	lr				@ CP2
	mov pc,	lr				@ CP3
	mov pc,	lr				@ CP4
	mov pc,	lr				@ CP5
	mov pc,	lr				@ CP6
	mov pc,	lr				@ CP7
	mov pc,	lr				@ CP8
	mov pc,	lr				@ CP9
	mov pc,	lr				@ CP10 VFP
	mov pc,	lr				@ CP11 VFP
	mov pc,	lr				@ CP12
	mov pc,	lr				@ CP13
	mov pc,	lr				@ CP14 DEBUG
	mov pc,	lr				@ CP15 SYS CONTROL