www.pudn.com > mizi_vivi.rar > proc-xscale.S
/* * proc-xscale.S * * Copyright (C) 2001 MIZI Research, Inc. * * Author: Yong-iL Joh* Date : $Date: 2002/08/02 02:02:12 $ * * $Revision: 1.6 $ * Mon May 23 2002 Yong-iL Joh - initial based on bootldr-sa11x0.S * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. */ #include "config.h" #include "asm-pxa.h" #include "machine.h" /* * This is the maximum size of an area which will be flushed. If the area * is larger than this, then we flush the whole cache */ #define MAX_AREA_SIZE 32768 /* * the cache line size of the I and D cache */ #define CACHELINESIZE 32 /* * the size of the data cache */ #define CACHESIZE 32768 /* * and the page size */ #define PAGESIZE 4096 /* * Virtual address used to allocate the cache when flushed * * This must be an address range which is _never_ used. It should * apparently have a mapping in the corresponding page table for * compatibility with future CPUs that _could_ require it. For instance we * don't care. * * This must be aligned on a 2*CACHESIZE boundary. The code selects one of * the 2 areas in alternance each time the clean_d_cache macro is used. * Without this the XScale core exhibits cache eviction problems and no one * knows why. * * Reminder: the vector table is located at 0xffff0000-0xffff0fff. */ #define CLEAN_ADDR 0xfffe0000 /* * This macro is used to wait for a CP15 write and is needed * when we have to ensure that the last operation to the co-pro * was completed before continuing with operation. */ .macro cpwait, rd mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 mov \rd, \rd @ wait for completion sub pc, pc, #4 @ flush instruction pipeline .endm .macro cpwait_ret, lr, rd mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 sub pc, \lr, \rd, LSR #32 @ wait for completion and @ flush instruction pipeline .endm /* * This macro cleans the entire dcache using line allocate. * The main loop has been unrolled to reduce loop overhead. * rd and rs are two scratch registers. */ .macro clean_d_cache, rd, rs ldr \rs, =clean_addr ldr \rd, [\rs] eor \rd, \rd, #CACHESIZE str \rd, [\rs] add \rs, \rd, #CACHESIZE 1: mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line add \rd, \rd, #CACHELINESIZE mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line add \rd, \rd, #CACHELINESIZE mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line add \rd, \rd, #CACHELINESIZE mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line add \rd, \rd, #CACHELINESIZE teq \rd, \rs bne 1b .endm .macro clean_d_line, rd mcr p15, 0, \rd, c7, c10, 1 .endm .data clean_addr: .word CLEAN_ADDR .text /* * cpu_xscale_reset(loc) * * Perform a soft reset of the system. Put the CPU into the * same state as it would be if it had been reset, and branch * to what would be the reset vector. * * loc: location to jump to for soft reset */ .align 5 ENTRY(cpu_xscale_reset) mov r1, #F_BIT|I_BIT|SVC_MODE msr cpsr_c, r1 @ reset CPSR mrc p15, 0, r1, c1, c0, 0 @ ctrl register bic r1, r1, #0x0086 @ ........B....CA. bic r1, r1, #0x1900 @ ...IZ..S........ mcr p15, 0, r1, c1, c0, 0 @ ctrl register mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB bic r1, r1, #0x0001 @ ...............M mcr p15, 0, r1, c1, c0, 0 @ ctrl register @ CAUTION: MMU turned off from this point. We count on the pipeline @ already containing those two last instructions to survive. mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs mov pc, r0 /* ================================= CACHE ================================ */ /* * cpu_xscale_cache_clean_invalidate_all (void) * * clean and invalidate all cache lines * * Note: * 1. We should preserve r0 at all times. * 2. Even if this function implies cache "invalidation" by its name, * we don't need to actually use explicit invalidation operations * since the goal is to discard all valid references from the cache * and the cleaning of it already has that effect. * 3. Because of 2 above and the fact that kernel space memory is always * coherent across task switches there is no need to worry about * inconsistencies due to interrupts, ence no irq disabling. */ .align 5 ENTRY(cpu_xscale_cache_clean_invalidate_all) mov r2, #1 cpu_xscale_cache_clean_invalidate_all_r2: clean_d_cache r0, r1 teq r2, #0 mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer mov pc, lr /* ================================== TLB ================================= */ /* * cpu_xscale_tlb_invalidate_all() * * Invalidate all TLB entries */ .align 5 ENTRY(cpu_xscale_tlb_invalidate_all) mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs cpwait_ret lr, ip mov pc,lr ENTRY(__xscale_setup) mov r0, #F_BIT|I_BIT|SVC_MODE msr cpsr_c, r0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs ldr r4, DW_MMU_TABLE mcr p15, 0, r4, c2, c0, 0 @ load page table pointer mvn r0, #0 @ Domains 0, 1 = client mcr p15, 0, r0, c3, c0, 0 @ load domain access register mov r0, #1 @ Allow user space to access mcr p15, 0, r0, c15, c1, 0 @ ... CP 0 only. @#if CACHE_WRITE_THROUGH @ mov r0, #0x20 @#else mov r0, #0x00 @#endif mcr p15, 0, r0, c1, c1, 0 @ set auxiliary control reg mrc p15, 0, r0, c1, c0, 0 @ get control register bic r0, r0, #0x0200 @ ......R......... bic r0, r0, #0x0082 @ ........B.....A. orr r0, r0, #0x0005 @ .............C.M orr r0, r0, #0x3900 @ ..VIZ..S........ @#ifdef CONFIG_XSCALE_CACHE_ERRATA bic r0, r0, #0x0004 @ see cpu_xscale_proc_init @#endif @ Enable MMU mcr p15, 0, r0, c1, c0, 0 mov pc, lr /* ;; ******************************************************************** ;; Data Area ;; ******************************************************************** */ .align 2 DW_MMU_TABLE: .word MMU_TABLE_BASE