diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-03-17 22:05:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-03-17 22:05:47 +0000 |
commit | 27cfca1ec98e91261b1a5355d10a8996464b63af (patch) | |
tree | 8e895a53e372fa682b4c0a585b9377d67ed70d0e /arch/arm/mm/proc-sa110.S | |
parent | 6a76fb7214c477ccf6582bd79c5b4ccc4f9c41b1 (diff) |
Look Ma' what I found on my harddisk ...
o New faster syscalls for 2.1.x, too
o Upgrade to 2.1.89.
Don't try to run this. It's flaky as hell. But feel free to debug ...
Diffstat (limited to 'arch/arm/mm/proc-sa110.S')
-rw-r--r-- | arch/arm/mm/proc-sa110.S | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S new file mode 100644 index 000000000..7d53bf230 --- /dev/null +++ b/arch/arm/mm/proc-sa110.S @@ -0,0 +1,305 @@ +/* + * linux/arch/arm/mm/sa110.S: MMU functions for SA110 + * + * (C) 1997 Russell King + * + * These are the low level assembler for performing cache and TLB + * functions on the sa110. + */ +#include <linux/linkage.h> +#include <asm/assembler.h> +#include "../lib/constants.h" + + .data +Lclean_switch: .long 0 + .text + +/* + * Function: sa110_flush_cache_all (void) + * + * Purpose : Flush all cache lines + */ + .align 5 +_sa110_flush_cache_all: @ preserves r0 + ldr r3, =Lclean_switch + ldr r2, [r3] + ands r2, r2, #1 + eor r2, r2, #1 + str r2, [r3] + ldr ip, =0xdf000000 + addne ip, ip, #32768 + add r1, ip, #16384 @ only necessary for 16k +1: ldr r2, [ip], #32 + teq r1, ip + bne 1b + mov ip, #0 + mcr p15, 0, ip, c7, c5, 0 @ flush I cache + mcr p15, 0, ip, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * Function: sa110_flush_cache_area (unsigned long address, int end, int flags) + * + * Params : address Area start address + * : end Area end address + * : flags b0 = I cache as well + * + * Purpose : clean & flush all cache lines associated with this area of memory + */ + .align 5 +_sa110_flush_cache_area: + sub r3, r1, r0 + cmp r3, #32768 + bgt _sa110_flush_cache_all +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ flush D entry + add r0, r0, #32 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ flush D entry + add r0, r0, #32 + cmp r0, r1 + blt 1b + tst r2, #1 + movne r0, #0 + mcrne p15, 0, r0, c7, c5, 0 @ flush I cache + mov pc, lr + +/* + * Function: sa110_flush_cache_entry (unsigned long address) + * + * Params : address Address of cache line to flush + * + * Purpose : clean & flush an entry + */ + .align 5 +_sa110_flush_cache_entry: + mov r1, #0 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r1, c7, c5, 0 @ flush I cache + mov pc, lr + +/* + * Function: sa110_flush_cache_pte (unsigned long address) + * + * Params : address Address of cache line to clean + * + * Purpose : Ensure that physical memory reflects cache at this location + * for page table purposes. + */ +_sa110_flush_cache_pte: + mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns) + mov pc, lr + +/* + * Function: sa110_flush_ram_page (unsigned long page) + * + * Params : address Area start address + * : size size of area + * : flags b0 = I cache as well + * + * Purpose : clean & flush all cache lines associated with this area of memory + */ + .align 5 +_sa110_flush_ram_page: + mov r1, #4096 +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ flush D entry + add r0, r0, #32 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + mcr p15, 0, r0, c7, c6, 1 @ flush D entry + add r0, r0, #32 + subs r1, r1, #64 + bne 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c7, c5, 0 @ flush I cache + mov pc, lr + +/* + * Function: sa110_flush_tlb_all (void) + * + * Purpose : flush all TLB entries in all caches + */ + .align 5 +_sa110_flush_tlb_all: + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c8, c7, 0 @ flush I & D tlbs + mov pc, lr + +/* + * Function: sa110_flush_tlb_area (unsigned long address, int end, int flags) + * + * Params : address Area start address + * : end Area end address + * : flags b0 = I cache as well + * + * Purpose : flush a TLB entry + */ + .align 5 +_sa110_flush_tlb_area: + mov r3, #0 + mcr p15, 0, r3, c7, c10, 4 @ drain WB +1: cmp r0, r1 + mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry + addlt r0, r0, #4096 + cmp r0, r1 + mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry + addlt r0, r0, #4096 + blt 1b + tst r2, #1 + mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB + mov pc, lr + + .align 5 +_sa110_flush_icache_area: + mov r3, #0 +1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry + add r0, r0, #32 + cmp r0, r1 + blt 1b + mcr p15, 0, r0, c7, c5, 0 @ flush I cache + mov pc, lr + +@LC0: .word _current +/* + * Function: sa110_switch_to (struct task_struct *prev, struct task_struct *next) + * + * Params : prev Old task structure + * : next New task structure for process to run + * + * Purpose : Perform a task switch, saving the old processes state, and restoring + * the new. + * + * Notes : We don't fiddle with the FP registers here - we postpone this until + * the new task actually uses FP. This way, we don't swap FP for tasks + * that do not require it. + */ + .align 5 +_sa110_switch_to: + stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack + mrs ip, cpsr + stmfd sp!, {ip} @ Save cpsr_SVC + str sp, [r0, #TSS_SAVE] @ Save sp_SVC + ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC + ldr r0, [r1, #ADDR_LIMIT] + teq r0, #0 + moveq r0, #KERNEL_DOMAIN + movne r0, #USER_DOMAIN + mcr p15, 0, r0, c3, c0 @ Set segment + ldr r0, [r1, #TSS_MEMMAP] @ Page table pointer + ldr r3, =Lclean_switch + ldr r2, [r3] + ands r2, r2, #1 + eor r2, r2, #1 + str r2, [r3] + ldr r2, =0xdf000000 + addne r2, r2, #32768 + add r1, r2, #16384 @ only necessary for 16k +1: ldr r3, [r2], #32 + teq r1, r2 + bne 1b + mov r1, #0 + mcr p15, 0, r1, c7, c5, 0 @ flush I cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mcr p15, 0, r0, c2, c0, 0 @ load page table pointer + mcr p15, 0, r1, c8, c7, 0 @ flush TLBs + ldmfd sp!, {ip} + msr spsr, ip @ Save tasks CPSR into SPSR for this return + ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously + +/* + * Function: sa110_data_abort () + * + * Params : r0 = address of aborted instruction + * + * Purpose : obtain information about current aborted instruction + * + * Returns : r0 = address of abort + * : r1 = FSR + * : r2 != 0 if writing + */ + .align 5 +_sa110_data_abort: + ldr r2, [r0] @ read instruction causing problem + mrc p15, 0, r0, c6, c0, 0 @ get FAR + mov r2, r2, lsr #19 @ b1 = L + and r3, r2, #0x69 << 2 + and r2, r2, #2 +// teq r3, #0x21 << 2 +// orreq r2, r2, #1 @ b0 = {LD,ST}RT + mrc p15, 0, r1, c5, c0, 0 @ get FSR + and r1, r1, #255 + mov pc, lr + +/* + * Function: sa110_set_pmd () + * + * Params : r0 = Address to set + * : r1 = value to set + * + * Purpose : Set a PMD and flush it out of any WB cache + */ + .align 5 +_sa110_set_pmd: str r1, [r0] + mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns) + mov pc, lr + +/* + * Function: sa110_check_bugs (void) + * : sa110_proc_init (void) + * : sa110_proc_fin (void) + * + * Notes : This processor does not require these + */ +_sa110_check_bugs: + mrs ip, cpsr + bic ip, ip, #F_BIT + msr cpsr, ip +_sa110_proc_init: +_sa110_proc_fin: + mov pc, lr + +/* + * Function: sa110_reset + * + * Notes : This sets up everything for a reset + */ +_sa110_reset: mrs r1, cpsr + orr r1, r1, #F_BIT | I_BIT + msr cpsr, r1 + stmfd sp!, {r1, lr} + bl _sa110_flush_cache_all + bl _sa110_flush_tlb_all + mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches + mrc p15, 0, r0, c1, c0, 0 @ ctrl register + bic r0, r0, #0x1800 + bic r0, r0, #0x000f + ldmfd sp!, {r1, pc} +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ +_sa110_name: .ascii "sa110\0" + .align + +ENTRY(sa110_processor_functions) + .word _sa110_name @ 0 + .word _sa110_switch_to @ 4 + .word _sa110_data_abort @ 8 + .word _sa110_check_bugs @ 12 + .word _sa110_proc_init @ 16 + .word _sa110_proc_fin @ 20 + + .word _sa110_flush_cache_all @ 24 + .word _sa110_flush_cache_area @ 28 + .word _sa110_flush_cache_entry @ 32 + .word _sa110_flush_cache_pte @ 36 + .word _sa110_flush_ram_page @ 40 + .word _sa110_flush_tlb_all @ 44 + .word _sa110_flush_tlb_area @ 48 + + .word _sa110_set_pmd @ 52 + .word _sa110_reset @ 54 + .word _sa110_flush_icache_area @ 58 |