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