Index: arch/arm/arm/cpufunc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm/cpufunc.c,v
retrieving revision 1.94
diff -u -r1.94 cpufunc.c
--- arch/arm/arm/cpufunc.c	27 Dec 2009 05:14:56 -0000	1.94
+++ arch/arm/arm/cpufunc.c	14 May 2010 13:16:55 -0000
@@ -7,6 +7,7 @@
  * arm9 support code Copyright (C) 2001 ARM Ltd
  * arm11 support code Copyright (c) 2007 Microsoft
  * cortexa8 support code Copyright (c) 2008 3am Software Foundry
+ * cortexa8 improvements Copyright (c) Goeran Weinholt
  * Copyright (c) 1997 Mark Brinicombe.
  * Copyright (c) 1997 Causality Limited
  * All rights reserved.
@@ -98,7 +99,7 @@
 int	arm_pdcache_size;	/* and unified */
 int	arm_pdcache_line_size;
 int	arm_pdcache_ways;
-#if (ARM_MMU_V6) != 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) != 0
 int	arm_cache_prefer_mask;
 #endif
  
@@ -1080,6 +1081,67 @@
 #endif
 /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 */
 
+#if defined(CPU_CORTEXA8)
+struct cpu_functions cortexa8_cpufuncs = {
+	/* CPU functions */
+
+	.cf_id			= cpufunc_id,
+	.cf_cpwait		= cpufunc_nullop, 	
+
+	/* MMU functions */
+
+	.cf_control		= cpufunc_control,
+	.cf_domains		= cpufunc_domains,
+	.cf_setttb		= armv7_setttb,
+	.cf_faultstatus		= cpufunc_faultstatus,
+	.cf_faultaddress	= cpufunc_faultaddress,
+
+	/* TLB functions */
+
+	.cf_tlb_flushID		= arm11_tlb_flushID,
+	.cf_tlb_flushID_SE	= armv7_tlb_flushID_SE,
+	.cf_tlb_flushI		= arm11_tlb_flushI,
+	.cf_tlb_flushI_SE	= arm11_tlb_flushI_SE,
+	.cf_tlb_flushD		= arm11_tlb_flushD,
+	.cf_tlb_flushD_SE	= arm11_tlb_flushD_SE,
+
+	/* Cache operations */
+
+	.cf_icache_sync_all	= armv7_icache_sync_all,
+	.cf_dcache_wbinv_all	= armv7_dcache_wbinv_all,
+
+	.cf_dcache_inv_range	= armv7_dcache_inv_range,
+	.cf_dcache_wb_range	= armv7_dcache_wb_range,
+	.cf_dcache_wbinv_range	= armv7_dcache_wbinv_range,
+
+	.cf_icache_sync_range	= armv7_icache_sync_range, 
+	.cf_idcache_wbinv_range = armv7_idcache_wbinv_range,
+
+
+	.cf_idcache_wbinv_all	= armv7_idcache_wbinv_all,
+
+	/* Other functions */
+
+	.cf_flush_prefetchbuf	= cpufunc_nullop,
+	.cf_drain_writebuf	= arm11_drain_writebuf,
+	.cf_flush_brnchtgt_C	= cpufunc_nullop,
+	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
+
+	.cf_sleep		= armv7_cpu_sleep,
+
+	/* Soft functions */
+
+	.cf_dataabt_fixup	= cpufunc_null_fixup,
+	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
+
+	.cf_context_switch	= armv7_context_switch,
+
+	.cf_setup		= armv7_setup
+
+};
+#endif /* CPU_CORTEXA8 */
+
+
 /*
  * Global constants also used by locore.s
  */
@@ -1092,7 +1154,8 @@
     defined(CPU_ARM9E) || defined(CPU_ARM10) || defined(CPU_ARM11) || \
     defined(CPU_FA526) || \
     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_CORTEXA8)
 static void get_cachetype_cp15(void);
 
 /* Additional cache information local to this file.  Log2 of some of the
@@ -1101,6 +1164,24 @@
 static int	arm_dcache_l2_assoc;
 static int	arm_dcache_l2_linesize;
 
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
+static inline u_int
+get_cachesize_cp15(int cssr)
+{
+    u_int csid;
+
+#if (CPU_CORTEXA8) > 0
+    __asm volatile("mcr p15, 2, %0, c0, c0, 0" :: "r" (cssr));
+    /* GAS does not have the ISB instruction ATM */
+    __asm volatile(".word 0xF57FF06F;"); /* sync to the new cssr */
+#else
+    __asm volatile("mcr p15, 1, %0, c0, c0, 2" :: "r" (cssr));
+#endif
+    __asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (csid));
+    return csid;
+}
+#endif
+
 static void
 get_cachetype_cp15()
 {
@@ -1120,15 +1201,13 @@
 	if (ctype == cpu_id())
 		goto out;
 
-#if (ARM_MMU_V6) > 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
 	if (CPU_CT_FORMAT(ctype) == 4) { 
 		u_int csid1, csid2;
 		isize = 1U << (CPU_CT4_ILINE(ctype) + 2);
 		dsize = 1U << (CPU_CT4_DLINE(ctype) + 2);
 
-		__asm volatile("mcr p15, 1, %0, c0, c0, 2"
-		    :: "r" (CPU_CSSR_L1));	/* select L1 cache values */
-		__asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (csid1));
+		csid1 = get_cachesize_cp15(CPU_CSSR_L1); /* select L1 cache values */
 		arm_pdcache_ways = CPU_CSID_ASSOC(csid1) + 1;
 		arm_pdcache_line_size = dsize << CPU_CSID_LEN(csid1);
 		arm_pdcache_size = arm_pdcache_line_size * arm_pdcache_ways;
@@ -1137,9 +1216,7 @@
 
 		arm_dcache_align = arm_pdcache_line_size;
 
-		__asm volatile("mcr p15, 1, %0, c0, c0, 2"
-		    :: "r" (CPU_CSSR_L2));	/* select L2 cache values */
-		__asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (csid2));
+		csid2 = get_cachesize_cp15(CPU_CSSR_L2); /* select L2 cache values */
 		arm_dcache_l2_assoc = CPU_CSID_ASSOC(csid2) + 1;
 		arm_dcache_l2_linesize = dsize << CPU_CSID_LEN(csid2);
 		arm_dcache_l2_nsets = CPU_CSID_NUMSETS(csid2) + 1;
@@ -1169,7 +1246,7 @@
 		} else {
 			arm_picache_ways = multiplier <<
 			    (CPU_CT_xSIZE_ASSOC(isize) - 1);
-#if (ARM_MMU_V6) > 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
 			if (CPU_CT_xSIZE_P & isize)
 				arm_cache_prefer_mask |=
 				    __BIT(9 + CPU_CT_xSIZE_SIZE(isize)
@@ -1191,7 +1268,7 @@
 	} else {
 		arm_pdcache_ways = multiplier <<
 		    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
-#if (ARM_MMU_V6) > 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
 		if (CPU_CT_xSIZE_P & dsize)
 			arm_cache_prefer_mask |=
 			    __BIT(9 + CPU_CT_xSIZE_SIZE(dsize)
@@ -1412,9 +1489,7 @@
 #if defined(CPU_ARM11)
 	if (cputype == CPU_ID_ARM1136JS ||
 	    cputype == CPU_ID_ARM1136JSR1 ||
-	    cputype == CPU_ID_ARM1176JS ||
-	    cputype == CPU_ID_CORTEXA8R1 ||
-	    cputype == CPU_ID_CORTEXA8R2) {
+	    cputype == CPU_ID_ARM1176JS) {
 		cpufuncs = arm11_cpufuncs;
 #if defined(CPU_ARM1136)
 		if (cputype != CPU_ID_ARM1176JS) {
@@ -1618,6 +1693,21 @@
 		return 0;
 	}
 #endif /* CPU_XSCALE_IXP425 */
+#if defined(CPU_CORTEXA8)
+	if (cputype == CPU_ID_CORTEXA8R1 ||
+	    cputype == CPU_ID_CORTEXA8R2 ||
+	    cputype == CPU_ID_CORTEXA8R3) {
+		cpufuncs = cortexa8_cpufuncs;
+		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
+		cpu_do_powersave = 1;			/* Enable powersave */
+		get_cachetype_cp15();
+		pmap_pte_init_armv7();
+		if (arm_cache_prefer_mask)
+			uvmexp.ncolors = (arm_cache_prefer_mask >> PGSHIFT) + 1;
+
+		return 0;
+	}
+#endif /* CPU_CORTEXA8 */
 	/*
 	 * Bzzzz. And the answer was ...
 	 */
@@ -2004,7 +2094,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_FA526) || defined(CPU_CORTEXA8)
 
 #define IGN	0
 #define OR	1
@@ -2393,7 +2483,7 @@
 }
 #endif	/* CPU_ARM9E || CPU_ARM10 */
 
-#if defined(CPU_ARM11)
+#if defined(CPU_ARM11) 
 struct cpu_option arm11_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) },
@@ -2456,6 +2546,104 @@
 }
 #endif	/* CPU_ARM11 */
 
+#if defined(CPU_CORTEXA8)
+struct cpu_option armv7_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) },
+    { "armv7.cache",    BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
+    { "armv7.icache",   BIC, OR,  CPU_CONTROL_IC_ENABLE },
+    { "armv7.dcache",   BIC, OR,  CPU_CONTROL_DC_ENABLE },
+	{ NULL, 			IGN, IGN, 0}
+};
+
+void
+armv7_setup(args)
+	char *args;
+{
+	int cpuctrl, cpuctrlmask;
+
+#if defined(PROCESS_ID_IS_CURCPU)
+	/* set curcpu() */
+        __asm("mcr\tp15, 0, %0, c13, c0, 4" : : "r"(&cpu_info_store)); 
+#elif defined(PROCESS_ID_IS_CURLWP)
+	/* set curlwp() */
+        __asm("mcr\tp15, 0, %0, c13, c0, 4" : : "r"(&lwp0)); 
+#endif
+
+	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_IC_ENABLE
+	    | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_BPRD_ENABLE ;
+	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
+	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
+	    | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BPRD_ENABLE
+	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
+	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
+
+#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
+	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
+#endif
+
+	cpuctrl = parse_cpu_options(args, armv7_options, cpuctrl);
+
+#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();
+	/* set some cortrol register? */
+}
+
+/* Clean the data cache to the level of coherency. Slow. */
+void
+armv7_dcache_wbinv_all()
+{
+	u_int clidr, loc, level;
+
+	/* Cache Level ID Register */
+	__asm volatile("mrc\tp15, 1, %0, c0, c0, 1" : "=r" (clidr));
+
+	loc = (clidr >> 24) & 7; /* Level of Coherency */
+
+	for (level = 0; level <= loc; level++) {
+		u_int ctype, csid;
+		int line_size, ways, nsets, wayshift, setshift;
+
+		ctype = (clidr >> (level * 3)) & 7;
+		/* We're supposed to stop when ctype == 0, but we
+		 * trust that loc isn't larger than necesssary. */
+		if (ctype < 2) continue; /* no cache / only icache */
+
+		csid = get_cachesize_cp15(level << 1);
+		line_size = CPU_CSID_LEN(csid);
+		ways = CPU_CSID_ASSOC(csid);
+		nsets = (csid >> 13) & 0x7fff;
+
+		wayshift = __builtin_clz(ways); /* leading zeros */
+		setshift = line_size + 4;
+
+		for (; nsets >= 0; nsets--) {
+			int way;
+
+			for (way = ways; way >= 0; way--) {
+				/* Clean by set/way */
+				u_int sw = (way << wayshift) | (nsets << setshift) |
+					(level << 1);
+
+				__asm volatile("mcr\tp15, 0, %0, c7, c10, 2" :: "r"(sw));
+			}
+		}
+	}
+
+	__asm volatile("mcr\tp15, 0, r0, c7, c10, 4"); /* DSB */
+	__asm volatile(".word 0xF57FF06F;");	       /* ISB */
+}
+#endif /* CPU_CORTEXA8 */
+
+
+
 #if defined(CPU_ARM1136)
 void
 arm1136_setup(char *args)
