2 * linux/arch/armnommu/mm/proc-lpc22xx.S
4 * Copyright (C) 1997-2000 Russell King
6 * Copyright (c) 2004 Cucy Systems (http://www.cucy.com)
7 * Curt Brune <curt@cucy.com>
8 * Modified for lpc22xx cache
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
15 #include <linux/linkage.h>
16 #include <linux/init.h>
17 #include <asm/assembler.h>
18 #include <asm/pgtable.h>
19 #include <asm/procinfo.h>
20 #include <asm/ptrace.h>
21 #include <asm/errno.h>
22 #include <asm/hardware.h>
24 ENTRY(lpc22xx_flush_user_cache_all)
25 ENTRY(lpc22xx_flush_kern_cache_all)
26 ENTRY(lpc22xx_flush_user_cache_range)
27 ENTRY(lpc22xx_coherent_kern_range)
28 ENTRY(lpc22xx_coherent_user_range)
29 ENTRY(lpc22xx_flush_kern_dcache_page)
30 ENTRY(lpc22xx_dma_inv_range)
31 ENTRY(lpc22xx_dma_flush_range)
32 ENTRY(lpc22xx_dma_clean_range)
35 ENTRY(cpu_arm7_dcache_clean_area)
39 * Function: arm6_7_data_abort ()
41 * Params : r2 = address of aborted instruction
42 * : sp = pointer to registers
44 * Purpose : obtain information about current aborted instruction
46 * Returns : r0 = address of abort
50 ENTRY(cpu_arm7_data_abort)
52 ldr r8, [r2] @ read arm instruction
53 tst r8, #1 << 20 @ L = 1 -> write?
56 orreq r1, r1, #1 << 8 @ yes.
57 add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine
60 /* 0 */ b .data_unknown
61 /* 1 */ mov pc, lr @ swp
62 /* 2 */ b .data_unknown
63 /* 3 */ b .data_unknown
64 /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m
65 /* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m]
66 /* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm
67 /* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm]
68 /* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist>
69 /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist>
70 /* a */ b .data_unknown
71 /* b */ b .data_unknown
72 /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
73 /* d */ mov pc, lr @ ldc rd, [rn, #m]
74 /* e */ b .data_unknown
76 .data_unknown: @ Part of jumptable
83 ENTRY(cpu_arm6_data_abort)
85 ldr r8, [r2] @ read arm instruction
86 tst r8, #1 << 20 @ L = 1 -> write?
87 orreq r1, r1, #1 << 8 @ yes.
89 teq r7, #8 << 24 @ was it ldm/stm
93 tst r8, #1 << 21 @ check writeback bit
94 moveq pc, lr @ no writeback -> no fixup
98 and r2, r8, r7, lsl #1
99 add r6, r6, r2, lsr #1
100 and r2, r8, r7, lsl #2
101 add r6, r6, r2, lsr #2
102 and r2, r8, r7, lsl #3
103 add r6, r6, r2, lsr #3
104 add r6, r6, r6, lsr #8
105 add r6, r6, r6, lsr #4
106 and r6, r6, #15 @ r6 = no. of registers to transfer.
107 and r5, r8, #15 << 16 @ Extract 'n' from instruction
108 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
109 tst r8, #1 << 23 @ Check U bit
110 subne r7, r7, r6, lsl #2 @ Undo increment
111 addeq r7, r7, r6, lsl #2 @ Undo decrement
112 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
115 .data_arm_apply_r6_and_rn:
116 and r5, r8, #15 << 16 @ Extract 'n' from instruction
117 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
118 tst r8, #1 << 23 @ Check U bit
119 subne r7, r7, r6 @ Undo incrmenet
120 addeq r7, r7, r6 @ Undo decrement
121 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
124 .data_arm_lateldrpreconst:
125 tst r8, #1 << 21 @ check writeback bit
126 moveq pc, lr @ no writeback -> no fixup
127 .data_arm_lateldrpostconst:
128 movs r2, r8, lsl #20 @ Get offset
129 moveq pc, lr @ zero -> no fixup
130 and r5, r8, #15 << 16 @ Extract 'n' from instruction
131 ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
132 tst r8, #1 << 23 @ Check U bit
133 subne r7, r7, r2, lsr #20 @ Undo increment
134 addeq r7, r7, r2, lsr #20 @ Undo decrement
135 str r7, [sp, r5, lsr #14] @ Put register 'Rn'
138 .data_arm_lateldrprereg:
139 tst r8, #1 << 21 @ check writeback bit
140 moveq pc, lr @ no writeback -> no fixup
141 .data_arm_lateldrpostreg:
142 and r7, r8, #15 @ Extract 'm' from instruction
143 ldr r6, [sp, r7, lsl #2] @ Get register 'Rm'
144 mov r5, r8, lsr #7 @ get shift count
146 and r7, r8, #0x70 @ get shift type
147 orreq r7, r7, #8 @ shift count = 0
151 mov r6, r6, lsl r5 @ 0: LSL #!0
152 b .data_arm_apply_r6_and_rn
153 b .data_arm_apply_r6_and_rn @ 1: LSL #0
155 b .data_unknown @ 2: MUL?
157 b .data_unknown @ 3: MUL?
159 mov r6, r6, lsr r5 @ 4: LSR #!0
160 b .data_arm_apply_r6_and_rn
161 mov r6, r6, lsr #32 @ 5: LSR #32
162 b .data_arm_apply_r6_and_rn
163 b .data_unknown @ 6: MUL?
165 b .data_unknown @ 7: MUL?
167 mov r6, r6, asr r5 @ 8: ASR #!0
168 b .data_arm_apply_r6_and_rn
169 mov r6, r6, asr #32 @ 9: ASR #32
170 b .data_arm_apply_r6_and_rn
171 b .data_unknown @ A: MUL?
173 b .data_unknown @ B: MUL?
175 mov r6, r6, ror r5 @ C: ROR #!0
176 b .data_arm_apply_r6_and_rn
177 mov r6, r6, rrx @ D: RRX
178 b .data_arm_apply_r6_and_rn
179 b .data_unknown @ E: MUL?
181 b .data_unknown @ F: MUL?
184 * Function: arm6_7_proc_init (void)
185 * : arm6_7_proc_fin (void)
187 * Notes : This processor does not require these
189 ENTRY(cpu_arm7_proc_init)
192 ENTRY(cpu_arm7_proc_fin)
193 mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
197 ENTRY(cpu_arm7_do_idle)
202 * Function: arm6_7_switch_mm(unsigned long pgd_phys)
203 * Params : pgd_phys Physical address of page table
204 * Purpose : Perform a task switch, saving the old processes state, and restoring
207 ENTRY(cpu_arm7_switch_mm)
211 * Function: _arm6_7_reset
212 * Params : r0 = address to jump to
213 * Notes : This sets up everything for a reset
215 ENTRY(cpu_arm7_reset)
221 .type __arm7_setup, #function
224 .size __arm7_setup, . - __arm7_setup
228 .type lpc22xx_cache_fns, #object
229 ENTRY(lpc22xx_cache_fns)
230 .long lpc22xx_flush_kern_cache_all
231 .long lpc22xx_flush_user_cache_all
232 .long lpc22xx_flush_user_cache_range
233 .long lpc22xx_coherent_kern_range
234 .long lpc22xx_coherent_user_range
235 .long lpc22xx_flush_kern_dcache_page
236 .long lpc22xx_dma_inv_range
237 .long lpc22xx_dma_clean_range
238 .long lpc22xx_dma_flush_range
239 .size lpc22xx_cache_fns, . - lpc22xx_cache_fns
242 * Purpose : Function pointers used to access above functions - all calls
245 .type arm7_processor_functions, #object
246 ENTRY(arm7_processor_functions)
247 .word cpu_arm7_data_abort
248 .word cpu_arm7_proc_init
249 .word cpu_arm7_proc_fin
251 .word cpu_arm7_do_idle
252 .word cpu_arm7_dcache_clean_area
253 .word cpu_arm7_switch_mm
254 .size arm7_processor_functions, . - arm7_processor_functions
258 .type cpu_arch_name, #object
259 cpu_arch_name: .asciz "armv4t"
260 .size cpu_arch_name, . - cpu_arch_name
262 .type cpu_elf_name, #object
263 cpu_elf_name: .asciz "v4"
264 .size cpu_elf_name, . - cpu_elf_name
266 .type cpu_lpc22xx, #object
268 .asciz "Philips-LPC22xx"
269 .size cpu_lpc22xx_name, . - cpu_lpc22xx_name
273 .section ".proc.info.init", #alloc, #execinstr
275 .type __lpc22xx_proc_info, #object
284 .long HWCAP_SWP | HWCAP_26BIT
285 .long cpu_lpc22xx_name
286 .long arm7_processor_functions
289 .long lpc22xx_cache_fns
290 .size __lpc22xx_proc_info, . - __lpc22xx_proc_info