MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / arm / mm / proc-s3c4510b.S
blob38a5b8426d57fdb58009d171c16e6d66f4d54c69
1 /*
2  *  linux/arch/armnommu/mm/proc-s3c4510b.S
3  *
4  *  Copyright (C) 1997-2000 Russell King
5  *
6  *  Copyright (c) 2004  Cucy Systems (http://www.cucy.com)
7  *  Curt Brune <curt@cucy.com>
8  *  Modified for s3c4510b cache
9  *  Copyright (c) 2005 Hyok S. Choi
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  *
15  */
16 #include <linux/linkage.h>
17 #include <linux/init.h>
18 #include <asm/assembler.h>
19 #include <asm/constants.h>
20 #include <asm/pgtable.h>
21 #include <asm/procinfo.h>
22 #include <asm/ptrace.h>
23 #include <asm/errno.h>
24 #include <asm/hardware.h>
25         
27  *      flush_user_cache_all()
28  *
29  *      Invalidate all cache entries in a particular address
30  *      space.
31  *
32  *      - mm    - mm_struct describing address space
33  */
34 ENTRY(s3c4510b_flush_user_cache_all)
35         /* FALLTHROUGH */
37  *      flush_kern_cache_all()
38  *
39  *      Clean and invalidate the entire cache.
40  */
41 ENTRY(s3c4510b_flush_kern_cache_all)
42         /* FALLTHROUGH */
45  *      flush_user_cache_range(start, end, flags)
46  *
47  *      Invalidate a range of cache entries in the specified
48  *      address space.
49  *
50  *      - start - start address (may not be aligned)
51  *      - end   - end address (exclusive, may not be aligned)
52  *      - flags - vma_area_struct flags describing address space
53  */
54 ENTRY(s3c4510b_flush_user_cache_range)
55         stmfd   sp!, {r5-r8, lr}
56         /* save current cache state */
57         ldr     r7, =REG_SYSCFG
58         ldr     r8, [r7]
59         /* disable cache */
60         ldr     r6, =0x83ffffa0
61         str     r6, [r7]
62         /* zero out the 1KB TAG RAM area starting @ 0x11000000 */
63         ldr     r7, =0x11000000
64         ldr     r6, =(0x11000000 + 1024)
65         ldr     r5, =0x0
66 tag_zero:               
67         str     r5, [r7]
68         add     r7, r7, #4
69         cmp     r6, r7
70         bne     tag_zero
71         
72         /* restore previoux cache state */
73         ldr     r7, =REG_SYSCFG
74         str     r8, [r7]
76         ldmfd   sp!, {r5-r8, pc}
77         
79  *      coherent_kern_range(start, end)
80  *
81  *      Ensure coherency between the Icache and the Dcache in the
82  *      region described by start.  If you have non-snooping
83  *      Harvard caches, you need to implement this function.
84  *
85  *      - start  - virtual start address
86  *      - end    - virtual end address
87  */
88 ENTRY(s3c4510b_coherent_kern_range)
89         /* FALLTHROUGH */
91                                                                                                                                            
93  *      coherent_user_range(start, end)
94  *
95  *      Ensure coherency between the Icache and the Dcache in the
96  *      region described by start, end.  If you have non-snooping
97  *      Harvard caches, you need to implement this function.
98  *
99  *      - start - virtual start address
100  *      - end   - virtual end address
101  */
102 ENTRY(s3c4510b_coherent_user_range)
105  *      flush_kern_dcache_page(void *page)
107  *      Ensure no D cache aliasing occurs, either with itself or
108  *      the I cache
110  *      - addr  - page aligned address
111  */
112 ENTRY(s3c4510b_flush_kern_dcache_page)
113         /* FALLTHROUGH */
116  *      dma_inv_range(start, end)
118  *      Invalidate (discard) the specified virtual address range.
119  *      May not write back any entries.  If 'start' or 'end'
120  *      are not cache line aligned, those lines must be written
121  *      back.
123  *      - start  - virtual start address
124  *      - end    - virtual end address
125  */
126 ENTRY(s3c4510b_dma_inv_range)
127         /* FALLTHROUGH */
130  *      dma_flush_range(start, end)
132  *      Clean and invalidate the specified virtual address range.
134  *      - start  - virtual start address
135  *      - end    - virtual end address
136  */
137 ENTRY(s3c4510b_dma_flush_range)
138         /* FALLTHROUGH */
141  *      dma_clean_range(start, end)
143  *      Clean (write back) the specified virtual address range.
145  *      - start  - virtual start address
146  *      - end    - virtual end address
147  */
148 ENTRY(s3c4510b_dma_clean_range)
149         /* FALLTHROUGH */
151 ENTRY(cpu_s3c4510b_dcache_clean_area)
152         mov     pc, lr  
155  * Function: cpu_s3c4510b_data_abort ()
157  * Params  : r2 = address of aborted instruction
158  *         : sp = pointer to registers
160  * Purpose : obtain information about current aborted instruction
162  * Returns : r0 = address of abort
163  *         : r1 = FSR
164  */
166 ENTRY(cpu_s3c4510b_data_abort)
167 @FIXME
168         ldr     r8, [r2]                        @ read arm instruction
169         tst     r8, #1 << 20                    @ L = 1 -> write?
170         and     r7, r8, #15 << 24
171         orr     r1, r7, #1
172         orreq   r1, r1, #1 << 8                 @ yes.
173         add     pc, pc, r7, lsr #22             @ Now branch to the relevant processing routine
174         nop
176 /* 0 */ b       .data_unknown
177 /* 1 */ mov     pc, lr                          @ swp
178 /* 2 */ b       .data_unknown
179 /* 3 */ b       .data_unknown
180 /* 4 */ b       .data_arm_lateldrpostconst      @ ldr   rd, [rn], #m
181 /* 5 */ b       .data_arm_lateldrpreconst       @ ldr   rd, [rn, #m]
182 /* 6 */ b       .data_arm_lateldrpostreg        @ ldr   rd, [rn], rm
183 /* 7 */ b       .data_arm_lateldrprereg         @ ldr   rd, [rn, rm]
184 /* 8 */ b       .data_arm_ldmstm                @ ldm*a rn, <rlist>
185 /* 9 */ b       .data_arm_ldmstm                @ ldm*b rn, <rlist>
186 /* a */ b       .data_unknown
187 /* b */ b       .data_unknown
188 /* c */ mov     pc, lr                          @ ldc   rd, [rn], #m    @ Same as ldr   rd, [rn], #m
189 /* d */ mov     pc, lr                          @ ldc   rd, [rn, #m]
190 /* e */ b       .data_unknown
191 /* f */
192 .data_unknown:  @ Part of jumptable
193         mov     r0, r2
194         mov     r1, r8
195         mov     r2, sp
196         bl      baddataabort
197         b       ret_from_exception
199 .data_arm_ldmstm:
200         tst     r8, #1 << 21                    @ check writeback bit
201         moveq   pc, lr                          @ no writeback -> no fixup
202         mov     r7, #0x11
203         orr     r7, r7, #0x1100
204         and     r6, r8, r7
205         and     r2, r8, r7, lsl #1
206         add     r6, r6, r2, lsr #1
207         and     r2, r8, r7, lsl #2
208         add     r6, r6, r2, lsr #2
209         and     r2, r8, r7, lsl #3
210         add     r6, r6, r2, lsr #3
211         add     r6, r6, r6, lsr #8
212         add     r6, r6, r6, lsr #4
213         and     r6, r6, #15                     @ r6 = no. of registers to transfer.
214         and     r5, r8, #15 << 16               @ Extract 'n' from instruction
215         ldr     r7, [sp, r5, lsr #14]           @ Get register 'Rn'
216         tst     r8, #1 << 23                    @ Check U bit
217         subne   r7, r7, r6, lsl #2              @ Undo increment
218         addeq   r7, r7, r6, lsl #2              @ Undo decrement
219         str     r7, [sp, r5, lsr #14]           @ Put register 'Rn'
220         mov     pc, lr
222 .data_arm_apply_r6_and_rn:
223         and     r5, r8, #15 << 16               @ Extract 'n' from instruction
224         ldr     r7, [sp, r5, lsr #14]           @ Get register 'Rn'
225         tst     r8, #1 << 23                    @ Check U bit
226         subne   r7, r7, r6                      @ Undo incrmenet
227         addeq   r7, r7, r6                      @ Undo decrement
228         str     r7, [sp, r5, lsr #14]           @ Put register 'Rn'
229         mov     pc, lr
231 .data_arm_lateldrpreconst:
232         tst     r8, #1 << 21                    @ check writeback bit
233         moveq   pc, lr                          @ no writeback -> no fixup
234 .data_arm_lateldrpostconst:
235         movs    r2, r8, lsl #20                 @ Get offset
236         moveq   pc, lr                          @ zero -> no fixup
237         and     r5, r8, #15 << 16               @ Extract 'n' from instruction
238         ldr     r7, [sp, r5, lsr #14]           @ Get register 'Rn'
239         tst     r8, #1 << 23                    @ Check U bit
240         subne   r7, r7, r2, lsr #20             @ Undo increment
241         addeq   r7, r7, r2, lsr #20             @ Undo decrement
242         str     r7, [sp, r5, lsr #14]           @ Put register 'Rn'
243         mov     pc, lr
245 .data_arm_lateldrprereg:
246         tst     r8, #1 << 21                    @ check writeback bit
247         moveq   pc, lr                          @ no writeback -> no fixup
248 .data_arm_lateldrpostreg:
249         and     r7, r8, #15                     @ Extract 'm' from instruction
250         ldr     r6, [sp, r7, lsl #2]            @ Get register 'Rm'
251         mov     r5, r8, lsr #7                  @ get shift count
252         ands    r5, r5, #31
253         and     r7, r8, #0x70                   @ get shift type
254         orreq   r7, r7, #8                      @ shift count = 0
255         add     pc, pc, r7
256         nop
258         mov     r6, r6, lsl r5                  @ 0: LSL #!0
259         b       .data_arm_apply_r6_and_rn
260         b       .data_arm_apply_r6_and_rn       @ 1: LSL #0
261         nop
262         b       .data_unknown                   @ 2: MUL?
263         nop
264         b       .data_unknown                   @ 3: MUL?
265         nop
266         mov     r6, r6, lsr r5                  @ 4: LSR #!0
267         b       .data_arm_apply_r6_and_rn
268         mov     r6, r6, lsr #32                 @ 5: LSR #32
269         b       .data_arm_apply_r6_and_rn
270         b       .data_unknown                   @ 6: MUL?
271         nop
272         b       .data_unknown                   @ 7: MUL?
273         nop
274         mov     r6, r6, asr r5                  @ 8: ASR #!0
275         b       .data_arm_apply_r6_and_rn
276         mov     r6, r6, asr #32                 @ 9: ASR #32
277         b       .data_arm_apply_r6_and_rn
278         b       .data_unknown                   @ A: MUL?
279         nop
280         b       .data_unknown                   @ B: MUL?
281         nop
282         mov     r6, r6, ror r5                  @ C: ROR #!0
283         b       .data_arm_apply_r6_and_rn
284         mov     r6, r6, rrx                     @ D: RRX
285         b       .data_arm_apply_r6_and_rn
286         b       .data_unknown                   @ E: MUL?
287         nop
288         b       .data_unknown                   @ F: MUL?
291 ENTRY(cpu_s3c4510b_proc_init)
292                 mov     pc, lr
294 ENTRY(cpu_s3c4510b_proc_fin)
295                 mov     r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
296                 msr     cpsr_c, r0
297                 mov     r0, #0
298                 mov     pc, lr
300 ENTRY(cpu_s3c4510b_do_idle)
301                 mov     r0, #-EINVAL
302                 mov     pc, lr
304 ENTRY(cpu_s3c4510b_switch_mm)
305                 mov     pc, lr
307 ENTRY(cpu_s3c4510b_reset)
308                 mov     r1, #0
309                 mov     pc, r0
312                 __INIT
314                 .type   __s3c4510b_setup, #function
315 __s3c4510b_setup:
316                 mov     r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
317                 msr     cpsr_c, r0
318                 mov     r0, #0
319                 mov     pc, lr
320                 .size   __s3c4510b_setup, . - __s3c4510b_setup
321         
322                 __INITDATA
324                 .type   s3c4510b_cache_fns, #object
325 ENTRY(s3c4510b_cache_fns)
326                 .long   s3c4510b_flush_kern_cache_all
327                 .long   s3c4510b_flush_user_cache_all
328                 .long   s3c4510b_flush_user_cache_range
329                 .long   s3c4510b_coherent_kern_range
330                 .long   s3c4510b_coherent_user_range
331                 .long   s3c4510b_flush_kern_dcache_page
332                 .long   s3c4510b_dma_inv_range
333                 .long   s3c4510b_dma_clean_range
334                 .long   s3c4510b_dma_flush_range
335                 .size   s3c4510b_cache_fns, . - s3c4510b_cache_fns
336         
338  * Purpose : Function pointers used to access above functions - all calls
339  *           come through these
340  */
341                 .type   s3c4510b_processor_functions, #object
342 ENTRY(s3c4510b_processor_functions)
343                 .word   cpu_s3c4510b_data_abort
344                 .word   cpu_s3c4510b_proc_init
345                 .word   cpu_s3c4510b_proc_fin
346                 .word   cpu_s3c4510b_reset
347                 .word   cpu_s3c4510b_do_idle
348                 .word   cpu_s3c4510b_dcache_clean_area
349                 .word   cpu_s3c4510b_switch_mm
350                 .size   s3c4510b_processor_functions, . - s3c4510b_processor_functions
352                 .section ".rodata"
354                 .type   cpu_arch_name, #object
355 cpu_arch_name:  .asciz  "armv4t"
356                 .size   cpu_arch_name, . - cpu_arch_name
358                 .type   cpu_elf_name, #object
359 cpu_elf_name:   .asciz  "v4"
360                 .size   cpu_elf_name, . - cpu_elf_name
362                 .type   cpu_s3c4510b, #object
363 cpu_s3c4510b_name:
364                 .asciz  "Samsung-S3C4510B"
365                 .size   cpu_s3c4510b_name, . - cpu_s3c4510b_name
367                 .align
369                 .section ".proc.info.init", #alloc, #execinstr
371                 .type   __s3c4510b_proc_info, #object
372 __s3c4510b_proc_info:
373                 .long   0x36807000
374                 .long   0xfffff000
375                 .long   0
376                 .long   0
377                 b       __s3c4510b_setup
378                 .long   cpu_arch_name
379                 .long   cpu_elf_name
380                 .long   HWCAP_SWP | HWCAP_26BIT
381                 .long   cpu_s3c4510b_name
382                 .long   s3c4510b_processor_functions
383                 .long   0
384                 .long   0
385                 .long   s3c4510b_cache_fns
386                 .size   __s3c4510b_proc_info, . - __s3c4510b_proc_info