@@ -2777,7 +2965,7 @@
 #endif /* CPU_IXP12X0 */
 
 #if 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_CORTEXA8)
 struct cpu_option xscale_options[] = {
 #ifdef COMPAT_12
 	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
@@ -2854,3 +3042,4 @@
 		: : "r" (auxctl));
 }
 #endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 */
+
Index: arch/arm/arm/cpufunc_asm_armv7.S
===================================================================
RCS file: arch/arm/arm/cpufunc_asm_armv7.S
diff -N arch/arm/arm/cpufunc_asm_armv7.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/arm/arm/cpufunc_asm_armv7.S	14 May 2010 13:16:55 -0000
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 2010 Per Odlund <per.odlund@armagedon.se>
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION 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.
+ */
+
+/* ARMv7 assembly functions for manipulating caches and other core functions.
+ * Based on cpufuncs for v6 and xscale.
+ */
+
+#include "assym.h"
+#include <machine/cpu.h>
+#include <machine/asm.h>
+
+#define ISB .word 0xF57FF06F;
+#define DMB .word 0xF57FF05F;
+#define DSB .word 0xF57FF04F;
+#define WFI .word 0xC320F003;
+
+#define DCACHE_SIZE		0x00008000
+
+#define entrysize		#32
+
+
+ENTRY(armv7_cpu_sleep)
+    tst r0, #0x00000000 			@shouldn't sleep 0
+    WFI 
+    RET
+
+ENTRY(armv7_wait)
+    mrc p15, 0, r0, c2, c0, 0  /* arbitrary read of CP15 */
+    add r0, r0, #0			   /* a stall */
+    RET
+
+ENTRY(armv7_context_switch)
+    mcr p15, 0, r0, c7, c10, 4  /* drain the write buffer */
+    mcr p15, 0, r0, c2, c0, 0 	/* set the new TTB */
+    mcr p15, 0, r0, c8, c7, 0	/* flush the I+D */
+    RET
+
+ENTRY(armv7_tlb_flushID_SE)
+    mcr p15, 0, r0, c8, c7, 1	/* flush I+D tlb single entry */
+    mcr p15, 0, r0, c7, c10, 4  /* drain write buffer */
+    RET
+
+
+ENTRY(armv7_setttb)
+/* Does this even exist on armv7? */
+#ifdef PMAP_CACHE_VIVT
+    stmdb	sp!, {r0, lr}
+    bl _C_LABEL(armv7_idcache_wbinv_all) 	/* Clean the D cache */
+    ldmia	sp!, {r0, lr}
+#endif
+
+    mcr p15, 0, r0, c2, c0, 0   /* load new TTB */
+    mcr p15, 0, r0, c8, c7, 0   /* invalidate I+D TLBs */
+    mcr p15, 0, r0, c7, c10, 4  /* drain the write buffer */
+
+    RET
+
+/* Cache operations. */
+
+/* LINTSTUB: void armv7_icache_sync_range(vaddr_t, vsize_t); */
+ENTRY_NP(armv7_icache_sync_range)
+1:
+    mcr p15, 0, r0, c7, c5, 1		@invalidate the I-Cache line
+    mcr p15, 0, r0, c7, c10, 1		@wb the D-Cache line
+    add r0, r0, entrysize
+    subs r1, r1, entrysize
+    bhi 1b
+
+    mcr p15, 0, r0, c7, c10, 4  	@drain the write buffer, BSB 
+    RET
+
+/* LINTSTUB: void armv7_icache_sync_all(void); */
+ENTRY_NP(armv7_icache_sync_all)
+    /*
+     * We assume that the code here can never be out of sync with the
+     * dcache, so that we can safely flush the Icache and fall through
+     * into the Dcache cleaning code.
+     */
+    stmdb	sp!, {r0, lr}
+    bl _C_LABEL(armv7_idcache_wbinv_all) 	/* Clean the D cache */
+    ldmia	sp!, {r0, lr}
+    mcr p15, 0, r0, c7, c10, 4  			/* drain the write buffer, BSB */
+    RET
+
+ENTRY(armv7_dcache_wb_range)
+1:
+    mcr p15, 0, r0, c7, c10, 1		@wb the D-Cache
+    add r0, r0, entrysize
+    subs r1, r1, entrysize
+    bhi 1b
+    mcr p15, 0, r0, c7, c10, 4  	@drain the write buffer, BSB 
+    RET
+
+/* LINTSTUB: void armv7_dcache_wbinv_range(vaddr_t, vsize_t); */
+ENTRY(armv7_dcache_wbinv_range)
+1:
+    mcr p15, 0, r0, c7, c14, 1		@wb and inv the D-Cache line
+    add r0, r0, entrysize
+    subs r1, r1, entrysize
+    bhi 1b
+    mcr p15, 0, r0, c7, c10, 4  	@drain the write buffer, BSB 
+    RET
+
+/* * LINTSTUB: void armv7_dcache_inv_range(vaddr_t, vsize_t); */
+ENTRY(armv7_dcache_inv_range)
+1:
+    mcr	p15, 0, r0, c7, c6, 1		@invalidate the D-Cache line  
+    add r0, r0, entrysize 
+    subs r1, r1, entrysize
+    bhi 1b
+    mcr p15, 0, r0, c7, c10, 4  	@drain the write buffer, BSB 
+    RET
+
+
+ENTRY(armv7_idcache_wbinv_range)
+1:
+    mcr p15, 0, r0, c7, c5, 1		@invalidate the I-Cache line
+    mcr p15, 0, r0, c7, c14, 1 		@wb and inv the D-Cache line
+    add r0, r0, entrysize
+    subs r1, r1, entrysize
+    bhi 1b
+    mcr p15, 0, r0, c7, c10, 4  	@drain the write buffer, BSB 
+    RET
+
+ENTRY_NP(armv7_idcache_wbinv_all)
+    /*
+     * We assume that the code here can never be out of sync with the
+     * dcache, so that we can safely flush the Icache and fall through
+     * into the Dcache purging code.
+     */
+    DMB
+    mcr p15, 0, r0, c7, c5, 0
+    b _C_LABEL(armv7_dcache_wbinv_all)
+
+/*
+ * armv7_dcache_wbinv_all is in cpufunc.c. It's really too long to
+ * write in assembler.
+ */
Index: arch/arm/arm32/cortexa8_pmc.c
===================================================================
RCS file: arch/arm/arm32/cortexa8_pmc.c
diff -N arch/arm/arm32/cortexa8_pmc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/arm/arm32/cortexa8_pmc.c	14 May 2010 13:16:56 -0000
@@ -0,0 +1,149 @@
+/* Copyright (c) 2007 Microsoft
+ * All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by Microsoft
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
+ * 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.
+ */
+
+
+/*
+ * support for ARM cortexa8 Performance Monitor Counters
+ * based on arm11_pmc.c
+ */
+
+#include <sys/cdefs.h>
+/* __KERNEL_RCSID(0, "$NetBSD: cortexa8_pmc.c,v 1.3 2008/07/03 06:12:02 matt Exp $"); */
+#include "opt_perfctrs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>  
+#include <sys/time.h>
+#include <sys/timetc.h>
+#include <dev/clock_subr.h>
+#include <arm/armreg.h>
+#include <arm/cpufunc.h>
+
+#ifndef CORTEXA8_PMC_CCNT_HZ
+# define CORTEXA8_PMC_CCNT_HZ	400000000	/* 400MHz */
+#endif
+
+void cortexa8_pmc_ccnt_init(void);
+
+#define COUNTS_PER_USEC	(CORTEXA8_PMC_CCNT_HZ / 1000000)
+
+static uint32_t counts_per_wrap = ~0UL;		/* XXX off by 1 */
+
+#define PMNC "c9, c12, 0"
+#define CCNT "c9, c13, 0"
+
+static inline uint32_t
+cortexa8_pmc_ctrl_read(void)
+{
+	uint32_t val;
+
+	__asm volatile ("mrc p15, 0, %0, " PMNC : "=r" (val));
+
+	return val;
+}
+
+static inline void
+cortexa8_pmc_ctrl_write(uint32_t val)
+{
+	__asm volatile ("mcr p15, 0, %0, " PMNC :: "r" (val));
+}
+
+static inline uint32_t
+cortexa8_pmc_ccnt_read(void)
+{
+	uint32_t val;
+
+	__asm volatile ("mrc p15, 0, %0, " CCNT : "=r" (val));
+
+	return val;
+}
+
+static inline void
+cortexa8_pmc_ccnt_write(uint32_t val)
+{
+  __asm volatile ("mcr p15, 0, %0, c9, c12, 2"  :: "r" (CORTEXA8_CNTENC_C));
+  __asm volatile ("mcr p15, 0, %0, " CCNT :: "r" (val));
+  __asm volatile ("mcr p15, 0, %0, c9, c12, 1" :: "r" (CORTEXA8_CNTENS_C));
+}
+
+/*
+ * enable the PMC CCNT for delay()
+ */
+void
+cortexa8_pmc_ccnt_init(void)
+{
+  uint32_t val;
+  
+  val = ARM11_PMCCTL_E | ARM11_PMCCTL_P | ARM11_PMCCTL_C;
+	
+  cortexa8_pmc_ctrl_write(val);
+  __asm volatile ("mcr p15, 0, %0, c9, c12, 1" :: "r" (CORTEXA8_CNTENS_C));
+}
+
+/*
+ * delay - for "at least" arg usec
+ *
+ *	NOTE: at 400MHz we are restricted to (uint32_t)~0 "counts"
+ *	if this is a problem, accumulate counts in LL vars
+ */
+#define DELAY_ARG_LIMIT (((uint32_t)~0) / COUNTS_PER_USEC)	/* about 10 sec */
+void
+delay(u_int arg)
+{
+	uint32_t ctrl;
+	uint32_t cur;
+	uint32_t last;
+	uint32_t delta = 0;
+	uint32_t usecs = 0;
+
+	if (arg > DELAY_ARG_LIMIT)
+		panic("delay: arg %u overflow, limit is %d usec\n", arg, DELAY_ARG_LIMIT);
+
+	last = cortexa8_pmc_ccnt_read();
+	delta = usecs = 0;
+	while (arg > usecs) {
+		cur  = cortexa8_pmc_ccnt_read();
+		
+		/* overflow flag is moved to a separate register
+		   and is not read from PMC Control Register */
+		__asm volatile ("mrc p15, 0, %0, c9, c12, 3" : "=r" (ctrl));
+		if(ctrl & CORTEXA8_CNTOFL_C){
+		  /* Reset overflow flag for cycle counter in overflow register */
+		  __asm volatile ("mcr p15, 0, %0, c9, c12, 3" :: "r" (CORTEXA8_CNTOFL_C));
+		  delta += (last + (counts_per_wrap - cur));
+		} else {
+			delta += (cur - last);
+		}
+		last = cur;
+		if (delta >= COUNTS_PER_USEC) {
+			usecs += delta / COUNTS_PER_USEC;
+			delta %= COUNTS_PER_USEC;
+		}
+	}
+}
Index: arch/arm/arm32/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/cpu.c,v
retrieving revision 1.72
diff -u -r1.72 cpu.c
--- arch/arm/arm32/cpu.c	23 Jan 2010 15:58:13 -0000	1.72
+++ arch/arm/arm32/cpu.c	14 May 2010 13:16:56 -0000
@@ -410,6 +410,8 @@
 	  pN_steppings },
 	{ CPU_ID_CORTEXA8R2,	CPU_CLASS_ARM11J,	"Cortex-A8 r2",
 	  pN_steppings },
