2 * linux/arch/arm/mm/proc-arm7tdmi.S
4 * Copyright (C) 1997-2000 Russell King
5 * Copyright (C) 2003 Hyok S. Choi <hyok.choi@samsung.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * for ARM7TDMI and the compatibles.
13 #include <linux/linkage.h>
14 #include <linux/init.h>
15 #include <asm/assembler.h>
16 #include <asm/pgtable.h>
17 #include <asm/procinfo.h>
18 #include <asm/ptrace.h>
19 #include <asm/errno.h>
21 ENTRY(cpu_arm7tdmi_dcache_clean_area)
25 * Function: arm7tdmi_data_abort ()
27 * Params : r2 = address of aborted instruction
28 * : sp = pointer to registers
30 * Purpose : obtain information about current aborted instruction
32 * Returns : r0 = address of abort
36 ENTRY(cpu_arm7tdmi_data_abort)
37 #ifdef CONFIG_CPU_CP15
38 mrc p15, 0, r1, c5, c0, 0 @ get FSR
39 mrc p15, 0, r0, c6, c0, 0 @ get FAR
41 ldr r8, [r0] @ read arm instruction
42 tst r8, #1 << 20 @ L = 1 -> write?
43 orreq r1, r1, #1 << 8 @ yes.
45 add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine
48 /* 0 */ b .data_unknown
49 /* 1 */ mov pc, lr @ swp
50 /* 2 */ b .data_unknown
51 /* 3 */ b .data_unknown
52 /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m
53 /* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m]
54 /* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm
55 /* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm]
56 /* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist>
57 /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist>
58 /* a */ b .data_unknown
59 /* b */ b .data_unknown
60 /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
61 /* d */ mov pc, lr @ ldc rd, [rn, #m]
62 /* e */ b .data_unknown
64 .data_unknown: @ Part of jumptable
73 tst r8, #1 << 21 @ check writeback bit
74 moveq pc, lr @ no writeback -> no fixup
78 and r2, r8, r7, lsl #1
79 add r6, r6, r2, lsr #1
80 and r2, r8, r7, lsl #2
81 add r6, r6, r2, lsr #2
82 and r2, r8, r7, lsl #3
83 add r6, r6, r2, lsr #3
84 add r6, r6, r6, lsr #8
85 add r6, r6, r6, lsr #4
86 and r6, r6, #15 @ r6 = no. of registers to transfer.
87 and r5, r8, #15 << 16 @ Extract 'n' from instruction
88 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
89 tst r8, #1 << 23 @ Check U bit
90 subne r7, r7, r6, lsl #2 @ Undo increment
91 addeq r7, r7, r6, lsl #2 @ Undo decrement
92 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
95 .data_arm_apply_r6_and_rn:
96 and r5, r8, #15 << 16 @ Extract 'n' from instruction
97 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
98 tst r8, #1 << 23 @ Check U bit
99 subne r7, r7, r6 @ Undo incrmenet
100 addeq r7, r7, r6 @ Undo decrement
101 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
104 .data_arm_lateldrpreconst:
105 tst r8, #1 << 21 @ check writeback bit
106 moveq pc, lr @ no writeback -> no fixup
107 .data_arm_lateldrpostconst:
108 movs r2, r8, lsl #20 @ Get offset
109 moveq pc, lr @ zero -> no fixup
110 and r5, r8, #15 << 16 @ Extract 'n' from instruction
111 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
112 tst r8, #1 << 23 @ Check U bit
113 subne r7, r7, r2, lsr #20 @ Undo increment
114 addeq r7, r7, r2, lsr #20 @ Undo decrement
115 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
118 .data_arm_lateldrprereg:
119 tst r8, #1 << 21 @ check writeback bit
120 moveq pc, lr @ no writeback -> no fixup
121 .data_arm_lateldrpostreg:
122 and r7, r8, #15 @ Extract 'm' from instruction
123 ldr r6, [sp, r7, lsl #2] @ Get register 'Rm'
124 mov r5, r8, lsr #7 @ get shift count
126 and r7, r8, #0x70 @ get shift type
127 orreq r7, r7, #8 @ shift count = 0
131 mov r6, r6, lsl r5 @ 0: LSL #!0
132 b .data_arm_apply_r6_and_rn
133 b .data_arm_apply_r6_and_rn @ 1: LSL #0
135 b .data_unknown @ 2: MUL?
137 b .data_unknown @ 3: MUL?
139 mov r6, r6, lsr r5 @ 4: LSR #!0
140 b .data_arm_apply_r6_and_rn
141 mov r6, r6, lsr #32 @ 5: LSR #32
142 b .data_arm_apply_r6_and_rn
143 b .data_unknown @ 6: MUL?
145 b .data_unknown @ 7: MUL?
147 mov r6, r6, asr r5 @ 8: ASR #!0
148 b .data_arm_apply_r6_and_rn
149 mov r6, r6, asr #32 @ 9: ASR #32
150 b .data_arm_apply_r6_and_rn
151 b .data_unknown @ A: MUL?
153 b .data_unknown @ B: MUL?
155 mov r6, r6, ror r5 @ C: ROR #!0
156 b .data_arm_apply_r6_and_rn
157 mov r6, r6, rrx @ D: RRX
158 b .data_arm_apply_r6_and_rn
159 b .data_unknown @ E: MUL?
161 b .data_unknown @ F: MUL?
164 * Function: arm7tdmi_proc_init (void)
165 * : arm7tdmi_proc_fin (void)
167 * Notes : This processor does not require these
169 ENTRY(cpu_arm7tdmi_proc_init)
172 ENTRY(cpu_arm7tdmi_proc_fin)
173 mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
175 #ifdef CONFIG_CPU_CP15
176 mov r0, #0x31 @ ....S..DP...M
177 mcr p15, 0, r0, c1, c0, 0 @ disable caches
181 ENTRY(cpu_arm7tdmi_do_idle)
185 * Function: arm7tdmi_switch_mm(unsigned long pgd_phys)
186 * Params : pgd_phys Physical address of page table
187 * Purpose : Perform a task switch, saving the old processes state, and restoring
190 ENTRY(cpu_arm7tdmi_switch_mm)
194 * Function: _arm7tdmi_reset
195 * Params : r0 = address to jump to
196 * Notes : This sets up everything for a reset
198 ENTRY(cpu_arm7tdmi_reset)
199 #ifdef CONFIG_CPU_CP15
201 mcr p15, 0, r1, c7, c0, 0 @ flush cache
203 mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc
209 .type __arm7tdmi_setup, #function
211 #ifdef CONFIG_CPU_CP15
213 mcr p15, 0, r0, c7, c0 @ flush caches on v3
215 mov r0, #0x7c @ . .... .LDP WC..
217 .size __arm7tdmi_setup, . - __arm7tdmi_setup
222 * Purpose : Function pointers used to access above functions - all calls
225 .type arm7tdmi_processor_functions, #object
226 ENTRY(arm7tdmi_processor_functions)
227 .word cpu_arm7tdmi_data_abort
228 .word cpu_arm7tdmi_proc_init
229 .word cpu_arm7tdmi_proc_fin
230 .word cpu_arm7tdmi_reset
231 .word cpu_arm7tdmi_do_idle
232 .word cpu_arm7tdmi_dcache_clean_area
233 .word cpu_arm7tdmi_switch_mm
234 .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
238 .type cpu_arch_name, #object
239 cpu_arch_name: .asciz "armv4t"
240 .size cpu_arch_name, . - cpu_arch_name
242 .type cpu_elf_name, #object
243 cpu_elf_name: .asciz "v4"
244 .size cpu_elf_name, . - cpu_elf_name
246 .type cpu_arm7tdmi_name, #object
249 .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name
251 .type cpu_triscenda7_name, #object
253 #if defined(CONFIG_ARCH_TA7S)
254 .asciz "Triscend-A7S"
255 #elif defined(CONFIG_ARCH_TA7V)
256 .asciz "Triscend-A7V"
258 .size cpu_triscenda7_name, . - cpu_triscenda7_name
260 .type cpu_at91_name, #object
262 .asciz "Atmel-AT91M40xxx"
263 .size cpu_at91_name, . - cpu_at91_name
265 .type cpu_s3c3410_name, #object
267 .asciz "Samsung-S3C3410"
268 .size cpu_s3c3410_name, . - cpu_s3c3410_name
270 .type cpu_s3c44b0x_name, #object
272 .asciz "Samsung-S3C44B0x"
273 .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name
275 .type cpu_s3c4510b, #object
277 .asciz "Samsung-S3C4510B"
278 .size cpu_s3c4510b_name, . - cpu_s3c4510b_name
280 .type cpu_s3c4530_name, #object
282 .asciz "Samsung-S3C4530"
283 .size cpu_s3c4530_name, . - cpu_s3c4530_name
285 .type cpu_netarm_name, #object
288 .size cpu_netarm_name, . - cpu_netarm_name
292 .section ".proc.info.init", #alloc, #execinstr
294 .type __arm7tdmi_proc_info, #object
295 __arm7tdmi_proc_info:
303 .long HWCAP_SWP | HWCAP_26BIT
304 .long cpu_arm7tdmi_name
305 .long arm7tdmi_processor_functions
309 .size __arm7tdmi_proc_info, . - __arm7dmi_proc_info
311 .type __triscenda7_proc_info, #object
312 __triscenda7_proc_info:
320 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
321 .long cpu_triscenda7_name
322 .long arm7tdmi_processor_functions
326 .size __triscenda7_proc_info, . - __triscenda7_proc_info
328 .type __at91_proc_info, #object
337 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
339 .long arm7tdmi_processor_functions
343 .size __at91_proc_info, . - __at91_proc_info
345 .type __s3c4510b_proc_info, #object
346 __s3c4510b_proc_info:
354 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
355 .long cpu_s3c4510b_name
356 .long arm7tdmi_processor_functions
360 .size __s3c4510b_proc_info, . - __s3c4510b_proc_info
362 .type __s3c4530_proc_info, #object
371 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
372 .long cpu_s3c4530_name
373 .long arm7tdmi_processor_functions
377 .size __s3c4530_proc_info, . - __s3c4530_proc_info
379 .type __s3c3410_proc_info, #object
388 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
389 .long cpu_s3c3410_name
390 .long arm7tdmi_processor_functions
394 .size __s3c3410_proc_info, . - __s3c3410_proc_info
396 .type __s3c44b0x_proc_info, #object
397 __s3c44b0x_proc_info:
405 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
406 .long cpu_s3c44b0x_name
407 .long arm7tdmi_processor_functions
411 .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info