2 * linux/arch/arm/mm/proc-arm9tdmi.S
4 * Copyright (C) 1997-2000 Russell King
5 * Copyright (C) 2003 Hyok S. Choi <hyok.choi@samsung.com>
6 * Copyright (C) 2004-2005 Tobias Lorenz <tobias.lorenz@gmx.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * for ARM9TDMI and the compatibles.
14 #include <linux/linkage.h>
15 #include <linux/init.h>
16 #include <asm/assembler.h>
17 #include <asm/pgtable.h>
18 #include <asm/procinfo.h>
19 #include <asm/ptrace.h>
20 #include <asm/errno.h>
22 ENTRY(cpu_arm9tdmi_dcache_clean_area)
26 * Function: arm9tdmi_data_abort ()
28 * Params : r2 = address of aborted instruction
29 * : sp = pointer to registers
31 * Purpose : obtain information about current aborted instruction
33 * Returns : r0 = address of abort
37 ENTRY(cpu_arm9tdmi_data_abort)
38 ldr r8, [r0] @ read arm instruction
39 tst r8, #1 << 20 @ L = 1 -> write?
40 orreq r1, r1, #1 << 8 @ yes.
42 add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine
45 /* 0 */ b .data_unknown
46 /* 1 */ mov pc, lr @ swp
47 /* 2 */ b .data_unknown
48 /* 3 */ b .data_unknown
49 /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m
50 /* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m]
51 /* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm
52 /* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm]
53 /* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist>
54 /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist>
55 /* a */ b .data_unknown
56 /* b */ b .data_unknown
57 /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
58 /* d */ mov pc, lr @ ldc rd, [rn, #m]
59 /* e */ b .data_unknown
61 .data_unknown: @ Part of jumptable
69 tst r8, #1 << 21 @ check writeback bit
70 moveq pc, lr @ no writeback -> no fixup
74 and r2, r8, r7, lsl #1
75 add r6, r6, r2, lsr #1
76 and r2, r8, r7, lsl #2
77 add r6, r6, r2, lsr #2
78 and r2, r8, r7, lsl #3
79 add r6, r6, r2, lsr #3
80 add r6, r6, r6, lsr #8
81 add r6, r6, r6, lsr #4
82 and r6, r6, #15 @ r6 = no. of registers to transfer.
83 and r5, r8, #15 << 16 @ Extract 'n' from instruction
84 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
85 tst r8, #1 << 23 @ Check U bit
86 subne r7, r7, r6, lsl #2 @ Undo increment
87 addeq r7, r7, r6, lsl #2 @ Undo decrement
88 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
91 .data_arm_apply_r6_and_rn:
92 and r5, r8, #15 << 16 @ Extract 'n' from instruction
93 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
94 tst r8, #1 << 23 @ Check U bit
95 subne r7, r7, r6 @ Undo incrmenet
96 addeq r7, r7, r6 @ Undo decrement
97 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
100 .data_arm_lateldrpreconst:
101 tst r8, #1 << 21 @ check writeback bit
102 moveq pc, lr @ no writeback -> no fixup
103 .data_arm_lateldrpostconst:
104 movs r2, r8, lsl #20 @ Get offset
105 moveq pc, lr @ zero -> no fixup
106 and r5, r8, #15 << 16 @ Extract 'n' from instruction
107 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
108 tst r8, #1 << 23 @ Check U bit
109 subne r7, r7, r2, lsr #20 @ Undo increment
110 addeq r7, r7, r2, lsr #20 @ Undo decrement
111 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
114 .data_arm_lateldrprereg:
115 tst r8, #1 << 21 @ check writeback bit
116 moveq pc, lr @ no writeback -> no fixup
117 .data_arm_lateldrpostreg:
118 and r7, r8, #15 @ Extract 'm' from instruction
119 ldr r6, [sp, r7, lsl #2] @ Get register 'Rm'
120 mov r5, r8, lsr #7 @ get shift count
122 and r7, r8, #0x70 @ get shift type
123 orreq r7, r7, #8 @ shift count = 0
127 mov r6, r6, lsl r5 @ 0: LSL #!0
128 b .data_arm_apply_r6_and_rn
129 b .data_arm_apply_r6_and_rn @ 1: LSL #0
131 b .data_unknown @ 2: MUL?
133 b .data_unknown @ 3: MUL?
135 mov r6, r6, lsr r5 @ 4: LSR #!0
136 b .data_arm_apply_r6_and_rn
137 mov r6, r6, lsr #32 @ 5: LSR #32
138 b .data_arm_apply_r6_and_rn
139 b .data_unknown @ 6: MUL?
141 b .data_unknown @ 7: MUL?
143 mov r6, r6, asr r5 @ 8: ASR #!0
144 b .data_arm_apply_r6_and_rn
145 mov r6, r6, asr #32 @ 9: ASR #32
146 b .data_arm_apply_r6_and_rn
147 b .data_unknown @ A: MUL?
149 b .data_unknown @ B: MUL?
151 mov r6, r6, ror r5 @ C: ROR #!0
152 b .data_arm_apply_r6_and_rn
153 mov r6, r6, rrx @ D: RRX
154 b .data_arm_apply_r6_and_rn
155 b .data_unknown @ E: MUL?
157 b .data_unknown @ F: MUL?
160 * Function: arm9tdmi_proc_init (void)
161 * : arm9tdmi_proc_fin (void)
163 * Notes : This processor does not require these
165 ENTRY(cpu_arm9tdmi_proc_init)
168 ENTRY(cpu_arm9tdmi_proc_fin)
169 mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
173 ENTRY(cpu_arm9tdmi_do_idle)
177 * Function: arm9tdmi_switch_mm(unsigned long pgd_phys)
178 * Params : pgd_phys Physical address of page table
179 * Purpose : Perform a task switch, saving the old processes state, and restoring
182 ENTRY(cpu_arm9tdmi_switch_mm)
186 * Function: _arm9tdmi_reset
187 * Params : r0 = address to jump to
188 * Notes : This sets up everything for a reset
190 ENTRY(cpu_arm9tdmi_reset)
195 .type __arm9tdmi_setup, #function
197 mov r0, #0x7c @ . .... .LDP WC..
199 .size __arm9tdmi_setup, . - __arm9tdmi_setup
204 * Purpose : Function pointers used to access above functions - all calls
207 .type arm9tdmi_processor_functions, #object
208 ENTRY(arm9tdmi_processor_functions)
209 .word cpu_arm9tdmi_data_abort
210 .word cpu_arm9tdmi_proc_init
211 .word cpu_arm9tdmi_proc_fin
212 .word cpu_arm9tdmi_reset
213 .word cpu_arm9tdmi_do_idle
214 .word cpu_arm9tdmi_dcache_clean_area
215 .word cpu_arm9tdmi_switch_mm
216 .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
220 .type cpu_arch_name, #object
221 cpu_arch_name: .asciz "armv4t"
222 .size cpu_arch_name, . - cpu_arch_name
224 .type cpu_elf_name, #object
225 cpu_elf_name: .asciz "v4"
226 .size cpu_elf_name, . - cpu_elf_name
228 .type cpu_arm9tdmi_name, #object
231 .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name
233 .type cpu_p2001_name, #object
236 .size cpu_p2001_name, . - cpu_p2001_name
240 .section ".proc.info.init", #alloc, #execinstr
242 .type __p2001_proc_info, #object
251 .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
253 .long arm9tdmi_processor_functions
257 .size __p2001_proc_info, . - __p2001_proc_info