+	{ CPU_ID_CORTEXA8R3,	CPU_CLASS_ARM11J,	"Cortex-A8 r3",
+	  pN_steppings },
 
 	{ CPU_ID_FA526,		CPU_CLASS_ARMV4,	"FA526",
 	  generic_steppings },
Index: arch/arm/arm32/db_interface.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/db_interface.c,v
retrieving revision 1.47
diff -u -r1.47 db_interface.c
--- arch/arm/arm32/db_interface.c	14 Mar 2009 15:36:01 -0000	1.47
+++ arch/arm/arm32/db_interface.c	14 May 2010 13:16:56 -0000
@@ -248,7 +248,7 @@
 			pgva = (vaddr_t)dst & L1_S_FRAME;
 			limit = L1_S_SIZE - ((vaddr_t)dst & L1_S_OFFSET);
 
-			tmppde = oldpde | L1_S_PROT_W;
+			tmppde = l1pte_set_writable(oldpde);
 			*pde = tmppde;
 			PTE_SYNC(pde);
 			break;
@@ -260,7 +260,7 @@
 			if (pte == NULL)
 				goto no_mapping;
 			oldpte = *pte;
-			tmppte = oldpte | L2_S_PROT_W;
+			tmppte = l2pte_set_writable(oldpte);
 			*pte = tmppte;
 			PTE_SYNC(pte);
 			break;
Index: arch/arm/arm32/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/pmap.c,v
retrieving revision 1.212
diff -u -r1.212 pmap.c
--- arch/arm/arm32/pmap.c	15 Feb 2010 07:55:33 -0000	1.212
+++ arch/arm/arm32/pmap.c	14 May 2010 13:16:56 -0000
@@ -2219,7 +2219,7 @@
 					pv->pv_flags &= ~PVF_NC;
 				}
 			} else
-			if (opte & L2_S_PROT_W) {
+			if (l2pte_writable_p(opte)) {
 				/* 
 				 * Entry is writable/cacheable: check if pmap
 				 * is current if it is flush it, otherwise it
@@ -2237,7 +2237,7 @@
 #endif
 
 			/* make the pte read only */
-			npte &= ~L2_S_PROT_W;
+			npte = l2pte_set_readonly(npte);
 
 			if (maskbits & oflags & PVF_WRITE) {
 				/*
@@ -2836,7 +2836,7 @@
 			 * - The physical page has already been referenced
 			 *   so no need to re-do referenced emulation here.
 			 */
-			npte |= L2_S_PROTO;
+			npte |= l2pte_set_readonly(L2_S_PROTO);
 
 			nflags |= PVF_REF;
 
@@ -2849,7 +2849,7 @@
 				 * already been modified. Make it
 				 * writable from the outset.
 				 */
-				npte |= L2_S_PROT_W;
+				npte = l2pte_set_writable(npte);
 				nflags |= PVF_MOD;
 			}
 		} else {
@@ -2878,7 +2878,7 @@
 			 */
 			if (pm->pm_cstate.cs_cache_d &&
 			    (oflags & PVF_NC) == 0 &&
-			    (opte & L2_S_PROT_W) != 0 &&
+			    l2pte_writeable_p(opte) &&
 			    (prot & VM_PROT_WRITE) == 0)
 				cpu_dcache_wb_range(va, PAGE_SIZE);
 #endif
@@ -2941,9 +2941,9 @@
 		 * These are always readable, and possibly writable, from
 		 * the get go as we don't need to track ref/mod status.
 		 */
-		npte |= L2_S_PROTO;
+		npte |= l2pte_set_readonly(L2_S_PROTO);
 		if (prot & VM_PROT_WRITE)
-			npte |= L2_S_PROT_W;
+			npte = l2pte_set_writable(npte);
 
 		/*
 		 * Make sure the vector table is mapped cacheable
@@ -3604,7 +3604,7 @@
 
 		while (sva < next_bucket) {
 			pte = *ptep;
-			if (l2pte_valid(pte) != 0 && (pte & L2_S_PROT_W) != 0) {
+			if (l2pte_valid(pte) != 0 && l2pte_writable_p(pte)) {
 				struct vm_page *pg;
 				u_int f;
 
@@ -3619,7 +3619,7 @@
 #endif
 
 				pg = PHYS_TO_VM_PAGE(l2pte_pa(pte));
-				pte &= ~L2_S_PROT_W;
+				pte = l2pte_set_readonly(pte);
 				*ptep = pte;
 				PTE_SYNC(ptep);
 
@@ -3843,7 +3843,7 @@
 
 	pa = l2pte_pa(pte);
 
-	if ((ftype & VM_PROT_WRITE) && (pte & L2_S_PROT_W) == 0) {
+	if ((ftype & VM_PROT_WRITE) && !l2pte_writable_p(pte)) {
 		/*
 		 * This looks like a good candidate for "page modified"
 		 * emulation...
@@ -3898,7 +3898,7 @@
 		 * changing. We've already set the cacheable bits based on
 		 * the assumption that we can write to this page.
 		 */
-		*ptep = (pte & ~L2_TYPE_MASK) | L2_S_PROTO | L2_S_PROT_W;
+		*ptep = l2pte_set_writable((pte & ~L2_TYPE_MASK) | L2_S_PROTO);
 		PTE_SYNC(ptep);
 		rv = 1;
 	} else
@@ -3931,7 +3931,7 @@
 		    printf("pmap_fault_fixup: ref emul. pm %p, va 0x%08lx, pa 0x%08lx\n",
 		    pm, va, VM_PAGE_TO_PHYS(pg)));
 
-		*ptep = (pte & ~L2_TYPE_MASK) | L2_S_PROTO;
+		*ptep = l2pte_set_readonly((pte & ~L2_TYPE_MASK) | L2_S_PROTO);
 		PTE_SYNC(ptep);
 		rv = 1;
 	}
@@ -4358,7 +4358,7 @@
 	mutex_exit(&pm->pm_lock);
 }
 
-#if ARM_MMU_V6 > 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
 
 static struct evcnt pmap_prefer_nochange_ev =
     EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "pmap prefer", "nochange");
@@ -4383,7 +4383,7 @@
 		*vap = va + diff;
 	}
 }
-#endif /* ARM_MMU_V6 */
+#endif /* ARM_MMU_V6 | ARM_MMU_V7 */
 
 /*
  * pmap_zero_page()
@@ -4393,7 +4393,7 @@
  * StrongARM accesses to non-cached pages are non-burst making writing
  * _any_ bulk data very slow.
  */
