2 * linux/arch/arm26/mm/proc-arm2,3.S
4 * Copyright (C) 1997-1999 Russell King
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * MMU functions for ARM2,3
12 * These are the low level assembler for performing cache
13 * and memory functions on ARM2, ARM250 and ARM3 processors.
15 #include <linux/linkage.h>
16 #include <asm/assembler.h>
17 #include <asm/asm-offsets.h>
18 #include <asm/procinfo.h>
19 #include <asm/ptrace.h>
22 * MEMC workhorse code. It's both a horse which things it's a pig.
25 * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
26 * Params : pgd Page tables/MEMC mapping
27 * : phys_pte physical address, or PTE
28 * : addr virtual address
30 ENTRY(cpu_memc_update_entry)
31 tst r1, #PAGE_PRESENT @ is the page present
32 orreq r1, r1, #PAGE_OLD | PAGE_CLEAN
34 mov r3, r1, lsr #13 @ convert to physical page nr
36 adr ip, memc_phys_table_32
38 tst r1, #PAGE_OLD | PAGE_NOT_USER
40 tsteq r1, #PAGE_READONLY | PAGE_CLEAN
42 mov r2, r2, lsr #15 @ virtual -> nr
43 orr r3, r3, r2, lsl #15
45 orr r3, r3, r2, lsl #2
48 str r3, [r0, r2, lsl #2]
52 * Params : r0 = preserved
53 * : r1 = memc table base (preserved)
54 * : r2 = page table entry
57 * : r5 = memc physical address translation table
58 * : ip = virtual address (preserved)
63 ldr r4, [r5, r4] @ covert to MEMC page
65 tst r2, #PAGE_OLD | PAGE_NOT_USER @ check for MEMC read
67 tsteq r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write
71 and r2, ip, #0x01800000
72 orr r4, r4, r2, lsr #13
75 str r4, [r1, r2, lsl #2]
79 * Params : r0 = preserved
80 * : r1 = memc table base (preserved)
81 * : r2 = page table base
84 * : r5 = memc physical address translation table
85 * : ip = virtual address (updated)
90 1: ldr r2, [r0], #4 @ get entry
91 tst r2, #PAGE_PRESENT @ page present
92 blne update_pte @ process pte
93 add ip, ip, #32768 @ increment virt addr
94 ldr r2, [r0], #4 @ get entry
95 tst r2, #PAGE_PRESENT @ page present
96 blne update_pte @ process pte
97 add ip, ip, #32768 @ increment virt addr
98 ldr r2, [r0], #4 @ get entry
99 tst r2, #PAGE_PRESENT @ page present
100 blne update_pte @ process pte
101 add ip, ip, #32768 @ increment virt addr
102 ldr r2, [r0], #4 @ get entry
103 tst r2, #PAGE_PRESENT @ page present
104 blne update_pte @ process pte
105 add ip, ip, #32768 @ increment virt addr
106 tst ip, #32768 * 31 @ finished?
111 * Function: cpu_memc_update_all(pgd_t *pgd)
112 * Params : pgd Page tables/MEMC mapping
113 * Notes : this is optimised for 32k pages
115 ENTRY(cpu_memc_update_all)
116 stmfd sp!, {r4, r5, lr}
118 sub r1, r0, #256 * 4 @ start of MEMC tables
119 adr r5, memc_phys_table_32 @ Convert to logical page number
120 mov ip, #0 @ virtual address
121 1: ldmia r0!, {r2, r3} @ load two pgd entries
122 tst r2, #PAGE_PRESENT @ is pgd entry present?
123 addeq ip, ip, #1048576 @FIXME - PAGE_PRESENT is for PTEs technically...
124 blne update_pte_table
126 tst r2, #PAGE_PRESENT @ is pgd entry present?
127 addeq ip, ip, #1048576
128 blne update_pte_table
129 teq ip, #32 * 1048576
131 ldmfd sp!, {r4, r5, pc}^
134 * Build the table to map from physical page number to memc page number
136 .type memc_phys_table_32, #object
147 .long 0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
157 .size memc_phys_table_32, . - memc_phys_table_32
160 * helper for cpu_memc_update_all, this clears out all
161 * mappings, setting them close to the top of memory,
162 * and inaccessible (0x01f00000).
163 * Params : r0 = page table pointer
165 clear_tables: ldr r1, _arm3_set_pgd - 4
167 sub r1, r0, #256 * 4 @ start of MEMC tables
168 add r2, r1, r2, lsl #2 @ end of tables
169 mov r3, #0x03f00000 @ Default mapping (null mapping)
170 orr r3, r3, #0x00000f00
174 1: stmia r1!, {r3, r4, r5, ip}
179 stmia r1!, {r3, r4, r5, ip}
189 * Function: *_set_pgd(pgd_t *pgd)
190 * Params : pgd New page tables/MEMC mapping
191 * Purpose : update MEMC hardware with new mapping
193 .word page_nr @ extern - declared in mm-memc.c
194 _arm3_set_pgd: mcr p15, 0, r1, c1, c0, 0 @ flush cache
195 _arm2_set_pgd: stmfd sp!, {lr}
196 ldr r1, _arm3_set_pgd - 4
198 sub r0, r0, #256 * 4 @ start of MEMC tables
199 add r1, r0, r2, lsl #2 @ end of tables
200 1: ldmia r0!, {r2, r3, ip, lr}
205 ldmia r0!, {r2, r3, ip, lr}
215 * Function: *_proc_init (void)
216 * Purpose : Initialise the cache control registers
220 orr r0, r0, #0x0000ff00
221 orr r0, r0, #0x000000ff
222 mcr p15, 0, r0, c3, c0 @ ARM3 Cacheable
223 mcr p15, 0, r0, c4, c0 @ ARM3 Updateable
225 mcr p15, 0, r0, c5, c0 @ ARM3 Disruptive
226 mcr p15, 0, r0, c1, c0 @ ARM3 Flush
228 mcr p15, 0, r0, c2, c0 @ ARM3 Control
233 * Function: *_proc_fin (void)
234 * Purpose : Finalise processor (disable caches)
236 _arm3_proc_fin: mov r0, #2
237 mcr p15, 0, r0, c2, c0
238 _arm2_proc_fin: orrs pc, lr, #PSR_I_BIT|PSR_F_BIT
241 * Function: *_xchg_1 (int new, volatile void *ptr)
242 * Params : new New value to store at...
243 * : ptr pointer to byte-wide location
244 * Purpose : Performs an exchange operation
245 * Returns : Original byte data at 'ptr'
247 _arm2_xchg_1: mov r2, pc
248 orr r2, r2, #PSR_I_BIT
255 _arm3_xchg_1: swpb r0, r0, [r1]
259 * Function: *_xchg_4 (int new, volatile void *ptr)
260 * Params : new New value to store at...
261 * : ptr pointer to word-wide location
262 * Purpose : Performs an exchange operation
263 * Returns : Original word data at 'ptr'
265 _arm2_xchg_4: mov r2, pc
266 orr r2, r2, #PSR_I_BIT
273 _arm3_xchg_4: swp r0, r0, [r1]
277 bics pc, lr, #PSR_F_BIT @ Clear FIQ disable bit
279 armvlsi_name: .asciz "ARM/VLSI"
280 _arm2_name: .asciz "ARM 2"
281 _arm250_name: .asciz "ARM 250"
282 _arm3_name: .asciz "ARM 3"
284 .section ".init.text", #alloc, #execinstr
286 * Purpose : Function pointers used to access above functions - all calls
289 .globl arm2_processor_functions
290 arm2_processor_functions:
291 .word _arm2_3_check_bugs
292 .word _arm2_proc_init
302 .globl arm250_processor_functions
303 arm250_processor_functions:
304 .word _arm2_3_check_bugs
305 .word _arm2_proc_init
315 .globl arm3_processor_functions
316 arm3_processor_functions:
317 .word _arm2_3_check_bugs
318 .word _arm3_proc_init
328 arm2_arch_name: .asciz "armv1"
329 arm3_arch_name: .asciz "armv2"
330 arm2_elf_name: .asciz "v1"
331 arm3_elf_name: .asciz "v2"
334 .section ".proc.info", #alloc, #execinstr
342 .long arm2_processor_functions
349 .long cpu_arm250_info
350 .long arm250_processor_functions
358 .long arm3_processor_functions