Module Name: src Committed By: kiyohara Date: Sat Oct 2 05:37:59 UTC 2010
Modified Files: src/sys/arch/arm/arm: cpufunc.c src/sys/arch/arm/arm32: cpu.c src/sys/arch/arm/conf: files.arm src/sys/arch/arm/include: armreg.h cpuconf.h cpufunc.h Added Files: src/sys/arch/arm/arm: cpufunc_asm_sheeva.S Log Message: Add support Marvell Sheeva Core and SoC. (Orion/Kirkwood) Discovery Innovation not yet. To generate a diff of this commit: cvs rdiff -u -r1.100 -r1.101 src/sys/arch/arm/arm/cpufunc.c cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/arm/cpufunc_asm_sheeva.S cvs rdiff -u -r1.76 -r1.77 src/sys/arch/arm/arm32/cpu.c cvs rdiff -u -r1.99 -r1.100 src/sys/arch/arm/conf/files.arm cvs rdiff -u -r1.44 -r1.45 src/sys/arch/arm/include/armreg.h cvs rdiff -u -r1.18 -r1.19 src/sys/arch/arm/include/cpuconf.h cvs rdiff -u -r1.51 -r1.52 src/sys/arch/arm/include/cpufunc.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/arm/cpufunc.c diff -u src/sys/arch/arm/arm/cpufunc.c:1.100 src/sys/arch/arm/arm/cpufunc.c:1.101 --- src/sys/arch/arm/arm/cpufunc.c:1.100 Thu Sep 23 07:31:10 2010 +++ src/sys/arch/arm/arm/cpufunc.c Sat Oct 2 05:37:58 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.c,v 1.100 2010/09/23 07:31:10 kiyohara Exp $ */ +/* $NetBSD: cpufunc.c,v 1.101 2010/10/02 05:37:58 kiyohara Exp $ */ /* * arm7tdmi support code Copyright (c) 2001 John Fremlin @@ -49,7 +49,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.100 2010/09/23 07:31:10 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.101 2010/10/02 05:37:58 kiyohara Exp $"); #include "opt_compat_netbsd.h" #include "opt_cpuoptions.h" @@ -1141,6 +1141,63 @@ }; #endif /* CPU_CORTEX */ +#ifdef CPU_SHEEVA +struct cpu_functions sheeva_cpufuncs = { + /* CPU functions */ + + .cf_id = cpufunc_id, + .cf_cpwait = cpufunc_nullop, + + /* MMU functions */ + + .cf_control = cpufunc_control, + .cf_domains = cpufunc_domains, + .cf_setttb = armv5_ec_setttb, + .cf_faultstatus = cpufunc_faultstatus, + .cf_faultaddress = cpufunc_faultaddress, + + /* TLB functions */ + + .cf_tlb_flushID = armv4_tlb_flushID, + .cf_tlb_flushID_SE = arm10_tlb_flushID_SE, + .cf_tlb_flushI = armv4_tlb_flushI, + .cf_tlb_flushI_SE = arm10_tlb_flushI_SE, + .cf_tlb_flushD = armv4_tlb_flushD, + .cf_tlb_flushD_SE = armv4_tlb_flushD_SE, + + /* Cache operations */ + + .cf_icache_sync_all = armv5_ec_icache_sync_all, + .cf_icache_sync_range = armv5_ec_icache_sync_range, + + .cf_dcache_wbinv_all = armv5_ec_dcache_wbinv_all, + .cf_dcache_wbinv_range = sheeva_dcache_wbinv_range, + .cf_dcache_inv_range = sheeva_dcache_inv_range, + .cf_dcache_wb_range = sheeva_dcache_wb_range, + + .cf_idcache_wbinv_all = armv5_ec_idcache_wbinv_all, + .cf_idcache_wbinv_range = sheeva_idcache_wbinv_range, + + /* Other functions */ + + .cf_flush_prefetchbuf = cpufunc_nullop, + .cf_drain_writebuf = armv4_drain_writebuf, + .cf_flush_brnchtgt_C = cpufunc_nullop, + .cf_flush_brnchtgt_E = (void *)cpufunc_nullop, + + .cf_sleep = (void *)cpufunc_nullop, + + /* Soft functions */ + + .cf_dataabt_fixup = cpufunc_null_fixup, + .cf_prefetchabt_fixup = cpufunc_null_fixup, + + .cf_context_switch = arm10_context_switch, + + .cf_setup = sheeva_setup +}; +#endif /* CPU_SHEEVA */ + /* * Global constants also used by locore.s @@ -1155,7 +1212,7 @@ defined(CPU_FA526) || \ defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \ - defined(CPU_CORTEX) + defined(CPU_CORTEX) || defined(CPU_SHEEVA) static void get_cachetype_cp15(void); /* Additional cache information local to this file. Log2 of some of the @@ -1476,6 +1533,16 @@ return 0; } #endif /* CPU_ARM9E || CPU_ARM10 */ +#if defined(CPU_SHEEVA) + if (cputype == CPU_ID_MV88SV131 || + cputype == CPU_ID_MV88FR571_VD) { + cpufuncs = sheeva_cpufuncs; + cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ + get_cachetype_cp15(); + pmap_pte_init_generic(); + return 0; + } +#endif /* CPU_SHEEVA */ #ifdef CPU_ARM10 if (/* cputype == CPU_ID_ARM1020T || */ cputype == CPU_ID_ARM1020E) { @@ -2105,7 +2172,7 @@ defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \ defined(CPU_ARM10) || defined(CPU_ARM11) || defined(CPU_ARM1136) || \ - defined(CPU_FA526) || defined(CPU_CORTEX) + defined(CPU_FA526) || defined(CPU_CORTEX) || defined(CPU_SHEEVA) #define IGN 0 #define OR 1 @@ -3059,3 +3126,63 @@ } #endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 */ +#if defined(CPU_SHEEVA) +struct cpu_option sheeva_options[] = { + { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, + { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, + { "sheeva.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, + { "sheeva.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, + { "sheeva.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, + { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, + { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, + { "sheeva.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, + { NULL, IGN, IGN, 0 } +}; + +void +sheeva_setup(char *args) +{ + int cpuctrl, cpuctrlmask; + + cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE + | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE + | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; + cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE + | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE + | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE + | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE + | CPU_CONTROL_BPRD_ENABLE + | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; + +#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS + cpuctrl |= CPU_CONTROL_AFLT_ENABLE; +#endif + + cpuctrl = parse_cpu_options(args, sheeva_options, cpuctrl); + + /* + * Sheeva has L2 Cache. Enable/Disable it here. + * Really not support yet... + */ + +#ifdef __ARMEB__ + cpuctrl |= CPU_CONTROL_BEND_ENABLE; +#endif + + if (vector_page == ARM_VECTORS_HIGH) + cpuctrl |= CPU_CONTROL_VECRELOC; + + /* Clear out the cache */ + cpu_idcache_wbinv_all(); + + /* Now really make sure they are clean. */ + __asm volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); + + /* Set the control register */ + curcpu()->ci_ctrl = cpuctrl; + cpu_control(0xffffffff, cpuctrl); + + /* And again. */ + cpu_idcache_wbinv_all(); +} +#endif /* CPU_SHEEVA */ Index: src/sys/arch/arm/arm32/cpu.c diff -u src/sys/arch/arm/arm32/cpu.c:1.76 src/sys/arch/arm/arm32/cpu.c:1.77 --- src/sys/arch/arm/arm32/cpu.c:1.76 Sat Jun 19 20:42:43 2010 +++ src/sys/arch/arm/arm32/cpu.c Sat Oct 2 05:37:58 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.76 2010/06/19 20:42:43 matt Exp $ */ +/* $NetBSD: cpu.c,v 1.77 2010/10/02 05:37:58 kiyohara Exp $ */ /* * Copyright (c) 1995 Mark Brinicombe. @@ -46,7 +46,7 @@ #include <sys/param.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.76 2010/06/19 20:42:43 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.77 2010/10/02 05:37:58 kiyohara Exp $"); #include <sys/systm.h> #include <sys/malloc.h> @@ -344,6 +344,10 @@ generic_steppings }, { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", generic_steppings }, + { CPU_ID_MV88SV131, CPU_CLASS_ARM9ES, "Sheeva 88SV131", + generic_steppings }, + { CPU_ID_MV88FR571_VD, CPU_CLASS_ARM9ES, "Sheeva 88FR571-vd", + generic_steppings }, { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", generic_steppings }, @@ -605,7 +609,7 @@ #ifdef CPU_ARM9 case CPU_CLASS_ARM9TDMI: #endif -#ifdef CPU_ARM9E +#if defined(CPU_ARM9E) || defined(CPU_SHEEVA) case CPU_CLASS_ARM9ES: case CPU_CLASS_ARM9EJS: #endif Index: src/sys/arch/arm/conf/files.arm diff -u src/sys/arch/arm/conf/files.arm:1.99 src/sys/arch/arm/conf/files.arm:1.100 --- src/sys/arch/arm/conf/files.arm:1.99 Sat Jun 19 19:44:57 2010 +++ src/sys/arch/arm/conf/files.arm Sat Oct 2 05:37:58 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files.arm,v 1.99 2010/06/19 19:44:57 matt Exp $ +# $NetBSD: files.arm,v 1.100 2010/10/02 05:37:58 kiyohara Exp $ # temporary define to allow easy moving to ../arch/arm/arm32 defflag ARM32 @@ -12,6 +12,7 @@ CPU_XSCALE_80200 CPU_XSCALE_80321 CPU_XSCALE_PXA250 CPU_XSCALE_PXA270 CPU_XSCALE_IXP425 + CPU_SHEEVA defflag opt_cputypes.h CPU_ARM1136: CPU_ARM11 defflag opt_cputypes.h CPU_ARM1176: CPU_ARM11 defflag opt_cputypes.h CPU_CORTEXA8: CPU_CORTEX @@ -105,7 +106,8 @@ file arch/arm/arm/cpufunc_asm_arm7tdmi.S cpu_arm7tdmi file arch/arm/arm/cpufunc_asm_arm8.S cpu_arm8 file arch/arm/arm/cpufunc_asm_arm9.S cpu_arm9 -file arch/arm/arm/cpufunc_asm_arm10.S cpu_arm9e | cpu_arm10 +file arch/arm/arm/cpufunc_asm_arm10.S cpu_arm9e | cpu_arm10 | + cpu_sheeva file arch/arm/arm/cpufunc_asm_arm11.S cpu_arm11 | cpu_cortex file arch/arm/arm/cpufunc_asm_arm1136.S cpu_arm1136 file arch/arm/arm/cpufunc_asm_armv4.S cpu_arm9 | cpu_arm9e | @@ -120,9 +122,11 @@ cpu_xscale_ixp425 | cpu_xscale_pxa250 | cpu_xscale_pxa270 | - cpu_cortex + cpu_cortex | + cpu_sheeva file arch/arm/arm/cpufunc_asm_armv5.S cpu_arm10 -file arch/arm/arm/cpufunc_asm_armv5_ec.S cpu_arm9e | cpu_arm10 +file arch/arm/arm/cpufunc_asm_armv5_ec.S cpu_arm9e | cpu_arm10 | + cpu_sheeva file arch/arm/arm/cpufunc_asm_armv6.S cpu_arm11 | cpu_cortex file arch/arm/arm/cpufunc_asm_armv7.S cpu_cortex file arch/arm/arm/cpufunc_asm_sa1.S cpu_sa110 | cpu_sa1100 | @@ -137,6 +141,7 @@ cpu_xscale_pxa270 | cpu_cortex file arch/arm/arm/cpufunc_asm_ixp12x0.S cpu_ixp12x0 +file arch/arm/arm/cpufunc_asm_sheeva.S cpu_sheeva file arch/arm/arm/fusu.S file arch/arm/arm/idle_machdep.c file arch/arm/arm/lock_cas.S Index: src/sys/arch/arm/include/armreg.h diff -u src/sys/arch/arm/include/armreg.h:1.44 src/sys/arch/arm/include/armreg.h:1.45 --- src/sys/arch/arm/include/armreg.h:1.44 Sat Jun 19 20:42:43 2010 +++ src/sys/arch/arm/include/armreg.h Sat Oct 2 05:37:58 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: armreg.h,v 1.44 2010/06/19 20:42:43 matt Exp $ */ +/* $NetBSD: armreg.h,v 1.45 2010/10/02 05:37:58 kiyohara Exp $ */ /* * Copyright (c) 1998, 2001 Ben Harris @@ -119,6 +119,7 @@ #define CPU_ID_DEC 0x44000000 /* 'D' */ #define CPU_ID_INTEL 0x69000000 /* 'i' */ #define CPU_ID_TI 0x54000000 /* 'T' */ +#define CPU_ID_MARVELL 0x56000000 /* 'V' */ #define CPU_ID_FARADAY 0x66000000 /* 'f' */ /* How to decide what format the CPUID is in. */ @@ -205,6 +206,8 @@ #define CPU_ID_SA110 0x4401a100 #define CPU_ID_SA1100 0x4401a110 #define CPU_ID_TI925T 0x54029250 +#define CPU_ID_MV88FR571_VD 0x56155710 +#define CPU_ID_MV88SV131 0x56251310 #define CPU_ID_FA526 0x66015260 #define CPU_ID_SA1110 0x6901b110 #define CPU_ID_IXP1200 0x6901c120 @@ -315,6 +318,18 @@ #define XSCALE_AUXCTL_MD_WT 0x00000020 /* mini-D$ wt, read-allocate */ #define XSCALE_AUXCTL_MD_MASK 0x00000030 +/* Marvell Feroceon Extra Features Register (CP15 register 1, opcode2 0) */ +#define FC_DCACHE_REPL_LOCK 0x80000000 /* Replace DCache Lock */ +#define FC_DCACHE_STREAM_EN 0x20000000 /* DCache Streaming Switch */ +#define FC_WR_ALLOC_EN 0x10000000 /* Enable Write Allocate */ +#define FC_L2_PREF_DIS 0x01000000 /* L2 Cache Prefetch Disable */ +#define FC_L2_INV_EVICT_LINE 0x00800000 /* L2 Invalidates Uncorrectable Error Line Eviction */ +#define FC_L2CACHE_EN 0x00400000 /* L2 enable */ +#define FC_ICACHE_REPL_LOCK 0x00080000 /* Replace ICache Lock */ +#define FC_GLOB_HIST_REG_EN 0x00040000 /* Branch Global History Register Enable */ +#define FC_BRANCH_TARG_BUF_DIS 0x00020000 /* Branch Target Buffer Disable */ +#define FC_L1_PAR_ERR_EN 0x00010000 /* L1 Parity Error Enable */ + /* Cache type register definitions 0 */ #define CPU_CT_FORMAT(x) (((x) >> 29) & 0x7) /* reg format */ #define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */ Index: src/sys/arch/arm/include/cpuconf.h diff -u src/sys/arch/arm/include/cpuconf.h:1.18 src/sys/arch/arm/include/cpuconf.h:1.19 --- src/sys/arch/arm/include/cpuconf.h:1.18 Sat Jun 19 19:44:58 2010 +++ src/sys/arch/arm/include/cpuconf.h Sat Oct 2 05:37:58 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuconf.h,v 1.18 2010/06/19 19:44:58 matt Exp $ */ +/* $NetBSD: cpuconf.h,v 1.19 2010/10/02 05:37:58 kiyohara Exp $ */ /* * Copyright (c) 2002 Wasabi Systems, Inc. @@ -81,7 +81,8 @@ defined(CPU_XSCALE_80200) + \ defined(CPU_XSCALE_80321) + \ defined(__CPU_XSCALE_PXA2XX) + \ - defined(CPU_XSCALE_IXP425)) + defined(CPU_XSCALE_IXP425)) + \ + defined(CPU_SHEEVA)) #else #define CPU_NTYPES 2 #endif /* _KERNEL_OPT */ @@ -116,7 +117,8 @@ #if !defined(_KERNEL_OPT) || \ (defined(CPU_ARM9E) || defined(CPU_ARM10) || \ defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ - defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425)) + defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425)) || \ + defined(CPU_SHEEVA) #define ARM_ARCH_5 1 #else #define ARM_ARCH_5 0 @@ -177,7 +179,7 @@ #if !defined(_KERNEL_OPT) || \ (defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) || \ defined(CPU_ARM8) || defined(CPU_ARM9) || defined(CPU_ARM9E) || \ - defined(CPU_ARM10) || defined(CPU_FA526)) + defined(CPU_ARM10) || defined(CPU_FA526)) || defined(CPU_SHEEVA) #define ARM_MMU_GENERIC 1 #else #define ARM_MMU_GENERIC 0 Index: src/sys/arch/arm/include/cpufunc.h diff -u src/sys/arch/arm/include/cpufunc.h:1.51 src/sys/arch/arm/include/cpufunc.h:1.52 --- src/sys/arch/arm/include/cpufunc.h:1.51 Sat Jun 19 19:44:58 2010 +++ src/sys/arch/arm/include/cpufunc.h Sat Oct 2 05:37:58 2010 @@ -365,7 +365,7 @@ extern unsigned arm9_dcache_index_inc; #endif -#if defined(CPU_ARM9E) || defined(CPU_ARM10) +#if defined(CPU_ARM9E) || defined(CPU_ARM10) || defined(CPU_SHEEVA) void arm10_tlb_flushID_SE (u_int); void arm10_tlb_flushI_SE (u_int); @@ -374,7 +374,7 @@ void arm10_setup (char *); #endif -#if defined(CPU_ARM9E) || defined (CPU_ARM10) +#if defined(CPU_ARM9E) || defined (CPU_ARM10) || defined(CPU_SHEEVA) void armv5_ec_setttb (u_int); void armv5_ec_icache_sync_all (void); @@ -481,7 +481,7 @@ defined(CPU_FA526) || \ defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \ - defined(CPU_CORTEX) + defined(CPU_CORTEX) || defined(CPU_SHEEVA) void armv4_tlb_flushID (void); void armv4_tlb_flushI (void); @@ -541,6 +541,14 @@ void xscale_setup (char *); #endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 || CPU_CORTEX */ +#if defined(CPU_SHEEVA) +void sheeva_dcache_wbinv_range (vaddr_t, vsize_t); +void sheeva_dcache_inv_range (vaddr_t, vsize_t); +void sheeva_dcache_wb_range (vaddr_t, vsize_t); +void sheeva_idcache_wbinv_range (vaddr_t, vsize_t); +void sheeva_setup(char *); +#endif + #define tlb_flush cpu_tlb_flushID #define setttb cpu_setttb #define drain_writebuf cpu_drain_writebuf Added files: Index: src/sys/arch/arm/arm/cpufunc_asm_sheeva.S diff -u /dev/null src/sys/arch/arm/arm/cpufunc_asm_sheeva.S:1.1 --- /dev/null Sat Oct 2 05:37:59 2010 +++ src/sys/arch/arm/arm/cpufunc_asm_sheeva.S Sat Oct 2 05:37:58 2010 @@ -0,0 +1,216 @@ +/*- + * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. + * All rights reserved. + * + * Developed by Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of MARVELL nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/cpu.h> +#include <machine/asm.h> +#include <arm/arm32/vmparam.h> + +.Lsheeva_cache_line_size: + .word _C_LABEL(arm_pdcache_line_size) +.Lsheeva_asm_page_mask: + .word _C_LABEL(PAGE_MASK) + +ENTRY(sheeva_dcache_wbinv_range) + str lr, [sp, #-4]! + mrs lr, cpsr + /* Start with cache line aligned address */ + ldr ip, .Lsheeva_cache_line_size + ldr ip, [ip] + sub ip, ip, #1 + and r2, r0, ip + add r1, r1, r2 + add r1, r1, ip + bics r1, r1, ip + bics r0, r0, ip + + ldr ip, .Lsheeva_asm_page_mask + and r2, r0, ip + rsb r2, r2, #PAGE_SIZE + cmp r1, r2 + movcc ip, r1 + movcs ip, r2 +1: + add r3, r0, ip + sub r2, r3, #1 + /* Disable irqs */ + orr r3, lr, #I32_bit | F32_bit + msr cpsr_c, r3 + mcr p15, 5, r0, c15, c15, 0 /* Clean and inv zone start address */ + mcr p15, 5, r2, c15, c15, 1 /* Clean and inv zone end address */ + /* Enable irqs */ + msr cpsr_c, lr + + add r0, r0, ip + sub r1, r1, ip + cmp r1, #PAGE_SIZE + movcc ip, r1 + movcs ip, #PAGE_SIZE + cmp r1, #0 + bne 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + ldr lr, [sp], #4 + RET + +ENTRY(sheeva_dcache_inv_range) + str lr, [sp, #-4]! + mrs lr, cpsr + /* Start with cache line aligned address */ + ldr ip, .Lsheeva_cache_line_size + ldr ip, [ip] + sub ip, ip, #1 + and r2, r0, ip + add r1, r1, r2 + add r1, r1, ip + bics r1, r1, ip + bics r0, r0, ip + + ldr ip, .Lsheeva_asm_page_mask + and r2, r0, ip + rsb r2, r2, #PAGE_SIZE + cmp r1, r2 + movcc ip, r1 + movcs ip, r2 +1: + add r3, r0, ip + sub r2, r3, #1 + /* Disable irqs */ + orr r3, lr, #I32_bit | F32_bit + msr cpsr_c, r3 + mcr p15, 5, r0, c15, c14, 0 /* Inv zone start address */ + mcr p15, 5, r2, c15, c14, 1 /* Inv zone end address */ + /* Enable irqs */ + msr cpsr_c, lr + + add r0, r0, ip + sub r1, r1, ip + cmp r1, #PAGE_SIZE + movcc ip, r1 + movcs ip, #PAGE_SIZE + cmp r1, #0 + bne 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + ldr lr, [sp], #4 + RET + +ENTRY(sheeva_dcache_wb_range) + str lr, [sp, #-4]! + mrs lr, cpsr + /* Start with cache line aligned address */ + ldr ip, .Lsheeva_cache_line_size + ldr ip, [ip] + sub ip, ip, #1 + and r2, r0, ip + add r1, r1, r2 + add r1, r1, ip + bics r1, r1, ip + bics r0, r0, ip + + ldr ip, .Lsheeva_asm_page_mask + and r2, r0, ip + rsb r2, r2, #PAGE_SIZE + cmp r1, r2 + movcc ip, r1 + movcs ip, r2 +1: + add r3, r0, ip + sub r2, r3, #1 + /* Disable irqs */ + orr r3, lr, #I32_bit | F32_bit + msr cpsr_c, r3 + mcr p15, 5, r0, c15, c13, 0 /* Clean zone start address */ + mcr p15, 5, r2, c15, c13, 1 /* Clean zone end address */ + /* Enable irqs */ + msr cpsr_c, lr + + add r0, r0, ip + sub r1, r1, ip + cmp r1, #PAGE_SIZE + movcc ip, r1 + movcs ip, #PAGE_SIZE + cmp r1, #0 + bne 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + ldr lr, [sp], #4 + RET + +ENTRY(sheeva_idcache_wbinv_range) + str lr, [sp, #-4]! + mrs lr, cpsr + /* Start with cache line aligned address */ + ldr ip, .Lsheeva_cache_line_size + ldr ip, [ip] + sub ip, ip, #1 + and r2, r0, ip + add r1, r1, r2 + add r1, r1, ip + bics r1, r1, ip + bics r0, r0, ip + + ldr ip, .Lsheeva_asm_page_mask + and r2, r0, ip + rsb r2, r2, #PAGE_SIZE + cmp r1, r2 + movcc ip, r1 + movcs ip, r2 +1: + add r3, r0, ip + sub r2, r3, #1 + /* Disable irqs */ + orr r3, lr, #I32_bit | F32_bit + msr cpsr_c, r3 + mcr p15, 5, r0, c15, c15, 0 /* Clean and inv zone start address */ + mcr p15, 5, r2, c15, c15, 1 /* Clean and inv zone end address */ + /* Enable irqs */ + msr cpsr_c, lr + + /* Invalidate and clean icache line by line */ + ldr r3, .Lsheeva_cache_line_size + ldr r3, [r3] +2: + mcr p15, 0, r0, c7, c5, 1 + add r0, r0, r3 + cmp r2, r0 + bhi 2b + + add r0, r2, #1 + sub r1, r1, ip + cmp r1, #PAGE_SIZE + movcc ip, r1 + movcs ip, #PAGE_SIZE + cmp r1, #0 + bne 1b + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */ + ldr lr, [sp], #4 + RET