-#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0
+#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6 + ARM_MMU_V7) != 0
 void
 pmap_zero_page_generic(paddr_t phys)
 {
@@ -4574,7 +4574,7 @@
  * hook points. The same comment regarding cachability as in
  * pmap_zero_page also applies here.
  */
-#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0
+#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6 + ARM_MMU_V7) != 0
 void
 pmap_copy_page_generic(paddr_t src, paddr_t dst)
 {
@@ -5885,10 +5885,21 @@
 pt_entry_t	pte_l2_s_cache_mode_pt;
 pt_entry_t	pte_l2_s_cache_mask;
 
+pt_entry_t	pte_l1_s_prot_u;
+pt_entry_t	pte_l1_s_prot_w;
+pt_entry_t	pte_l1_s_prot_ro;
+pt_entry_t	pte_l1_s_prot_mask;
+
 pt_entry_t	pte_l2_s_prot_u;
 pt_entry_t	pte_l2_s_prot_w;
+pt_entry_t	pte_l2_s_prot_ro;
 pt_entry_t	pte_l2_s_prot_mask;
 
+pt_entry_t	pte_l2_l_prot_u;
+pt_entry_t	pte_l2_l_prot_w;
+pt_entry_t	pte_l2_l_prot_ro;
+pt_entry_t	pte_l2_l_prot_mask;
+
 pt_entry_t	pte_l1_s_proto;
 pt_entry_t	pte_l1_c_proto;
 pt_entry_t	pte_l2_s_proto;
@@ -5896,7 +5907,7 @@
 void		(*pmap_copy_page_func)(paddr_t, paddr_t);
 void		(*pmap_zero_page_func)(paddr_t);
 
-#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0
+#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6 + ARM_MMU_V7) != 0
 void
 pmap_pte_init_generic(void)
 {
@@ -5931,10 +5942,21 @@
 #endif
 	}
 
+	pte_l1_s_prot_u = L1_S_PROT_U_generic;
+	pte_l1_s_prot_w = L1_S_PROT_W_generic;
+	pte_l1_s_prot_ro = L1_S_PROT_RO_generic;
+	pte_l1_s_prot_mask = L1_S_PROT_MASK_generic;
+
 	pte_l2_s_prot_u = L2_S_PROT_U_generic;
 	pte_l2_s_prot_w = L2_S_PROT_W_generic;
+	pte_l2_s_prot_ro = L2_S_PROT_RO_generic;
 	pte_l2_s_prot_mask = L2_S_PROT_MASK_generic;
 
+	pte_l2_l_prot_u = L2_L_PROT_U_generic;
+	pte_l2_l_prot_w = L2_L_PROT_W_generic;
+	pte_l2_l_prot_ro = L2_L_PROT_RO_generic;
+	pte_l2_l_prot_mask = L2_L_PROT_MASK_generic;
+
 	pte_l1_s_proto = L1_S_PROTO_generic;
 	pte_l1_c_proto = L1_C_PROTO_generic;
 	pte_l2_s_proto = L2_S_PROTO_generic;
@@ -6129,10 +6151,21 @@
 	xscale_use_minidata = 1;
 #endif
 
+	pte_l1_s_prot_u = L1_S_PROT_U_xscale;
+	pte_l1_s_prot_w = L1_S_PROT_W_xscale;
+	pte_l1_s_prot_ro = L1_S_PROT_RO_xscale;
+	pte_l1_s_prot_mask = L1_S_PROT_MASK_xscale;
+
 	pte_l2_s_prot_u = L2_S_PROT_U_xscale;
 	pte_l2_s_prot_w = L2_S_PROT_W_xscale;
+	pte_l2_s_prot_ro = L2_S_PROT_RO_xscale;
 	pte_l2_s_prot_mask = L2_S_PROT_MASK_xscale;
 
+	pte_l2_l_prot_u = L2_L_PROT_U_xscale;
+	pte_l2_l_prot_w = L2_L_PROT_W_xscale;
+	pte_l2_l_prot_ro = L2_L_PROT_RO_xscale;
+	pte_l2_l_prot_mask = L2_L_PROT_MASK_xscale;
+
 	pte_l1_s_proto = L1_S_PROTO_xscale;
 	pte_l1_c_proto = L1_C_PROTO_xscale;
 	pte_l2_s_proto = L2_S_PROTO_xscale;
@@ -6254,6 +6287,43 @@
 }
 #endif /* ARM_MMU_XSCALE == 1 */
 
+#if ARM_MMU_V7 == 1
+void
+pmap_pte_init_armv7(void)
+{
+	/*
+	 * The ARMv7-A MMU is mostly compatible with generic. If the
+	 * AP field is zero, that now means "no access" rather than
+	 * read-only. The prototypes are a little different because of
+	 * the XN bit.
+	 */
+	pmap_pte_init_generic();
+
+	pte_l1_s_cache_mask = L1_S_CACHE_MASK_armv7;
+	pte_l2_l_cache_mask = L2_L_CACHE_MASK_armv7;
+	pte_l2_s_cache_mask = L2_S_CACHE_MASK_armv7;
+
+	pte_l1_s_prot_u = L1_S_PROT_U_armv7;
+	pte_l1_s_prot_w = L1_S_PROT_W_armv7;
+	pte_l1_s_prot_ro = L1_S_PROT_RO_armv7;
+	pte_l1_s_prot_mask = L1_S_PROT_MASK_armv7;
+
+	pte_l2_s_prot_u = L2_S_PROT_U_armv7;
+	pte_l2_s_prot_w = L2_S_PROT_W_armv7;
+	pte_l2_s_prot_ro = L2_S_PROT_RO_armv7;
+	pte_l2_s_prot_mask = L2_S_PROT_MASK_armv7;
+
+	pte_l2_l_prot_u = L2_L_PROT_U_armv7;
+	pte_l2_l_prot_w = L2_L_PROT_W_armv7;
+	pte_l2_l_prot_ro = L2_L_PROT_RO_armv7;
+	pte_l2_l_prot_mask = L2_L_PROT_MASK_armv7;
+
+	pte_l1_s_proto = L1_S_PROTO_armv7;
+	pte_l1_c_proto = L1_C_PROTO_armv7;
+	pte_l2_s_proto = L2_S_PROTO_armv7;
+}
+#endif /* ARM_MMU_V7 */
+
 /*
  * return the PA of the current L1 table, for use when handling a crash dump
  */
Index: arch/arm/conf/files.arm
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/conf/files.arm,v
retrieving revision 1.97
diff -u -r1.97 files.arm
--- arch/arm/conf/files.arm	27 Dec 2009 05:14:56 -0000	1.97
+++ arch/arm/conf/files.arm	14 May 2010 13:16:56 -0000
@@ -11,10 +11,10 @@
 				CPU_FA526
 				CPU_XSCALE_80200 CPU_XSCALE_80321
 				CPU_XSCALE_PXA250 CPU_XSCALE_PXA270
-				CPU_XSCALE_IXP425
+				CPU_XSCALE_IXP425 
+				CPU_CORTEXA8
 defflag	opt_cputypes.h		CPU_ARM1136: CPU_ARM11
 defflag	opt_cputypes.h		CPU_ARM1176: CPU_ARM11
-defflag	opt_cputypes.h		CPU_CORTEXA8: CPU_ARM11
 defflag opt_cputypes.h		FPU_VFP
 
 defparam opt_cpuoptions.h	XSCALE_CCLKCFG
@@ -27,6 +27,7 @@
 defflag  opt_cpuoptions.h	PROCESS_ID_IS_CURLWP
 defflag  opt_cpuoptions.h	PROCESS_ID_IS_CURCPU
 defflag  opt_cpuoptions.h	ARM11_PMC
+defflag  opt_cpuoptions.h	CORTEXA8_PMC
 defflag  opt_cpuoptions.h	ARM11_CACHE_WRITE_THROUGH
 
 # Interrupt implementation header definition.
@@ -105,7 +106,7 @@
 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_arm11.S	cpu_arm11
+file	arch/arm/arm/cpufunc_asm_arm11.S	cpu_arm11 | cpu_cortexa8
 file	arch/arm/arm/cpufunc_asm_arm1136.S	cpu_arm1136
 file	arch/arm/arm/cpufunc_asm_armv4.S	cpu_arm9 | cpu_arm9e |
 							cpu_arm10 |
@@ -118,11 +119,14 @@
 							cpu_xscale_80321 |
 							cpu_xscale_ixp425 |
 							cpu_xscale_pxa250 |
-							cpu_xscale_pxa270
+							cpu_xscale_pxa270 |
+							cpu_cortexa8
 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_armv6.S	cpu_arm11
+file	arch/arm/arm/cpufunc_asm_armv6.S	cpu_arm11 | cpu_cortexa8
+file	arch/arm/arm/cpufunc_asm_armv7.S	cpu_cortexa8
 makeoptions	cpu_arm11	"AOPTS.cpufunc_asm_armv6.S"+="-Wa,-march=armv6"
+makeoptions	cpu_cortexa8	"AOPTS.cpufunc_asm_armv6.S"+="-Wa,-march=armv6"
 file	arch/arm/arm/cpufunc_asm_sa1.S		cpu_sa110 | cpu_sa1100 |
 							cpu_sa1110 |
 							cpu_ixp12x0
@@ -132,7 +136,8 @@
 						    cpu_xscale_80321 |
 						    cpu_xscale_ixp425 |
 						    cpu_xscale_pxa250 |
-						    cpu_xscale_pxa270
+						    cpu_xscale_pxa270 |
+						    cpu_cortexa8
 file	arch/arm/arm/cpufunc_asm_ixp12x0.S	cpu_ixp12x0
 file	arch/arm/arm/fusu.S
 file	arch/arm/arm/idle_machdep.c
@@ -167,6 +172,7 @@
 # files less common to arm32 implementations...
 file	kern/kern_cctr.c			arm11
 file	arch/arm/arm32/arm11_pmc.c		arm11_pmc
+file	arch/arm/arm32/cortexa8_pmc.c		cortexa8_pmc
 
 # arm32 library functions
 file	arch/arm/arm32/bcopy_page.S		arm32
Index: arch/arm/include/armreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/armreg.h,v
retrieving revision 1.41
diff -u -r1.41 armreg.h
--- arch/arm/include/armreg.h	27 Aug 2008 11:04:23 -0000	1.41
+++ arch/arm/include/armreg.h	14 May 2010 13:16:57 -0000
@@ -200,6 +200,7 @@
 #define CPU_ID_ARM1176JS	0x410fb760
 #define CPU_ID_CORTEXA8R1	0x411fc080
 #define CPU_ID_CORTEXA8R2	0x412fc080
+#define CPU_ID_CORTEXA8R3	0x413fc080
 #define CPU_ID_SA110		0x4401a100
 #define CPU_ID_SA1100		0x4401a110
 #define	CPU_ID_TI925T		0x54029250
@@ -446,4 +447,9 @@
 #define	ARM11_PMCEVT_RETURN_MISS	38	/* return addr. mispredicted */
 #define	ARM11_PMCEVT_CYCLE		255	/* Increment each cycle */
 
+/* Defines for ARM CORTEXA8 performance counters */
+#define CORTEXA8_CNTENS_C __BIT(31) /* Enables the cycle counter */
+#define CORTEXA8_CNTENC_C __BIT(31) /* Disables the cycle counter */
+#define CORTEXA8_CNTOFL_C __BIT(31)  /* Cycle counter overflow flag */
+
 #endif	/* _ARM_ARMREG_H */
Index: arch/arm/include/cpuconf.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/cpuconf.h,v
retrieving revision 1.16
diff -u -r1.16 cpuconf.h
--- arch/arm/include/cpuconf.h	27 Feb 2009 03:57:41 -0000	1.16
+++ arch/arm/include/cpuconf.h	14 May 2010 13:16:57 -0000
@@ -119,7 +119,7 @@
 #define	ARM_ARCH_5	0
 #endif
 
-#if defined(CPU_ARM11)
+#if defined(CPU_ARM11) || defined(CPU_CORTEXA8)
 #define ARM_ARCH_6	1
 #else
 #define ARM_ARCH_6	0
@@ -197,8 +197,16 @@
 #define	ARM_MMU_V6		0
 #endif
 
+#if !defined(_KERNEL_OPT) ||						\
+	 defined(CPU_CORTEXA8)
+#define	ARM_MMU_V7		1
+#else
+#define	ARM_MMU_V7		0
+#endif
+
 #define	ARM_NMMUS		(ARM_MMU_MEMC + ARM_MMU_GENERIC +	\
-				 ARM_MMU_SA1 + ARM_MMU_XSCALE + ARM_MMU_V6)
+				 ARM_MMU_SA1 + ARM_MMU_XSCALE +		\
+				 ARM_MMU_V6 + ARM_MMU_V7)
 #if ARM_NMMUS == 0
 #error ARM_NMMUS is 0
 #endif
Index: arch/arm/include/cpufunc.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/cpufunc.h,v
retrieving revision 1.49
diff -u -r1.49 cpufunc.h
--- arch/arm/include/cpufunc.h	21 Oct 2008 19:01:54 -0000	1.49
+++ arch/arm/include/cpufunc.h	14 May 2010 13:16:57 -0000
@@ -409,7 +409,7 @@
 extern unsigned armv5_dcache_index_inc;
 #endif
 
-#if defined(CPU_ARM11)
+#if defined(CPU_ARM11) || defined(CPU_CORTEXA8)
 void	arm11_setttb		(u_int);
 
 void	arm11_tlb_flushID_SE	(u_int);
@@ -444,6 +444,25 @@
 void	armv6_idcache_wbinv_range (vaddr_t, vsize_t);
 #endif
 
+#if defined(CPU_CORTEXA8)
+void	armv7_setttb(u_int);
+
+void	armv7_icache_sync_range(vaddr_t, vsize_t);
+void	armv7_dcache_wb_range(vaddr_t, vsize_t);
+void	armv7_dcache_wbinv_range(vaddr_t, vsize_t);
+void	armv7_dcache_inv_range(vaddr_t, vsize_t);
+void	armv7_idcache_wbinv_range(vaddr_t, vsize_t);
+
+void 	armv7_dcache_wbinv_all (void);
+void	armv7_idcache_wbinv_all(void);
+void	armv7_icache_sync_all(void);
+void	armv7_cpu_sleep(int);
+void	armv7_context_switch(u_int);
+void	armv7_tlb_flushID_SE(u_int);
+void	armv7_setup		(char *string);
+#endif
+
+
 #if defined(CPU_ARM1136)
 void	arm1136_setttb			(u_int);
 void	arm1136_idcache_wbinv_all	(void);
@@ -461,7 +480,7 @@
     defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
     defined(CPU_FA526) || \
     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_CORTEXA8)
 
 void	armv4_tlb_flushID	(void);
 void	armv4_tlb_flushI	(void);
@@ -478,7 +497,8 @@
 #endif
 
 #if 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_CORTEXA8)
 
 void	xscale_cpwait		(void);
 #define	cpu_cpwait()		cpufuncs.cf_cpwait()
@@ -518,7 +538,7 @@
 void	xscale_context_switch	(u_int);
 
 void	xscale_setup		(char *);
-#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 */
+#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || __CPU_XSCALE_PXA2XX || CPU_XSCALE_IXP425 || CPU_CORTEXA8 */
 
 #define tlb_flush	cpu_tlb_flushID
 #define setttb		cpu_setttb
Index: arch/arm/include/arm32/pmap.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/arm32/pmap.h,v
retrieving revision 1.94
diff -u -r1.94 pmap.h
--- arch/arm/include/arm32/pmap.h	27 Dec 2009 05:14:56 -0000	1.94
+++ arch/arm/include/arm32/pmap.h	14 May 2010 13:16:57 -0000
@@ -126,7 +126,7 @@
  * tell MI code that the cache is virtually-indexed.
  * ARMv6 is physically-tagged but all others are virtually-tagged.
  */
-#if ARM_MMU_V6 > 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
 #define PMAP_CACHE_VIPT
 #else
 #define PMAP_CACHE_VIVT
@@ -290,7 +290,7 @@
 #define PMAP_GROWKERNEL		/* turn on pmap_growkernel interface */
 #define	PMAP_ENABLE_PMAP_KMPAGE	/* enable the PMAP_KMPAGE flag */
 
-#if ARM_MMU_V6 > 0
+#if (ARM_MMU_V6 + ARM_MMU_V7) > 0
 #define	PMAP_PREFER(hint, vap, sz, td)	pmap_prefer((hint), (vap), (td))
 void	pmap_prefer(vaddr_t, vaddr_t *, int);
 #endif
@@ -390,7 +390,7 @@
  * we need to do PTE syncs.  If only SA-1 is configured, then evaluate
  * this at compile time.
  */
-#if (ARM_MMU_SA1 + ARM_MMU_V6 != 0) && (ARM_NMMUS == 1) 
+#if (ARM_MMU_SA1 + ARM_MMU_V6 + ARM_MMU_V7 != 0) && (ARM_NMMUS == 1) 
 #define	PMAP_NEEDS_PTE_SYNC	1
 #define	PMAP_INCLUDE_PTE_SYNC
 #elif (ARM_MMU_SA1 == 0)
@@ -448,7 +448,7 @@
 
 /************************* ARM MMU configuration *****************************/
 
-#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0
+#if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6 + ARM_MMU_V7) != 0
 void	pmap_copy_page_generic(paddr_t, paddr_t);
 void	pmap_zero_page_generic(paddr_t);
 
@@ -483,6 +483,10 @@
 void	pmap_uarea(vaddr_t);
 #endif /* ARM_MMU_XSCALE == 1 */
 
+#if ARM_MMU_V7 == 1
+void	pmap_pte_init_armv7(void);
+#endif /* ARM_MMU_V7 */
+
 extern pt_entry_t		pte_l1_s_cache_mode;
 extern pt_entry_t		pte_l1_s_cache_mask;
 
@@ -496,10 +500,21 @@
 extern pt_entry_t		pte_l2_l_cache_mode_pt;
 extern pt_entry_t		pte_l2_s_cache_mode_pt;
 
+extern pt_entry_t		pte_l1_s_prot_u;
+extern pt_entry_t		pte_l1_s_prot_w;
+extern pt_entry_t		pte_l1_s_prot_ro;
+extern pt_entry_t		pte_l1_s_prot_mask;
+
 extern pt_entry_t		pte_l2_s_prot_u;
 extern pt_entry_t		pte_l2_s_prot_w;
+extern pt_entry_t		pte_l2_s_prot_ro;
 extern pt_entry_t		pte_l2_s_prot_mask;
- 
+
+extern pt_entry_t		pte_l2_l_prot_u;
+extern pt_entry_t		pte_l2_l_prot_w;
+extern pt_entry_t		pte_l2_l_prot_ro;
+extern pt_entry_t		pte_l2_l_prot_mask;
+
 extern pt_entry_t		pte_l1_s_proto;
 extern pt_entry_t		pte_l1_c_proto;
 extern pt_entry_t		pte_l2_s_proto;
@@ -523,41 +538,66 @@
  * We use these macros since we use different bits on different processor
  * models.
  */
-#define	L1_S_PROT_U		(L1_S_AP(AP_U))
-#define	L1_S_PROT_W		(L1_S_AP(AP_W))
-#define	L1_S_PROT_MASK		(L1_S_PROT_U|L1_S_PROT_W)
+#define	L1_S_PROT_U_generic	(L1_S_AP(AP_U))
+#define	L1_S_PROT_W_generic	(L1_S_AP(AP_W))
+#define	L1_S_PROT_RO_generic	(0)
+#define	L1_S_PROT_MASK_generic	(L1_S_PROT_U|L1_S_PROT_W|L1_S_PROT_RO)
+
+#define	L1_S_PROT_U_armv7	(L1_S_AP(AP_R) | L1_S_AP(AP_U))
+#define	L1_S_PROT_W_armv7	(L1_S_AP(AP_W))
+#define	L1_S_PROT_RO_armv7	(L1_S_AP(AP_R) | L1_S_AP(AP_RO))
+#define	L1_S_PROT_MASK_armv7	(L1_S_PROT_U|L1_S_PROT_W|L1_S_PROT_RO)
 
 #define	L1_S_CACHE_MASK_generic	(L1_S_B|L1_S_C)
 #define	L1_S_CACHE_MASK_xscale	(L1_S_B|L1_S_C|L1_S_XS_TEX(TEX_XSCALE_X))
+#define	L1_S_CACHE_MASK_armv7	(L1_S_B|L1_S_C)
 
-#define	L2_L_PROT_U		(L2_AP(AP_U))
-#define	L2_L_PROT_W		(L2_AP(AP_W))
-#define	L2_L_PROT_MASK		(L2_L_PROT_U|L2_L_PROT_W)
+#define	L2_L_PROT_U_generic	(L2_AP(AP_U))
+#define	L2_L_PROT_W_generic	(L2_AP(AP_W))
+#define	L2_L_PROT_RO_generic	(0)
+#define	L2_L_PROT_MASK_generic	(L2_L_PROT_U|L2_L_PROT_W|L2_L_PROT_RO)
+
+#define	L2_L_PROT_U_armv7	(L2_AP0(AP_R) | L2_AP0(AP_U))
+#define	L2_L_PROT_W_armv7	(L2_AP0(AP_W))
+#define	L2_L_PROT_RO_armv7	(L2_AP0(AP_R) | L2_AP0(AP_RO))
+#define	L2_L_PROT_MASK_armv7	(L2_L_PROT_U|L2_L_PROT_W|L2_L_PROT_RO)
 
 #define	L2_L_CACHE_MASK_generic	(L2_B|L2_C)
 #define	L2_L_CACHE_MASK_xscale	(L2_B|L2_C|L2_XS_L_TEX(TEX_XSCALE_X))
+#define	L2_L_CACHE_MASK_armv7	(L2_B|L2_C)
 
 #define	L2_S_PROT_U_generic	(L2_AP(AP_U))
 #define	L2_S_PROT_W_generic	(L2_AP(AP_W))
-#define	L2_S_PROT_MASK_generic	(L2_S_PROT_U|L2_S_PROT_W)
+#define	L2_S_PROT_RO_generic	(0)
+#define	L2_S_PROT_MASK_generic	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
 
 #define	L2_S_PROT_U_xscale	(L2_AP0(AP_U))
 #define	L2_S_PROT_W_xscale	(L2_AP0(AP_W))
-#define	L2_S_PROT_MASK_xscale	(L2_S_PROT_U|L2_S_PROT_W)
+#define	L2_S_PROT_RO_xscale	(0)
+#define	L2_S_PROT_MASK_xscale	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
+
+#define	L2_S_PROT_U_armv7	(L2_AP0(AP_R) | L2_AP0(AP_U))
+#define	L2_S_PROT_W_armv7	(L2_AP0(AP_W))
+#define	L2_S_PROT_RO_armv7	(L2_AP0(AP_R) | L2_AP0(AP_RO))
+#define	L2_S_PROT_MASK_armv7	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
 
 #define	L2_S_CACHE_MASK_generic	(L2_B|L2_C)
 #define	L2_S_CACHE_MASK_xscale	(L2_B|L2_C|L2_XS_T_TEX(TEX_XSCALE_X))
+#define	L2_S_CACHE_MASK_armv7	(L2_B|L2_C)
 
 #define	L1_S_PROTO_generic	(L1_TYPE_S | L1_S_IMP)
 #define	L1_S_PROTO_xscale	(L1_TYPE_S)
+#define	L1_S_PROTO_armv7	(L1_TYPE_S)
 
 #define	L1_C_PROTO_generic	(L1_TYPE_C | L1_C_IMP2)
 #define	L1_C_PROTO_xscale	(L1_TYPE_C)
+#define	L1_C_PROTO_armv7	(L1_TYPE_C)
 
 #define	L2_L_PROTO		(L2_TYPE_L)
 
 #define	L2_S_PROTO_generic	(L2_TYPE_S)
 #define	L2_S_PROTO_xscale	(L2_TYPE_XS)
+#define	L2_S_PROTO_armv7	(L2_TYPE_S)
 
 /*
  * User-visible names for the ones that vary with MMU class.
@@ -565,10 +605,21 @@
 
 #if ARM_NMMUS > 1
 /* More than one MMU class configured; use variables. */
+#define	L1_S_PROT_U		pte_l1_s_prot_u
+#define	L1_S_PROT_W		pte_l1_s_prot_w
+#define	L1_S_PROT_RO		pte_l1_s_prot_ro
+#define	L1_S_PROT_MASK		pte_l1_s_prot_mask
+
 #define	L2_S_PROT_U		pte_l2_s_prot_u
 #define	L2_S_PROT_W		pte_l2_s_prot_w
+#define	L2_S_PROT_RO		pte_l2_s_prot_ro
 #define	L2_S_PROT_MASK		pte_l2_s_prot_mask
 
+#define	L2_L_PROT_U		pte_l2_l_prot_u
+#define	L2_L_PROT_W		pte_l2_l_prot_w
+#define	L2_L_PROT_RO		pte_l2_l_prot_ro
+#define	L2_L_PROT_MASK		pte_l2_l_prot_mask
+
 #define	L1_S_CACHE_MASK		pte_l1_s_cache_mask
 #define	L2_L_CACHE_MASK		pte_l2_l_cache_mask
 #define	L2_S_CACHE_MASK		pte_l2_s_cache_mask
@@ -580,10 +631,21 @@
 #define	pmap_copy_page(s, d)	(*pmap_copy_page_func)((s), (d))
 #define	pmap_zero_page(d)	(*pmap_zero_page_func)((d))
 #elif (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6) != 0
+#define	L1_S_PROT_U		L1_S_PROT_U_generic
+#define	L1_S_PROT_W		L1_S_PROT_W_generic
+#define	L1_S_PROT_RO		L1_S_PROT_RO_generic
+#define	L1_S_PROT_MASK		L1_S_PROT_MASK_generic
+
 #define	L2_S_PROT_U		L2_S_PROT_U_generic
 #define	L2_S_PROT_W		L2_S_PROT_W_generic
+#define	L2_S_PROT_RO		L2_S_PROT_RO_generic
 #define	L2_S_PROT_MASK		L2_S_PROT_MASK_generic
 
+#define	L2_L_PROT_U		L2_L_PROT_U_generic
+#define	L2_L_PROT_W		L2_L_PROT_W_generic
+#define	L2_L_PROT_RO		L2_L_PROT_RO_generic
+#define	L2_L_PROT_MASK		L2_L_PROT_MASK_generic
+
 #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_generic
 #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_generic
 #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_generic
@@ -595,10 +657,21 @@
 #define	pmap_copy_page(s, d)	pmap_copy_page_generic((s), (d))
 #define	pmap_zero_page(d)	pmap_zero_page_generic((d))
 #elif ARM_MMU_XSCALE == 1
+#define	L1_S_PROT_U		L1_S_PROT_U_generic
+#define	L1_S_PROT_W		L1_S_PROT_W_generic
+#define	L1_S_PROT_RO		L1_S_PROT_RO_generic
+#define	L1_S_PROT_MASK		L1_S_PROT_MASK_generic
+
 #define	L2_S_PROT_U		L2_S_PROT_U_xscale
 #define	L2_S_PROT_W		L2_S_PROT_W_xscale
+#define	L2_S_PROT_RO		L2_S_PROT_RO_xscale
 #define	L2_S_PROT_MASK		L2_S_PROT_MASK_xscale
 
+#define	L2_L_PROT_U		L2_L_PROT_U_generic
+#define	L2_L_PROT_W		L2_L_PROT_W_generic
+#define	L2_L_PROT_RO		L2_L_PROT_RO_generic
+#define	L2_L_PROT_MASK		L2_L_PROT_MASK_generic
+
 #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_xscale
 #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_xscale
 #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_xscale
@@ -609,20 +682,60 @@
 
 #define	pmap_copy_page(s, d)	pmap_copy_page_xscale((s), (d))
 #define	pmap_zero_page(d)	pmap_zero_page_xscale((d))
+#elif ARM_MMU_V7 == 1
+#define	L1_S_PROT_U		L1_S_PROT_U_armv7
+#define	L1_S_PROT_W		L1_S_PROT_W_armv7
+#define	L1_S_PROT_RO		L1_S_PROT_RO_armv7
+#define	L1_S_PROT_MASK		L1_S_PROT_MASK_armv7
+
+#define	L2_S_PROT_U		L2_S_PROT_U_armv7
+#define	L2_S_PROT_W		L2_S_PROT_W_armv7
+#define	L2_S_PROT_RO		L2_S_PROT_RO_armv7
+#define	L2_S_PROT_MASK		L2_S_PROT_MASK_armv7
+
+#define	L2_L_PROT_U		L2_L_PROT_U_armv7
+#define	L2_L_PROT_W		L2_L_PROT_W_armv7
+#define	L2_L_PROT_RO		L2_L_PROT_RO_armv7
+#define	L2_L_PROT_MASK		L2_L_PROT_MASK_armv7
+
+#define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_armv7
+#define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_armv7
+#define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_armv7
+
+/* These prototypes make writeable mappings, while the other MMU types
+ * make read-only mappings. */
+#define	L1_S_PROTO		L1_S_PROTO_armv7
+#define	L1_C_PROTO		L1_C_PROTO_armv7
+#define	L2_S_PROTO		L2_S_PROTO_armv7
+
+#define	pmap_copy_page(s, d)	pmap_copy_page_generic((s), (d))
+#define	pmap_zero_page(d)	pmap_zero_page_generic((d))
 #endif /* ARM_NMMUS > 1 */
 
 /*
+ * Macros to set and query the write permission on page descriptors.
+ */
+#define l1pte_set_writable(pte)	(((pte) & ~L1_S_PROT_RO) | L1_S_PROT_W)
+#define l1pte_set_readonly(pte)	(((pte) & ~L1_S_PROT_W) | L1_S_PROT_RO)
+#define l2pte_set_writable(pte)	(((pte) & ~L2_S_PROT_RO) | L2_S_PROT_W)
+#define l2pte_set_readonly(pte)	(((pte) & ~L2_S_PROT_W) | L2_S_PROT_RO)
+
+#define l2pte_writable_p(pte)	(((pte) & L2_S_PROT_W) == L2_S_PROT_W && \
+				 (L2_S_PROT_RO == 0 || \
+				  ((pte) & L2_S_PROT_RO) != L2_S_PROT_RO))
+
+/*
  * These macros return various bits based on kernel/user and protection.
  * Note that the compiler will usually fold these at compile time.
  */
 #define	L1_S_PROT(ku, pr)	((((ku) == PTE_USER) ? L1_S_PROT_U : 0) | \
-				 (((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : 0))
+				 (((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : L1_S_PROT_RO))
 
 #define	L2_L_PROT(ku, pr)	((((ku) == PTE_USER) ? L2_L_PROT_U : 0) | \
-				 (((pr) & VM_PROT_WRITE) ? L2_L_PROT_W : 0))
+				 (((pr) & VM_PROT_WRITE) ? L2_L_PROT_W : L2_L_PROT_RO))
 
 #define	L2_S_PROT(ku, pr)	((((ku) == PTE_USER) ? L2_S_PROT_U : 0) | \
-				 (((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : 0))
+				 (((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : L2_S_PROT_RO))
 
 /*
  * Macros to test if a mapping is mappable with an L1 Section mapping
Index: arch/arm/include/arm32/pte.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/arm32/pte.h,v
retrieving revision 1.8
diff -u -r1.8 pte.h
--- arch/arm/include/arm32/pte.h	27 Apr 2008 18:58:44 -0000	1.8
+++ arch/arm/include/arm32/pte.h	14 May 2010 13:16:57 -0000
@@ -227,6 +227,9 @@
 #define	AP_W		0x01		/* writable */
 #define	AP_U		0x02		/* user */
 
+#define	AP_R		0x01		/* readable (ARMv7 only) */
+#define	AP_RO		0x20		/* read-only (ARMv7 only) */
+
 /*
  * Short-hand for common AP_* constants.
  *
@@ -249,6 +252,15 @@
 #define	APX_KRWURW(APX)	(    0x03)	/* kernel read/write user read/write */
 
 /*
+ * Note: These values are for the simplified access permissions model
+ * of ARMv7. Assumes that AFE is clear in CP15 register 1.
+ */
+#define	AP7_KR		0x21		/* kernel read */
+#define	AP7_KRUR	0x23		/* kernel read usr read */
+#define	AP7_KRW		0x01		/* kernel read/write */
+#define	AP7_KRWURW	0x03		/* kernel read/write usr read/write */
+
+/*
  * Domain Types for the Domain Access Control Register.
  */
 #define	DOMAIN_FAULT	0x00		/* no access */
Index: arch/arm/omap/omap2_mputmr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/omap/omap2_mputmr.c,v
retrieving revision 1.1
diff -u -r1.1 omap2_mputmr.c
--- arch/arm/omap/omap2_mputmr.c	27 Aug 2008 11:03:10 -0000	1.1
+++ arch/arm/omap/omap2_mputmr.c	14 May 2010 13:16:57 -0000
@@ -254,7 +254,7 @@
 	tc_init(&mpu_timecounter);
 }
 
-#ifndef ARM11_PMC
+#if !(defined(ARM11_PMC) || defined(CORTEXA8_PMC))
 void
 delay(u_int n)
 {
@@ -288,7 +288,7 @@
 		}
 	}
 }
-#endif /* ARM11_PMC */
+#endif /* ARM11_PMC || CORTEXA8_PMC */
 
 /*
  * OVF_Rate =
Index: arch/arm/omap/omap2_obio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/omap/omap2_obio.c,v
retrieving revision 1.7
diff -u -r1.7 omap2_obio.c
--- arch/arm/omap/omap2_obio.c	12 Dec 2008 17:36:14 -0000	1.7
+++ arch/arm/omap/omap2_obio.c	14 May 2010 13:16:57 -0000
@@ -350,7 +350,11 @@
 	bus_addr_t addr;
 	bool required;
 } critical_devs[] = {
+#ifdef OMAP_3530
+	{ .name = "avic", .addr = INTC_BASE_3530, .required = true },
+#else
 	{ .name = "avic", .addr = INTC_BASE, .required = true },
+#endif
 	{ .name = "gpio1", .addr = GPIO1_BASE, .required = false },
 	{ .name = "gpio2", .addr = GPIO2_BASE, .required = false },
 	{ .name = "gpio3", .addr = GPIO3_BASE, .required = false },
Index: arch/arm/omap/omap2_reg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/omap/omap2_reg.h,v
retrieving revision 1.1
diff -u -r1.1 omap2_reg.h
--- arch/arm/omap/omap2_reg.h	27 Aug 2008 11:03:10 -0000	1.1
+++ arch/arm/omap/omap2_reg.h	14 May 2010 13:16:57 -0000
@@ -414,6 +414,20 @@
 /*
  * GPT - General Purpose Timers
  */
+#ifdef OMAP_3530
+#define	GPT1_BASE			0x48318000
+#define	GPT2_BASE			0x49032000
+#define	GPT3_BASE			0x49034000
+#define	GPT4_BASE			0x49036000
+#define	GPT5_BASE			0x49038000
+#define	GPT6_BASE			0x4903A000
+#define	GPT7_BASE			0x4903C000
+#define	GPT8_BASE			0x4903E000
+#define	GPT9_BASE			0x49040000
+#define	GPT10_BASE			0x48086000
+#define	GPT11_BASE			0x48088000
+#define	GPT12_BASE			0x48304000
+#else
 #define	GPT1_BASE			0x48028000
 #define	GPT2_BASE			0x4802a000
 #define	GPT3_BASE			0x48078000
@@ -426,6 +440,7 @@
 #define	GPT10_BASE			0x48086000
 #define	GPT11_BASE			0x48088000
 #define	GPT12_BASE			0x4808a000
+#endif
 
 /*
  * GPIO
Index: arch/evbarm/beagle/beagle.h
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/beagle/beagle.h,v
retrieving revision 1.2
diff -u -r1.2 beagle.h
--- arch/evbarm/beagle/beagle.h	22 Oct 2008 17:29:33 -0000	1.2
+++ arch/evbarm/beagle/beagle.h	14 May 2010 13:16:57 -0000
@@ -34,10 +34,10 @@
 #include <arm/omap/omap2_reg.h>
 
 /*
- * Kernel VM space: 192MB at KERNEL_VM_BASE
+ * Kernel VM space: 576MB at KERNEL_VM_BASE
  */
 #define	KERNEL_VM_BASE		((KERNEL_BASE + 0x01000000) & ~(0x400000-1))
-#define KERNEL_VM_SIZE		0x0C000000
+#define KERNEL_VM_SIZE		0x24000000
 
 /*
  * We devmap IO starting at KERNEL_VM_BASE + KERNEL_VM_SIZE
Index: arch/evbarm/beagle/beagle_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/beagle/beagle_machdep.c,v
retrieving revision 1.7
diff -u -r1.7 beagle_machdep.c
--- arch/evbarm/beagle/beagle_machdep.c	26 Dec 2009 16:01:23 -0000	1.7
+++ arch/evbarm/beagle/beagle_machdep.c	14 May 2010 13:16:57 -0000
@@ -627,7 +627,7 @@
 	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
 }
 
-void arm11_pmc_ccnt_init(void);
+void cortexa8_pmc_ccnt_init(void);
 
 static void
 init_clocks(void)
@@ -645,7 +645,7 @@
 	}
 	beagle_putchar('G');
 #endif
-	arm11_pmc_ccnt_init();
+	cortexa8_pmc_ccnt_init();
 }
 
 #ifndef CONSADDR
Index: arch/evbarm/beagle/beagle_start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/beagle/beagle_start.S,v
retrieving revision 1.3
diff -u -r1.3 beagle_start.S
--- arch/evbarm/beagle/beagle_start.S	21 Oct 2009 14:15:51 -0000	1.3
+++ arch/evbarm/beagle/beagle_start.S	14 May 2010 13:16:57 -0000
@@ -178,8 +178,6 @@
 
 	Invalidate_I_cache(r0)
 
-	mcr	p15, 0, r0, c7, c14, 0	/* Clean and Invalidate Entire Data Cache */
-
         ldr     r2, Lctl_ID_dis		/* Disable I+D caches */
 	mrc	p15, 0, r1, c1, c0, 0	/*  "       "   "     */
 	and	r1, r1, r2		/*  "       "   "     */
@@ -239,12 +237,8 @@
 	.word CPU_CONTROL_MMU_ENABLE  | \
 	      CPU_CONTROL_AFLT_ENABLE | \
 	      CPU_CONTROL_DC_ENABLE   | \
-	      CPU_CONTROL_WBUF_ENABLE | \
-	      CPU_CONTROL_32BP_ENABLE | \
-	      CPU_CONTROL_32BD_ENABLE | \
-	      CPU_CONTROL_LABT_ENABLE | \
-	      CPU_CONTROL_SYST_ENABLE | \
-	      CPU_CONTROL_IC_ENABLE
+	      CPU_CONTROL_IC_ENABLE   | \
+	      CPU_CONTROL_BPRD_ENABLE
 
 	/* bits to clear in the Control Register */
 Lcontrol_clr:
@@ -252,12 +246,10 @@
 
 	/* bits to "write as existing" in the Control Register */
 Lcontrol_wax:
-	.word	(3 << 30) | \
-		(1 << 29) | \
-		(1 << 28) | \
-		(3 << 26) | \
-		(3 << 19) | \
-		(1 << 17)
+	.word	(1 << 31) | \
+		(1 << 26) | \
+		(0x7ff << 14) | \
+		(0xff << 3)
 		
 	/* bits to disable the caches */
 Lctl_ID_dis:
@@ -279,22 +271,22 @@
 	/* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable */
 	MMU_INIT(KERNEL_BASE, KERNEL_BASE,
 		(MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
-		L1_S_PROTO | L1_S_AP(AP_KRW) | L1_S_B | L1_S_C)
+		L1_S_PROTO | L1_S_AP(AP7_KRW) | L1_S_B | L1_S_C)
 
 	/* Map first 1MB of L4 CORE (so console will work) */
 	MMU_INIT(OMAP3530_L4_CORE_VBASE, OMAP3530_L4_CORE_BASE,
 		1,
-		L1_S_PROTO | L1_S_AP(AP_KRW))
+		L1_S_PROTO | L1_S_AP(AP7_KRW))
 
 	/* Map first(all) 1MB of L4 PERIPHERAL (so console will work) */
 	MMU_INIT(OMAP3530_L4_PERIPHERAL_VBASE, OMAP3530_L4_PERIPHERAL_BASE,
 		1,
-		L1_S_PROTO | L1_S_AP(AP_KRW))
+		L1_S_PROTO | L1_S_AP(AP7_KRW))
 
 	/* Map all 256KB of L4 WAKEUP (so console will work) */
 	MMU_INIT(OMAP3530_L4_WAKEUP_VBASE, OMAP3530_L4_WAKEUP_BASE,
 		1,
-		L1_S_PROTO | L1_S_AP(AP_KRW))
+		L1_S_PROTO | L1_S_AP(AP7_KRW))
 
 	/* end of table */
 	MMU_INIT(0, 0, 0, 0)
Index: arch/evbarm/conf/IGEPV2
===================================================================
RCS file: arch/evbarm/conf/IGEPV2
diff -N arch/evbarm/conf/IGEPV2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/evbarm/conf/IGEPV2	14 May 2010 13:16:57 -0000
@@ -0,0 +1,259 @@
+#
+#	$NetBSD: BEAGLEBOARD,v 1.2 2008/10/22 17:38:59 matt Exp $
+#
+#	IGEPv2 -- TI OMAP 3530 Eval Board Kernel
+#
+
+include	"arch/evbarm/conf/std.igepv2"
+
+# estimated number of users
+
+maxusers	32
+
+# Standard system options
+
+options 	RTC_OFFSET=0	# hardware clock is this many mins. west of GMT
+#options 	NTP		# NTP phase/frequency locked loop
+
+# CPU options
+
+options 	CPU_CORTEXA8
+options 	OMAP_3530
+options 	PMAPCOUNTERS
+
+# Architecture options
+
+# File systems
+
+file-system	FFS		# UFS
+#file-system	LFS		# log-structured file system
+file-system	MFS		# memory file system
+file-system	NFS		# Network file system
+#file-system 	ADOSFS		# AmigaDOS-compatible file system
+#file-system 	EXT2FS		# second extended file system (linux)
+#file-system	CD9660		# ISO 9660 + Rock Ridge file system
+file-system	MSDOSFS		# MS-DOS file system
+#file-system	FDESC		# /dev/fd
+#file-system	KERNFS		# /kern
+#file-system	NULLFS		# loopback file system
+#file-system	PORTAL		# portal filesystem (still experimental)
+#file-system	PROCFS		# /proc
+#file-system	UMAPFS		# NULLFS + uid and gid remapping
+#file-system	UNION		# union file system
+file-system	TMPFS		# memory file system
+file-system	PTYFS		# /dev/pts/N support
+
+# File system options
+#options 	QUOTA		# UFS quotas
+#options 	FFS_EI		# FFS Endian Independant support
+#options 	NFSSERVER
+#options 	SOFTDEP
+options 	WAPBL		# File system journaling support - Experimental
+#options 	FFS_NO_SNAPSHOT	# No FFS snapshot support
+
+# Networking options
+
+#options 	GATEWAY		# packet forwarding
+options 	INET		# IP + ICMP + TCP + UDP
+options 	INET6		# IPV6
+#options 	IPSEC		# IP security
+#options 	IPSEC_ESP	# IP security (encryption part; define w/ IPSEC)
+#options 	IPSEC_NAT_T	# IPsec NAT traversal (NAT-T)
+#options 	IPSEC_DEBUG	# debug for IP security
+#options 	MROUTING	# IP multicast routing
+#options 	PIM		# Protocol Independent Multicast
+#options 	NS		# XNS
+#options 	NSIP		# XNS tunneling over IP
+#options 	ISO,TPIP	# OSI
+#options 	EON		# OSI tunneling over IP
+#options 	CCITT,LLC,HDLC	# X.25
+#options 	NETATALK	# AppleTalk networking
+#options 	PFIL_HOOKS	# pfil(9) packet filter hooks
+#options 	PPP_BSDCOMP	# BSD-Compress compression support for PPP
+#options 	PPP_DEFLATE	# Deflate compression support for PPP
+#options 	PPP_FILTER	# Active filter support for PPP (requires bpf)
+#options 	TCP_DEBUG	# Record last TCP_NDEBUG packets with SO_DEBUG
+
+options 	NFS_BOOT_BOOTP
+options 	NFS_BOOT_DHCP
+#options		NFS_BOOT_BOOTSTATIC
+#options		NFS_BOOTSTATIC_MYIP="\"192.168.1.4\""
+#options		NFS_BOOTSTATIC_GWIP="\"192.168.1.1\""
+#options		NFS_BOOTSTATIC_MASK="\"255.255.255.0\""
+#options		NFS_BOOTSTATIC_SERVADDR="\"192.168.1.1\""
+#options		NFS_BOOTSTATIC_SERVER="\"192.168.1.1:/nfs/sdp2430\""
+
+options		NFS_BOOT_RWSIZE=1024
+
+# Compatibility options
+
+#options 	COMPAT_43	# 4.3BSD compatibility.
+options 	COMPAT_40	# NetBSD 4.0 compatibility.
+options 	COMPAT_30	# NetBSD 3.0 compatibility.
+#options 	COMPAT_20	# NetBSD 2.0 compatibility.
+#options 	COMPAT_16	# NetBSD 1.6 compatibility.
+#options 	COMPAT_15	# NetBSD 1.5 compatibility.
+#options 	COMPAT_14	# NetBSD 1.4 compatibility.
+#options 	COMPAT_13	# NetBSD 1.3 compatibility.
+#options 	COMPAT_12	# NetBSD 1.2 compatibility.
+#options 	COMPAT_11	# NetBSD 1.1 compatibility.
+#options 	COMPAT_10	# NetBSD 1.0 compatibility.
+#options 	COMPAT_09	# NetBSD 0.9 compatibility.
+#options 	TCP_COMPAT_42	# 4.2BSD TCP/IP bug compat. Not recommended.
+#options		COMPAT_BSDPTY	# /dev/[pt]ty?? ptys.
+
+# Shared memory options
+
+options 	SYSVMSG		# System V-like message queues
+options 	SYSVSEM		# System V-like semaphores
+#options 	SEMMNI=10	# number of semaphore identifiers
+#options 	SEMMNS=60	# number of semaphores in system
+#options 	SEMUME=10	# max number of undo entries per process
+#options 	SEMMNU=30	# number of undo structures in system
+options 	SYSVSHM		# System V-like memory sharing
+#options 	SHMMAXPGS=1024	# 1024 pages is the default
+
+# Device options
+
+#options 	MEMORY_DISK_HOOKS	# boottime setup of ramdisk
+#options 	MEMORY_DISK_ROOT_SIZE=8192	# Size in blocks
+#options 	MEMORY_DISK_DYNAMIC
+#options 	MINIROOTSIZE=1000	# Size in blocks
+#options 	MEMORY_DISK_IS_ROOT	# use memory disk as root
+
+# Miscellaneous kernel options
+options 	KTRACE		# system call tracing, a la ktrace(1)
+#options 	LKM		# loadable kernel modules
+#options 	KMEMSTATS	# kernel memory statistics
+#options 	SCSIVERBOSE	# Verbose SCSI errors
+#options 	MIIVERBOSE	# Verbose MII autoconfuration messages
+#options 	DDB_KEYCODE=0x40
+#options 	USERCONF	# userconf(4) support
+#options	PIPE_SOCKETPAIR	# smaller, but slower pipe(2)
+
+# Development and Debugging options
+
+#options 	PERFCTRS	# performance counters
+options 	DIAGNOSTIC	# internally consistency checks
+#options 	DEBUG
+#options 	PMAP_DEBUG	# Enable pmap_debug_level code
+#options 	IPKDB		# remote kernel debugging
+options 	VERBOSE_INIT_ARM # verbose bootstraping messages
+options 	DDB		# in-kernel debugger
+options		DDB_ONPANIC=1
+options 	DDB_HISTORY_SIZE=100	# Enable history editing in DDB
+#options 	KGDB
+makeoptions	DEBUG="-g"	# compile full symbol table
+options 	SYMTAB_SPACE=300000
+
+## USB Debugging options
+options USB_DEBUG
+options OHCI_DEBUG 
+options UHUB_DEBUG 
+
+
+# Valid options for BOOT_ARGS:
+#  single		Boot to single user only
+#  kdb			Give control to kernel debugger
+#  ask			Ask for file name to reboot from
+#  pmapdebug=<n>	If PMAP_DEBUG, set pmap_debug_level to <n>
+#  memorydisk=<n>	Set memorydisk size to <n> KB
+#  quiet		Show aprint_naive output
+#  verbose		Show aprint_normal and aprint_verbose output
+options		BOOT_ARGS="\"\""
+
+config		netbsd		root on ? type ?
+
+# The main bus device
+mainbus0	at root
+
+# The boot cpu
+cpu0		at mainbus?
+
+# Specify the memory size in megabytes.
+options		MEMSIZE=512
+
+# L3 Interconnect
+L3i0		at mainbus?
+
+# OBIO
+obio0		at mainbus? base 0x48000000 size 0x1000000	# L4 CORE 
+obio1		at mainbus? base 0x48300000 size 0x0040000	# L4 WAKEUP 
+obio2		at mainbus? base 0x49000000 size 0x0100000	# L4 PERIPHERAL 
+#obio3		at mainbus? base 0x54000000 size 0x0800000	# L4 EMUL 
+
+# General Purpose Memory Controller
+gpmc0		at mainbus? base 0x6e000000
+
+# Interrupt Controller
+omapicu0	at obio0 addr 0x48200000 size 0x1000 intrbase 0
+omapgpio0	at obio1 addr 0x48310000 size 0x0400 intrbase 96  intr 29
+#omapgpio1	at obio2 addr 0x49050000 size 0x0400 intrbase 128 intr 30
+#omapgpio2	at obio2 addr 0x49052000 size 0x0400 intrbase 160 intr 31
+#omapgpio3	at obio2 addr 0x49054000 size 0x0400 intrbase 192 intr 32
+omapgpio4	at obio2 addr 0x49056000 size 0x0400 intrbase 224 intr 33
+#omapgpio5	at obio2 addr 0x49058000 size 0x0400 intrbase 256 intr 34
+
+gpio*		at omapgpio?
+
+# # I2C Controller
+# omapi2c0	at tipb? addr 0xfffb3800 intr 36 mult 4
+# iic*		at omapi2c?
+# # omap's own i2c address
+# options		OMAP_I2C_ADDRESS=0xe
+# # i2c bus clock low and high times in ns
+# options		I2C_LOW_TIME_nSEC=1500
+# options		I2C_HIGH_TIME_nSEC=1000
+
+# On-board 16550 UARTs
+#com0		at obio0 addr 0x4806a000 intr 72 mult 4 # UART1
+#com1		at obio0 addr 0x4806c000 intr 73 mult 4 # UART2
+com0		at obio2 addr 0x49020000 intr 74 mult 4	# UART3 (console)
+options 	CONSADDR=0x49020000, CONSPEED=115200
+
+# Operating System Timer
+omapmputmr0	at obio2 addr 0x49032000 intr 38	# GP Timer 2
+# Statistics Timer
+omapmputmr1	at obio2 addr 0x49034000 intr 39	# GP Timer 3
+# Microtime Reference Timer
+omapmputmr2	at obio2 addr 0x49036000 intr 40	# GP Timer 4
+options OMAP_MPU_TIMER_CLOCK_FREQ=12000000
+
+# Watchdog timers
+omapwdt32k*	at obio2 addr 0x49030000 size 2048	# WDT3
+#omapwdt32k*	at obio1 addr 0x4830c000 size 2048	# WDT1
+#omapwdt32k*	at obio1 addr 0x48314000 size 2048	# WDT2
+
+# On-board USB
+#ehci*		at obio0 addr 0x48064800 size 0x0400 intr 77
+#ohci*		at obio0 addr 0x48064400 size 0x0400 intr 76
+#usb*		at ohci?
+#uhub*		at usb?
+##umass*		at uhub? port ? configuration ? interface ?
+##wd*		at umass?
+#axe*		at uhub? port ? configuration ? interface ?
+
+# Hardware clocking and power management
+
+options		HWCLOCK
+options		HWCLOCK_MACHINE="<arch/arm/omap/hwclock_omap1.h>"
+options		OMAP_CK_REF_SPEED=12000000
+
+# Pseudo-Devices
+
+# disk/mass storage pseudo-devices
+pseudo-device	md		1	# memory disk device (ramdisk)
+#pseudo-device	vnd			# disk-like interface to files
+#pseudo-device	fss		4	# file system snapshot device
+
+# network pseudo-devices
+pseudo-device	bpfilter		# Berkeley packet filter
+pseudo-device	loop			# network loopback
+#pseudo-device	kttcp			# network loopback
+
+# miscellaneous pseudo-devices
+pseudo-device	pty			# pseudo-terminals
+pseudo-device	rnd			# /dev/random and in-kernel generator
+#options	RND_COM
+#pseudo-device	clockctl		# user control of clock subsystem
+pseudo-device	ksyms			# /dev/ksyms
Index: arch/evbarm/conf/std.igepv2
===================================================================
RCS file: arch/evbarm/conf/std.igepv2
diff -N arch/evbarm/conf/std.igepv2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/evbarm/conf/std.igepv2	14 May 2010 13:16:57 -0000
@@ -0,0 +1,28 @@
+#	$NetBSD: std.beagle,v 1.1 2008/10/22 10:50:56 matt Exp $
+#
+# standard NetBSD/evbarm for IGEPV2 options
+
+machine	evbarm arm
+include		"conf/std"	# MI standard options
+
+# Pull in BEAGLEBOARD config definitions.
+include "arch/evbarm/conf/files.beagle"
+
+options 	EXEC_ELF32
+options 	EXEC_SCRIPT
+
+# To support easy transit to ../arch/arm/arm32
+options 	ARM32
+options 	CORTEXA8_PMC
+options 	CORTEXA8_CCNT_HZ=720000000
+options 	__HAVE_FAST_SOFTINTS		# should be in types.h
+#options 	PROCESS_ID_IS_CURLWP
+options 	KERNEL_BASE_EXT=0x80000000
+
+makeoptions	LOADADDRESS="0x80300000"
+makeoptions	BOARDTYPE="igepv2"
+makeoptions	BOARDMKFRAG="${THISARM}/conf/mk.beagle"
+makeoptions	CPPFLAGS+="-I$S/../../../include"
+
+options 	ARM_INTR_IMPL="<arch/arm/omap/omap2_intr.h>"
+options		ARM_GENERIC_TODR
