Index: projects/armv6/sys/arm/arm/identcpu.c =================================================================== --- projects/armv6/sys/arm/arm/identcpu.c (revision 225145) +++ projects/armv6/sys/arm/arm/identcpu.c (revision 225146) @@ -1,595 +1,607 @@ /* $NetBSD: cpu.c,v 1.55 2004/02/13 11:36:10 wiz Exp $ */ /*- * Copyright (c) 1995 Mark Brinicombe. * Copyright (c) 1995 Brini. * 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 Brini. * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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. * * RiscBSD kernel project * * cpu.c * * Probing and configuration for the master CPU * * Created : 10/10/95 */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include char machine[] = "arm"; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "Machine class"); static const char * const generic_steppings[16] = { "rev 0", "rev 1", "rev 2", "rev 3", "rev 4", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const sa110_steppings[16] = { "rev 0", "step J", "step K", "step S", "step T", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const sa1100_steppings[16] = { "rev 0", "step B", "step C", "rev 3", "rev 4", "rev 5", "rev 6", "rev 7", "step D", "step E", "rev 10" "step G", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const sa1110_steppings[16] = { "step A-0", "rev 1", "rev 2", "rev 3", "step B-0", "step B-1", "step B-2", "step B-3", "step B-4", "step B-5", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const ixp12x0_steppings[16] = { "(IXP1200 step A)", "(IXP1200 step B)", "rev 2", "(IXP1200 step C)", "(IXP1200 step D)", "(IXP1240/1250 step A)", "(IXP1240 step B)", "(IXP1250 step B)", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const xscale_steppings[16] = { "step A-0", "step A-1", "step B-0", "step C-0", "step D-0", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const i80219_steppings[16] = { "step A-0", "rev 1", "rev 2", "rev 3", "rev 4", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const i80321_steppings[16] = { "step A-0", "step B-0", "rev 2", "rev 3", "rev 4", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const i81342_steppings[16] = { "step A-0", "rev 1", "rev 2", "rev 3", "rev 4", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; /* Steppings for PXA2[15]0 */ static const char * const pxa2x0_steppings[16] = { "step A-0", "step A-1", "step B-0", "step B-1", "step B-2", "step C-0", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; /* Steppings for PXA255/26x. * rev 5: PXA26x B0, rev 6: PXA255 A0 */ static const char * const pxa255_steppings[16] = { "rev 0", "rev 1", "rev 2", "step A-0", "rev 4", "step B-0", "step A-0", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; /* Stepping for PXA27x */ static const char * const pxa27x_steppings[16] = { "step A-0", "step A-1", "step B-0", "step B-1", "step C-0", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; static const char * const ixp425_steppings[16] = { "step 0 (A0)", "rev 1 (ARMv5TE)", "rev 2", "rev 3", "rev 4", "rev 5", "rev 6", "rev 7", "rev 8", "rev 9", "rev 10", "rev 11", "rev 12", "rev 13", "rev 14", "rev 15", }; struct cpuidtab { u_int32_t cpuid; enum cpu_class cpu_class; const char *cpu_name; const char * const *cpu_steppings; }; const struct cpuidtab cpuids[] = { { CPU_ID_ARM2, CPU_CLASS_ARM2, "ARM2", generic_steppings }, { CPU_ID_ARM250, CPU_CLASS_ARM2AS, "ARM250", generic_steppings }, { CPU_ID_ARM3, CPU_CLASS_ARM3, "ARM3", generic_steppings }, { CPU_ID_ARM600, CPU_CLASS_ARM6, "ARM600", generic_steppings }, { CPU_ID_ARM610, CPU_CLASS_ARM6, "ARM610", generic_steppings }, { CPU_ID_ARM620, CPU_CLASS_ARM6, "ARM620", generic_steppings }, { CPU_ID_ARM700, CPU_CLASS_ARM7, "ARM700", generic_steppings }, { CPU_ID_ARM710, CPU_CLASS_ARM7, "ARM710", generic_steppings }, { CPU_ID_ARM7500, CPU_CLASS_ARM7, "ARM7500", generic_steppings }, { CPU_ID_ARM710A, CPU_CLASS_ARM7, "ARM710a", generic_steppings }, { CPU_ID_ARM7500FE, CPU_CLASS_ARM7, "ARM7500FE", generic_steppings }, { CPU_ID_ARM710T, CPU_CLASS_ARM7TDMI, "ARM710T", generic_steppings }, { CPU_ID_ARM720T, CPU_CLASS_ARM7TDMI, "ARM720T", generic_steppings }, { CPU_ID_ARM740T8K, CPU_CLASS_ARM7TDMI, "ARM740T (8 KB cache)", generic_steppings }, { CPU_ID_ARM740T4K, CPU_CLASS_ARM7TDMI, "ARM740T (4 KB cache)", generic_steppings }, { CPU_ID_ARM810, CPU_CLASS_ARM8, "ARM810", generic_steppings }, { CPU_ID_ARM920T, CPU_CLASS_ARM9TDMI, "ARM920T", generic_steppings }, { CPU_ID_ARM920T_ALT, CPU_CLASS_ARM9TDMI, "ARM920T", generic_steppings }, { CPU_ID_ARM922T, CPU_CLASS_ARM9TDMI, "ARM922T", generic_steppings }, { CPU_ID_ARM926EJS, CPU_CLASS_ARM9EJS, "ARM926EJ-S", generic_steppings }, { CPU_ID_ARM940T, CPU_CLASS_ARM9TDMI, "ARM940T", generic_steppings }, { CPU_ID_ARM946ES, CPU_CLASS_ARM9ES, "ARM946E-S", generic_steppings }, { CPU_ID_ARM966ES, CPU_CLASS_ARM9ES, "ARM966E-S", generic_steppings }, { CPU_ID_ARM966ESR1, CPU_CLASS_ARM9ES, "ARM966E-S", generic_steppings }, { CPU_ID_FA526, CPU_CLASS_ARM9TDMI, "FA526", generic_steppings }, { CPU_ID_FA626TE, CPU_CLASS_ARM9ES, "FA626TE", generic_steppings }, { CPU_ID_TI925T, CPU_CLASS_ARM9TDMI, "TI ARM925T", generic_steppings }, { CPU_ID_ARM1020E, CPU_CLASS_ARM10E, "ARM1020E", generic_steppings }, { CPU_ID_ARM1022ES, CPU_CLASS_ARM10E, "ARM1022E-S", generic_steppings }, { CPU_ID_ARM1026EJS, CPU_CLASS_ARM10EJ, "ARM1026EJ-S", generic_steppings }, + { CPU_ID_CORTEXA8R1, CPU_CLASS_CORTEXA, "Cortex A8-r1", + generic_steppings }, + { CPU_ID_CORTEXA8R2, CPU_CLASS_CORTEXA, "Cortex A8-r2", + generic_steppings }, + { CPU_ID_CORTEXA8R3, CPU_CLASS_CORTEXA, "Cortex A8-r3", + generic_steppings }, + { CPU_ID_CORTEXA9R1, CPU_CLASS_CORTEXA, "Cortex A9-r1", + generic_steppings }, + { CPU_ID_CORTEXA9R2, CPU_CLASS_CORTEXA, "Cortex A9-r2", + generic_steppings }, + { CPU_ID_SA110, CPU_CLASS_SA1, "SA-110", sa110_steppings }, { CPU_ID_SA1100, CPU_CLASS_SA1, "SA-1100", sa1100_steppings }, { CPU_ID_SA1110, CPU_CLASS_SA1, "SA-1110", sa1110_steppings }, { CPU_ID_IXP1200, CPU_CLASS_SA1, "IXP1200", ixp12x0_steppings }, { CPU_ID_80200, CPU_CLASS_XSCALE, "i80200", xscale_steppings }, { CPU_ID_80321_400, CPU_CLASS_XSCALE, "i80321 400MHz", i80321_steppings }, { CPU_ID_80321_600, CPU_CLASS_XSCALE, "i80321 600MHz", i80321_steppings }, { CPU_ID_80321_400_B0, CPU_CLASS_XSCALE, "i80321 400MHz", i80321_steppings }, { CPU_ID_80321_600_B0, CPU_CLASS_XSCALE, "i80321 600MHz", i80321_steppings }, { CPU_ID_81342, CPU_CLASS_XSCALE, "i81342", i81342_steppings }, { CPU_ID_80219_400, CPU_CLASS_XSCALE, "i80219 400MHz", i80219_steppings }, { CPU_ID_80219_600, CPU_CLASS_XSCALE, "i80219 600MHz", i80219_steppings }, { CPU_ID_PXA27X, CPU_CLASS_XSCALE, "PXA27x", pxa27x_steppings }, { CPU_ID_PXA250A, CPU_CLASS_XSCALE, "PXA250", pxa2x0_steppings }, { CPU_ID_PXA210A, CPU_CLASS_XSCALE, "PXA210", pxa2x0_steppings }, { CPU_ID_PXA250B, CPU_CLASS_XSCALE, "PXA250", pxa2x0_steppings }, { CPU_ID_PXA210B, CPU_CLASS_XSCALE, "PXA210", pxa2x0_steppings }, { CPU_ID_PXA250C, CPU_CLASS_XSCALE, "PXA255", pxa255_steppings }, { CPU_ID_PXA210C, CPU_CLASS_XSCALE, "PXA210", pxa2x0_steppings }, { CPU_ID_IXP425_533, CPU_CLASS_XSCALE, "IXP425 533MHz", ixp425_steppings }, { CPU_ID_IXP425_400, CPU_CLASS_XSCALE, "IXP425 400MHz", ixp425_steppings }, { CPU_ID_IXP425_266, CPU_CLASS_XSCALE, "IXP425 266MHz", ixp425_steppings }, /* XXX ixp435 steppings? */ { CPU_ID_IXP435, CPU_CLASS_XSCALE, "IXP435", ixp425_steppings }, { CPU_ID_ARM1136JS, CPU_CLASS_ARM11J, "ARM1136J-S", generic_steppings }, { CPU_ID_ARM1136JSR1, CPU_CLASS_ARM11J, "ARM1136J-S R1", generic_steppings }, { CPU_ID_MV88FR131, CPU_CLASS_MARVELL, "Feroceon 88FR131", generic_steppings }, { CPU_ID_MV88FR571_VD, CPU_CLASS_MARVELL, "Feroceon 88FR571-VD", generic_steppings }, { CPU_ID_MV88SV581X_V6, CPU_CLASS_MARVELL, "Sheeva 88SV581x", generic_steppings }, { CPU_ID_ARM_88SV581X_V6, CPU_CLASS_MARVELL, "Sheeva 88SV581x", generic_steppings }, { CPU_ID_MV88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x", generic_steppings }, { CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x", generic_steppings }, { CPU_ID_MV88SV584X, CPU_CLASS_MARVELL, "Sheeva 88SV584x", generic_steppings }, { CPU_ID_ARM_88SV584X, CPU_CLASS_MARVELL, "Sheeva 88SV584x", generic_steppings }, { 0, CPU_CLASS_NONE, NULL, NULL } }; struct cpu_classtab { const char *class_name; const char *class_option; }; const struct cpu_classtab cpu_classes[] = { { "unknown", NULL }, /* CPU_CLASS_NONE */ { "ARM2", "CPU_ARM2" }, /* CPU_CLASS_ARM2 */ { "ARM2as", "CPU_ARM250" }, /* CPU_CLASS_ARM2AS */ { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */ { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */ { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */ { "ARM7TDMI", "CPU_ARM7TDMI" }, /* CPU_CLASS_ARM7TDMI */ { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */ { "ARM9TDMI", "CPU_ARM9TDMI" }, /* CPU_CLASS_ARM9TDMI */ { "ARM9E-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9ES */ { "ARM9EJ-S", "CPU_ARM9E" }, /* CPU_CLASS_ARM9EJS */ { "ARM10E", "CPU_ARM10" }, /* CPU_CLASS_ARM10E */ { "ARM10EJ", "CPU_ARM10" }, /* CPU_CLASS_ARM10EJ */ + { "Cortex-A", "CPU_CORTEXA" }, /* CPU_CLASS_CORTEXA */ { "SA-1", "CPU_SA110" }, /* CPU_CLASS_SA1 */ { "XScale", "CPU_XSCALE_..." }, /* CPU_CLASS_XSCALE */ { "ARM11J", "CPU_ARM11" }, /* CPU_CLASS_ARM11J */ { "Marvell", "CPU_MARVELL" }, /* CPU_CLASS_MARVELL */ }; /* * Report the type of the specified arm processor. This uses the generic and * arm specific information in the cpu structure to identify the processor. * The remaining fields in the cpu structure are filled in appropriately. */ static const char * const wtnames[] = { "write-through", "write-back", "write-back", "**unknown 3**", "**unknown 4**", "write-back-locking", /* XXX XScale-specific? */ "write-back-locking-A", "write-back-locking-B", "**unknown 8**", "**unknown 9**", "**unknown 10**", "**unknown 11**", "**unknown 12**", "**unknown 13**", "write-back-locking-C", "**unknown 15**", }; static void print_enadis(int enadis, char *s) { printf(" %s %sabled", s, (enadis == 0) ? "dis" : "en"); } extern int ctrl; enum cpu_class cpu_class = CPU_CLASS_NONE; u_int cpu_pfr(int num) { u_int feat; switch (num) { case 0: __asm __volatile("mrc p15, 0, %0, c0, c1, 0" : "=r" (feat)); break; case 1: __asm __volatile("mrc p15, 0, %0, c0, c1, 1" : "=r" (feat)); break; default: panic("Processor Feature Register %d not implemented", num); break; } return (feat); } static void identify_armv7(void) { u_int feature; printf("Supported features:"); /* Get Processor Feature Register 0 */ feature = cpu_pfr(0); if (feature & ARM_PFR0_ARM_ISA_MASK) printf(" ARM_ISA"); if (feature & ARM_PFR0_THUMB2) printf(" THUMB2"); else if (feature & ARM_PFR0_THUMB) printf(" THUMB"); if (feature & ARM_PFR0_JAZELLE_MASK) printf(" JAZELLE"); if (feature & ARM_PFR0_THUMBEE_MASK) printf(" THUMBEE"); /* Get Processor Feature Register 1 */ feature = cpu_pfr(1); if (feature & ARM_PFR1_ARMV4_MASK) printf(" ARMv4"); if (feature & ARM_PFR1_SEC_EXT_MASK) printf(" Security_Ext"); if (feature & ARM_PFR1_MICROCTRL_MASK) printf(" M_profile"); printf("\n"); } void identify_arm_cpu(void) { u_int cpuid, reg, size, sets, ways; u_int8_t type, linesize; int i; cpuid = cpu_id(); if (cpuid == 0) { printf("Processor failed probe - no CPU ID\n"); return; } for (i = 0; cpuids[i].cpuid != 0; i++) if (cpuids[i].cpuid == (cpuid & CPU_ID_CPU_MASK)) { cpu_class = cpuids[i].cpu_class; printf("CPU: %s %s (%s core)\n", cpuids[i].cpu_name, cpuids[i].cpu_steppings[cpuid & CPU_ID_REVISION_MASK], cpu_classes[cpu_class].class_name); break; } if (cpuids[i].cpuid == 0) printf("unknown CPU (ID = 0x%x)\n", cpuid); printf(" "); if ((cpuid & CPU_ID_ARCH_MASK) == CPU_ID_CPUID_SCHEME) { identify_armv7(); } else { if (ctrl & CPU_CONTROL_BEND_ENABLE) printf(" Big-endian"); else printf(" Little-endian"); switch (cpu_class) { case CPU_CLASS_ARM6: case CPU_CLASS_ARM7: case CPU_CLASS_ARM7TDMI: case CPU_CLASS_ARM8: print_enadis(ctrl & CPU_CONTROL_IDC_ENABLE, "IDC"); break; case CPU_CLASS_ARM9TDMI: case CPU_CLASS_ARM9ES: case CPU_CLASS_ARM9EJS: case CPU_CLASS_ARM10E: case CPU_CLASS_ARM10EJ: case CPU_CLASS_SA1: case CPU_CLASS_XSCALE: case CPU_CLASS_ARM11J: case CPU_CLASS_MARVELL: print_enadis(ctrl & CPU_CONTROL_DC_ENABLE, "DC"); print_enadis(ctrl & CPU_CONTROL_IC_ENABLE, "IC"); #ifdef CPU_XSCALE_81342 print_enadis(ctrl & CPU_CONTROL_L2_ENABLE, "L2"); #endif #if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) i = sheeva_control_ext(0, 0); print_enadis(i & MV_WA_ENABLE, "WA"); print_enadis(i & MV_DC_STREAM_ENABLE, "DC streaming"); printf("\n "); print_enadis((i & MV_BTB_DISABLE) == 0, "BTB"); print_enadis(i & MV_L2_ENABLE, "L2"); print_enadis((i & MV_L2_PREFETCH_DISABLE) == 0, "L2 prefetch"); printf("\n "); #endif break; default: break; } } print_enadis(ctrl & CPU_CONTROL_WBUF_ENABLE, "WB"); if (ctrl & CPU_CONTROL_LABT_ENABLE) printf(" LABT"); else printf(" EABT"); print_enadis(ctrl & CPU_CONTROL_BPRD_ENABLE, "branch prediction"); printf("\n"); if (arm_cache_level) { printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1, arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1); i = 0; while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) { printf("Cache level %d: \n", i + 1); if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || type == CACHE_SEP_CACHE) { reg = arm_cache_type[2 * i]; ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1; sets = CPUV7_CT_xSIZE_SET(reg) + 1; linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4); size = (ways * sets * linesize) / 1024; if (type == CACHE_UNI_CACHE) printf(" %dKB/%dB %d-way unified cache", size, linesize,ways); else printf(" %dKB/%dB %d-way data cache", size, linesize, ways); if (reg & CPUV7_CT_CTYPE_WT) printf(" WT"); if (reg & CPUV7_CT_CTYPE_WB) printf(" WB"); if (reg & CPUV7_CT_CTYPE_RA) printf(" Read-Alloc"); if (reg & CPUV7_CT_CTYPE_WA) printf(" Write-Alloc"); printf("\n"); } if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { reg = arm_cache_type[(2 * i) + 1]; ways = CPUV7_CT_xSIZE_ASSOC(reg) + 1; sets = CPUV7_CT_xSIZE_SET(reg) + 1; linesize = 1 << (CPUV7_CT_xSIZE_LEN(reg) + 4); size = (ways * sets * linesize) / 1024; printf(" %dKB/%dB %d-way instruction cache", size, linesize, ways); if (reg & CPUV7_CT_CTYPE_WT) printf(" WT"); if (reg & CPUV7_CT_CTYPE_WB) printf(" WB"); if (reg & CPUV7_CT_CTYPE_RA) printf(" Read-Alloc"); if (reg & CPUV7_CT_CTYPE_WA) printf(" Write-Alloc"); printf("\n"); } i++; } } else { /* Print cache info. */ if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) return; if (arm_pcache_unified) { printf(" %dKB/%dB %d-way %s unified cache\n", arm_pdcache_size / 1024, arm_pdcache_line_size, arm_pdcache_ways, wtnames[arm_pcache_type]); } else { printf(" %dKB/%dB %d-way instruction cache\n", arm_picache_size / 1024, arm_picache_line_size, arm_picache_ways); printf(" %dKB/%dB %d-way %s data cache\n", arm_pdcache_size / 1024, arm_pdcache_line_size, arm_pdcache_ways, wtnames[arm_pcache_type]); } } } Index: projects/armv6/sys/arm/arm/locore.S =================================================================== --- projects/armv6/sys/arm/arm/locore.S (revision 225145) +++ projects/armv6/sys/arm/arm/locore.S (revision 225146) @@ -1,353 +1,353 @@ /* $NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $ */ /*- * Copyright (C) 1994-1997 Mark Brinicombe * Copyright (C) 1994 Brini * 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 Brini. * 4. The name of Brini may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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 "assym.s" #include #include #include #include __FBSDID("$FreeBSD$"); /* What size should this really be ? It is only used by initarm() */ #define INIT_ARM_STACK_SIZE 2048 /* * This is for kvm_mkdb, and should be the address of the beginning * of the kernel text segment (not necessarily the same as kernbase). */ #define CPWAIT_BRANCH \ sub pc, pc, #4 #define CPWAIT(tmp) \ mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\ mov tmp, tmp /* wait for it to complete */ ;\ CPWAIT_BRANCH /* branch to next insn */ .text .align 0 .globl kernbase .set kernbase,KERNBASE .globl physaddr .set physaddr,PHYSADDR ENTRY_NP(btext) /* * On entry: * r0 - metadata pointer or 0 * r1 - if (r0 == 0) then metadata pointer */ ASENTRY_NP(_start) /* Move metadata ptr to r12 (ip) */ mov ip, r0 ldr r0, =0 cmp ip, r0 bne 1f mov ip, r1 1: /* Make sure interrupts are disabled. */ mrs r7, cpsr orr r7, r7, #(I32_bit|F32_bit) msr cpsr_c, r7 #if defined (FLASHADDR) && defined(LOADERRAMADDR) /* Check if we're running from flash. */ ldr r7, =FLASHADDR /* * If we're running with MMU disabled, test against the * physical address instead. */ mrc p15, 0, r2, c1, c0, 0 ands r2, r2, #CPU_CONTROL_MMU_ENABLE ldreq r8, =PHYSADDR ldrne r8, =LOADERRAMADDR cmp r7, r8 bls flash_lower cmp r7, pc bhi from_ram b do_copy flash_lower: cmp r8, pc bls from_ram do_copy: ldr r9, =KERNBASE adr r1, _start ldr r0, Lreal_start ldr r2, Lend sub r2, r2, r0 sub r0, r0, r9 add r0, r0, r8 mov r4, r0 bl memcpy ldr r0, Lram_offset add pc, r4, r0 Lram_offset: .word from_ram-_C_LABEL(_start) from_ram: nop #endif adr r7, Lunmapped bic r7, r7, #0xf0000000 orr r7, r7, #PHYSADDR disable_mmu: /* Disable MMU for a while */ mrc p15, 0, r2, c1, c0, 0 bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\ CPU_CONTROL_WBUF_ENABLE) bic r2, r2, #(CPU_CONTROL_IC_ENABLE) bic r2, r2, #(CPU_CONTROL_BPRD_ENABLE) mcr p15, 0, r2, c1, c0, 0 nop nop nop mov pc, r7 Lunmapped: #ifdef STARTUP_PAGETABLE_ADDR /* build page table from scratch */ ldr r0, Lstartup_pagetable adr r4, mmu_init_table b 3f 2: str r3, [r0, r2] add r2, r2, #4 add r3, r3, #(L1_S_SIZE) adds r1, r1, #-1 bhi 2b 3: ldmia r4!, {r1,r2,r3} /* # of sections, VA, PA|attr */ cmp r1, #0 adrne r5, 2b bicne r5, r5, #0xf0000000 orrne r5, r5, #PHYSADDR movne pc, r5 mcr p15, 0, r0, c2, c0, 0 /* Set TTB */ mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */ -#if defined(CPU_ARM11) || defined(CPU_MV_PJ4B) +#if defined(CPU_ARM11) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) mov r0, #0 mcr p15, 0, r0, c13, c0, 1 /* Set ASID to 0 */ #endif /* Set the Domain Access register. Very important! */ mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) mcr p15, 0, r0, c3, c0, 0 /* Enable MMU */ mrc p15, 0, r0, c1, c0, 0 -#if defined(CPU_ARM11) || defined(CPU_MV_PJ4B) +#if defined(CPU_ARM11) || defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B) orr r0, r0, #CPU_CONTROL_V6_EXTPAGE #endif orr r0, r0, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE) mcr p15, 0, r0, c1, c0, 0 nop nop nop CPWAIT(r0) #endif mmu_done: nop adr r1, .Lstart ldmia r1, {r1, r2, sp} /* Set initial stack and */ sub r2, r2, r1 /* get zero init data */ mov r3, #0 .L1: str r3, [r1], #0x0004 /* get zero init data */ subs r2, r2, #4 bgt .L1 ldr pc, .Lvirt_done virt_done: mov r0, ip /* Load argument: metadata ptr */ mov fp, #0 /* trace back starts here */ bl _C_LABEL(initarm) /* Off we go */ /* init arm will return the new stack pointer. */ mov sp, r0 bl _C_LABEL(mi_startup) /* call mi_startup()! */ adr r0, .Lmainreturned b _C_LABEL(panic) /* NOTREACHED */ #ifdef STARTUP_PAGETABLE_ADDR #define MMU_INIT(va,pa,n_sec,attr) \ .word n_sec ; \ .word 4*((va)>>L1_S_SHIFT) ; \ .word (pa)|(attr) ; Lvirtaddr: .word KERNVIRTADDR Lphysaddr: .word KERNPHYSADDR Lreal_start: .word _start Lend: .word _edata Lstartup_pagetable: .word STARTUP_PAGETABLE_ADDR mmu_init_table: /* fill all table VA==PA */ /* map SDRAM VA==PA, WT cacheable */ MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) /* map VA 0xc0000000..0xc3ffffff to PA */ MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)) .word 0 /* end of table */ #endif .Lstart: .word _edata .word _end .word svcstk + INIT_ARM_STACK_SIZE #if defined(FLASHADDR) && defined(LOADERRAMADDR) .L_arm_memcpy: .word _C_LABEL(_arm_memcpy) #endif .Lvirt_done: .word virt_done .Lmainreturned: .asciz "main() returned" .align 0 .bss svcstk: .space INIT_ARM_STACK_SIZE .text .align 0 .Lcpufuncs: .word _C_LABEL(cpufuncs) ENTRY_NP(cpu_halt) mrs r2, cpsr bic r2, r2, #(PSR_MODE) orr r2, r2, #(PSR_SVC32_MODE) orr r2, r2, #(I32_bit | F32_bit) msr cpsr_all, r2 ldr r4, .Lcpu_reset_address ldr r4, [r4] ldr r0, .Lcpufuncs mov lr, pc ldr pc, [r0, #CF_IDCACHE_WBINV_ALL] mov lr, pc ldr pc, [r0, #CF_L2CACHE_WBINV_ALL] /* * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's * necessary. */ ldr r1, .Lcpu_reset_needs_v4_MMU_disable ldr r1, [r1] cmp r1, #0 mov r2, #0 /* * MMU & IDC off, 32 bit program & data space * Hurl ourselves into the ROM */ mov r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE) mcr 15, 0, r0, c1, c0, 0 mcrne 15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */ mov pc, r4 /* * _cpu_reset_address contains the address to branch to, to complete * the cpu reset after turning the MMU off * This variable is provided by the hardware specific code */ .Lcpu_reset_address: .word _C_LABEL(cpu_reset_address) /* * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the * v4 MMU disable instruction needs executing... it is an illegal instruction * on f.e. ARM6/7 that locks up the computer in an endless illegal * instruction / data-abort / reset loop. */ .Lcpu_reset_needs_v4_MMU_disable: .word _C_LABEL(cpu_reset_needs_v4_MMU_disable) /* * setjump + longjmp */ ENTRY(setjmp) stmia r0, {r4-r14} mov r0, #0x00000000 RET ENTRY(longjmp) ldmia r0, {r4-r14} mov r0, #0x00000001 RET .data .global _C_LABEL(esym) _C_LABEL(esym): .word _C_LABEL(end) ENTRY_NP(abort) b _C_LABEL(abort) ENTRY_NP(sigcode) mov r0, sp swi SYS_sigreturn /* Well if that failed we better exit quick ! */ swi SYS_exit b . - 8 .align 0 .global _C_LABEL(esigcode) _C_LABEL(esigcode): .data .global szsigcode szsigcode: .long esigcode-sigcode /* End of locore.S */ Index: projects/armv6/sys/arm/arm/swtch.S =================================================================== --- projects/armv6/sys/arm/arm/swtch.S (revision 225145) +++ projects/armv6/sys/arm/arm/swtch.S (revision 225146) @@ -1,510 +1,510 @@ /* $NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $ */ /*- * Copyright 2003 Wasabi Systems, Inc. * All rights reserved. * * Written by Steve C. Woodford for Wasabi Systems, Inc. * * 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 for the NetBSD Project by * Wasabi Systems, Inc. * 4. The name of Wasabi Systems, Inc. may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * 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. */ /*- * Copyright (c) 1994-1998 Mark Brinicombe. * Copyright (c) 1994 Brini. * All rights reserved. * * This code is derived from software written for Brini by Mark Brinicombe * * 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 Brini. * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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. * * RiscBSD kernel project * * cpuswitch.S * * cpu switching functions * * Created : 15/10/94 * */ #include "assym.s" #include #include #include __FBSDID("$FreeBSD$"); /* * New experimental definitions of IRQdisable and IRQenable * These keep FIQ's enabled since FIQ's are special. */ #define DOMAIN_CLIENT 0x01 #define IRQdisable \ mrs r14, cpsr ; \ orr r14, r14, #(I32_bit) ; \ msr cpsr_c, r14 ; \ #define IRQenable \ mrs r14, cpsr ; \ bic r14, r14, #(I32_bit) ; \ msr cpsr_c, r14 ; \ /* * These are used for switching the translation table/DACR. * Since the vector page can be invalid for a short time, we must * disable both regular IRQs *and* FIQs. * * XXX: This is not necessary if the vector table is relocated. */ #define IRQdisableALL \ mrs r14, cpsr ; \ orr r14, r14, #(I32_bit | F32_bit) ; \ msr cpsr_c, r14 #define IRQenableALL \ mrs r14, cpsr ; \ bic r14, r14, #(I32_bit | F32_bit) ; \ msr cpsr_c, r14 .Lcurpcb: .word _C_LABEL(__pcpu) + PC_CURPCB .Lcpufuncs: .word _C_LABEL(cpufuncs) .Lblock_userspace_access: .word _C_LABEL(block_userspace_access) .Lcpu_do_powersave: .word _C_LABEL(cpu_do_powersave) .Lblocked_lock: .word _C_LABEL(blocked_lock) ENTRY(cpu_throw) mov r5, r1 /* * r5 = newtd */ ldr r7, [r5, #(TD_PCB)] /* r7 = new thread's PCB */ /* Switch to lwp0 context */ ldr r9, .Lcpufuncs -#if !defined(CPU_ARM11) && !defined(CPU_MV_PJ4B) +#if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B) mov lr, pc ldr pc, [r9, #CF_IDCACHE_WBINV_ALL] #endif ldr r0, [r7, #(PCB_PL1VEC)] ldr r1, [r7, #(PCB_DACR)] /* * r0 = Pointer to L1 slot for vector_page (or NULL) * r1 = lwp0's DACR * r5 = lwp0 * r6 = exit func * r7 = lwp0's PCB * r9 = cpufuncs */ /* * Ensure the vector table is accessible by fixing up lwp0's L1 */ cmp r0, #0 /* No need to fixup vector table? */ ldrne r3, [r0] /* But if yes, fetch current value */ ldrne r2, [r7, #(PCB_L1VEC)] /* Fetch new vector_page value */ mcr p15, 0, r1, c3, c0, 0 /* Update DACR for lwp0's context */ cmpne r3, r2 /* Stuffing the same value? */ strne r2, [r0] /* Store if not. */ #ifdef PMAP_INCLUDE_PTE_SYNC /* * Need to sync the cache to make sure that last store is * visible to the MMU. */ movne r1, #4 movne lr, pc ldrne pc, [r9, #CF_DCACHE_WB_RANGE] #endif /* PMAP_INCLUDE_PTE_SYNC */ /* * Note: We don't do the same optimisation as cpu_switch() with * respect to avoiding flushing the TLB if we're switching to * the same L1 since this process' VM space may be about to go * away, so we don't want *any* turds left in the TLB. */ /* Switch the memory to the new process */ ldr r0, [r7, #(PCB_PAGEDIR)] mov lr, pc ldr pc, [r9, #CF_CONTEXT_SWITCH] /* Restore all the save registers */ #ifndef _ARM_ARCH_5E add r1, r7, #PCB_R8 ldmia r1, {r8-r13} #else ldr r8, [r7, #(PCB_R8)] ldr r9, [r7, #(PCB_R9)] ldr r10, [r7, #(PCB_R10)] ldr r11, [r7, #(PCB_R11)] ldr r12, [r7, #(PCB_R12)] ldr r13, [r7, #(PCB_SP)] #endif /* We have a new curthread now so make a note it */ ldr r6, .Lcurthread str r5, [r6] /* Set the new tp */ ldr r6, [r5, #(TD_MD + MD_TP)] ldr r4, =ARM_TP_ADDRESS str r6, [r4] ldr r6, [r5, #(TD_MD + MD_RAS_START)] str r6, [r4, #4] /* ARM_RAS_START */ ldr r6, [r5, #(TD_MD + MD_RAS_END)] str r6, [r4, #8] /* ARM_RAS_END */ /* Hook in a new pcb */ ldr r6, .Lcurpcb str r7, [r6] ldmfd sp!, {r4-r7, pc} ENTRY(cpu_switch) stmfd sp!, {r4-r7, lr} mov r6, r2 /* Save the mutex */ .Lswitch_resume: /* rem: r0 = old lwp */ /* rem: interrupts are disabled */ #ifdef MULTIPROCESSOR /* XXX use curcpu() */ ldr r2, .Lcpu_info_store str r2, [r6, #(L_CPU)] #endif /* Process is now on a processor. */ /* We have a new curthread now so make a note it */ ldr r7, .Lcurthread str r1, [r7] /* Hook in a new pcb */ ldr r7, .Lcurpcb ldr r2, [r1, #TD_PCB] str r2, [r7] /* rem: r1 = new process */ /* rem: interrupts are enabled */ /* Stage two : Save old context */ /* Get the user structure for the old thread. */ ldr r2, [r0, #(TD_PCB)] mov r4, r0 /* Save the old thread. */ /* Save all the registers in the old thread's pcb */ #ifndef _ARM_ARCH_5E add r7, r2, #(PCB_R8) stmia r7, {r8-r13} #else strd r8, [r2, #(PCB_R8)] strd r10, [r2, #(PCB_R10)] strd r12, [r2, #(PCB_R12)] #endif str pc, [r2, #(PCB_PC)] /* * NOTE: We can now use r8-r13 until it is time to restore * them for the new process. */ /* Store the old tp */ ldr r3, =ARM_TP_ADDRESS ldr r9, [r3] str r9, [r0, #(TD_MD + MD_TP)] ldr r9, [r3, #4] str r9, [r0, #(TD_MD + MD_RAS_START)] ldr r9, [r3, #8] str r9, [r0, #(TD_MD + MD_RAS_END)] /* Set the new tp */ ldr r9, [r1, #(TD_MD + MD_TP)] str r9, [r3] ldr r9, [r1, #(TD_MD + MD_RAS_START)] str r9, [r3, #4] ldr r9, [r1, #(TD_MD + MD_RAS_END)] str r9, [r3, #8] /* Get the user structure for the new process in r9 */ ldr r9, [r1, #(TD_PCB)] /* r1 now free! */ mrs r3, cpsr /* * We can do that, since * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE */ orr r8, r3, #(PSR_UND32_MODE) msr cpsr_c, r8 str sp, [r2, #(PCB_UND_SP)] msr cpsr_c, r3 /* Restore the old mode */ /* rem: r8 = old PCB */ /* rem: r9 = new PCB */ /* rem: interrupts are enabled */ /* What else needs to be saved Only FPA stuff when that is supported */ /* Third phase : restore saved context */ /* rem: r8 = old PCB */ /* rem: r9 = new PCB */ /* rem: interrupts are enabled */ ldr r5, [r9, #(PCB_DACR)] /* r5 = new DACR */ mov r2, #DOMAIN_CLIENT cmp r5, r2, lsl #(PMAP_DOMAIN_KERNEL * 2) /* Sw to kernel thread? */ beq .Lcs_context_switched /* Yup. Don't flush cache */ mrc p15, 0, r0, c3, c0, 0 /* r0 = old DACR */ /* * Get the new L1 table pointer into r11. If we're switching to * an LWP with the same address space as the outgoing one, we can * skip the cache purge and the TTB load. * * To avoid data dep stalls that would happen anyway, we try * and get some useful work done in the mean time. */ mrc p15, 0, r10, c2, c0, 0 /* r10 = old L1 */ ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */ teq r10, r11 /* Same L1? */ cmpeq r0, r5 /* Same DACR? */ beq .Lcs_context_switched /* yes! */ -#if !defined(CPU_ARM11) && !defined(CPU_MV_PJ4B) +#if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B) /* * Definately need to flush the cache. */ ldr r1, .Lcpufuncs mov lr, pc ldr pc, [r1, #CF_IDCACHE_WBINV_ALL] #endif .Lcs_cache_purge_skipped: /* rem: r6 = lock */ /* rem: r9 = new PCB */ /* rem: r10 = old L1 */ /* rem: r11 = new L1 */ mov r2, #0x00000000 ldr r7, [r9, #(PCB_PL1VEC)] /* * Ensure the vector table is accessible by fixing up the L1 */ cmp r7, #0 /* No need to fixup vector table? */ ldrne r2, [r7] /* But if yes, fetch current value */ ldrne r0, [r9, #(PCB_L1VEC)] /* Fetch new vector_page value */ mcr p15, 0, r5, c3, c0, 0 /* Update DACR for new context */ cmpne r2, r0 /* Stuffing the same value? */ #ifndef PMAP_INCLUDE_PTE_SYNC strne r0, [r7] /* Nope, update it */ #else beq .Lcs_same_vector str r0, [r7] /* Otherwise, update it */ -#if !defined(CPU_ARM11) && !defined(CPU_MV_PJ4B) +#if !defined(CPU_ARM11) && !defined(CPU_CORTEXA) && !defined(CPU_MV_PJ4B) /* * Need to sync the cache to make sure that last store is * visible to the MMU. */ ldr r2, .Lcpufuncs mov r0, r7 mov r1, #4 mov lr, pc ldr pc, [r2, #CF_DCACHE_WB_RANGE] #endif .Lcs_same_vector: #endif /* PMAP_INCLUDE_PTE_SYNC */ cmp r10, r11 /* Switching to the same L1? */ ldr r10, .Lcpufuncs beq .Lcs_same_l1 /* Yup. */ /* * Do a full context switch, including full TLB flush. */ mov r0, r11 mov lr, pc ldr pc, [r10, #CF_CONTEXT_SWITCH] b .Lcs_context_switched /* * We're switching to a different process in the same L1. * In this situation, we only need to flush the TLB for the * vector_page mapping, and even then only if r7 is non-NULL. */ .Lcs_same_l1: cmp r7, #0 movne r0, #0 /* We *know* vector_page's VA is 0x0 */ movne lr, pc ldrne pc, [r10, #CF_TLB_FLUSHID_SE] /* * We can do that, since * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE */ .Lcs_context_switched: /* Release the old thread */ str r6, [r4, #TD_LOCK] ldr r6, .Lblocked_lock ldr r3, .Lcurthread ldr r3, [r3] 1: ldr r4, [r3, #TD_LOCK] cmp r4, r6 beq 1b /* XXXSCW: Safe to re-enable FIQs here */ /* rem: r9 = new PCB */ mrs r3, cpsr /* * We can do that, since * PSR_SVC32_MODE|PSR_UND32_MODE == MSR_UND32_MODE */ orr r2, r3, #(PSR_UND32_MODE) msr cpsr_c, r2 ldr sp, [r9, #(PCB_UND_SP)] msr cpsr_c, r3 /* Restore the old mode */ /* Restore all the save registers */ #ifndef _ARM_ARCH_5E add r7, r9, #PCB_R8 ldmia r7, {r8-r13} sub r7, r7, #PCB_R8 /* restore PCB pointer */ #else mov r7, r9 ldr r8, [r7, #(PCB_R8)] ldr r9, [r7, #(PCB_R9)] ldr r10, [r7, #(PCB_R10)] ldr r11, [r7, #(PCB_R11)] ldr r12, [r7, #(PCB_R12)] ldr r13, [r7, #(PCB_SP)] #endif /* rem: r6 = lock */ /* rem: r7 = new pcb */ #ifdef ARMFPE add r0, r7, #(USER_SIZE) & 0x00ff add r0, r0, #(USER_SIZE) & 0xff00 bl _C_LABEL(arm_fpe_core_changecontext) #endif /* rem: r5 = new lwp's proc */ /* rem: r6 = lock */ /* rem: r7 = new PCB */ .Lswitch_return: /* * Pull the registers that got pushed when either savectx() or * cpu_switch() was called and return. */ ldmfd sp!, {r4-r7, pc} #ifdef DIAGNOSTIC .Lswitch_bogons: adr r0, .Lswitch_panic_str bl _C_LABEL(panic) 1: nop b 1b .Lswitch_panic_str: .asciz "cpu_switch: sched_qs empty with non-zero sched_whichqs!\n" #endif ENTRY(savectx) stmfd sp!, {r4-r7, lr} /* * r0 = pcb */ /* Store all the registers in the process's pcb */ add r2, r0, #(PCB_R8) stmia r2, {r8-r13} ldmfd sp!, {r4-r7, pc} ENTRY(fork_trampoline) mov r1, r5 mov r2, sp mov r0, r4 mov fp, #0 bl _C_LABEL(fork_exit) /* Kill irq"s */ mrs r0, cpsr orr r0, r0, #(I32_bit|F32_bit) msr cpsr_c, r0 DO_AST PULLFRAME movs pc, lr /* Exit */ AST_LOCALS Index: projects/armv6/sys/arm/include/armreg.h =================================================================== --- projects/armv6/sys/arm/include/armreg.h (revision 225145) +++ projects/armv6/sys/arm/include/armreg.h (revision 225146) @@ -1,396 +1,401 @@ /* $NetBSD: armreg.h,v 1.37 2007/01/06 00:50:54 christos Exp $ */ /*- * Copyright (c) 1998, 2001 Ben Harris * Copyright (c) 1994-1996 Mark Brinicombe. * Copyright (c) 1994 Brini. * All rights reserved. * * This code is derived from software written for Brini by Mark Brinicombe * * 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 Brini. * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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. * * $FreeBSD$ */ #ifndef MACHINE_ARMREG_H #define MACHINE_ARMREG_H #define INSN_SIZE 4 #define INSN_COND_MASK 0xf0000000 /* Condition mask */ #define PSR_MODE 0x0000001f /* mode mask */ #define PSR_USR26_MODE 0x00000000 #define PSR_FIQ26_MODE 0x00000001 #define PSR_IRQ26_MODE 0x00000002 #define PSR_SVC26_MODE 0x00000003 #define PSR_USR32_MODE 0x00000010 #define PSR_FIQ32_MODE 0x00000011 #define PSR_IRQ32_MODE 0x00000012 #define PSR_SVC32_MODE 0x00000013 #define PSR_ABT32_MODE 0x00000017 #define PSR_UND32_MODE 0x0000001b #define PSR_SYS32_MODE 0x0000001f #define PSR_32_MODE 0x00000010 #define PSR_FLAGS 0xf0000000 /* flags */ #define PSR_C_bit (1 << 29) /* carry */ /* The high-order byte is always the implementor */ #define CPU_ID_IMPLEMENTOR_MASK 0xff000000 #define CPU_ID_ARM_LTD 0x41000000 /* 'A' */ #define CPU_ID_DEC 0x44000000 /* 'D' */ #define CPU_ID_INTEL 0x69000000 /* 'i' */ #define CPU_ID_TI 0x54000000 /* 'T' */ #define CPU_ID_FARADAY 0x66000000 /* 'f' */ /* How to decide what format the CPUID is in. */ #define CPU_ID_ISOLD(x) (((x) & 0x0000f000) == 0x00000000) #define CPU_ID_IS7(x) (((x) & 0x0000f000) == 0x00007000) #define CPU_ID_ISNEW(x) (!CPU_ID_ISOLD(x) && !CPU_ID_IS7(x)) /* On ARM3 and ARM6, this byte holds the foundry ID. */ #define CPU_ID_FOUNDRY_MASK 0x00ff0000 #define CPU_ID_FOUNDRY_VLSI 0x00560000 /* On ARM7 it holds the architecture and variant (sub-model) */ #define CPU_ID_7ARCH_MASK 0x00800000 #define CPU_ID_7ARCH_V3 0x00000000 #define CPU_ID_7ARCH_V4T 0x00800000 #define CPU_ID_7VARIANT_MASK 0x007f0000 /* On more recent ARMs, it does the same, but in a different format */ #define CPU_ID_ARCH_MASK 0x000f0000 #define CPU_ID_ARCH_V3 0x00000000 #define CPU_ID_ARCH_V4 0x00010000 #define CPU_ID_ARCH_V4T 0x00020000 #define CPU_ID_ARCH_V5 0x00030000 #define CPU_ID_ARCH_V5T 0x00040000 #define CPU_ID_ARCH_V5TE 0x00050000 #define CPU_ID_ARCH_V5TEJ 0x00060000 #define CPU_ID_ARCH_V6 0x00070000 #define CPU_ID_CPUID_SCHEME 0x000f0000 #define CPU_ID_VARIANT_MASK 0x00f00000 /* Next three nybbles are part number */ #define CPU_ID_PARTNO_MASK 0x0000fff0 /* Intel XScale has sub fields in part number */ #define CPU_ID_XSCALE_COREGEN_MASK 0x0000e000 /* core generation */ #define CPU_ID_XSCALE_COREREV_MASK 0x00001c00 /* core revision */ #define CPU_ID_XSCALE_PRODUCT_MASK 0x000003f0 /* product number */ /* And finally, the revision number. */ #define CPU_ID_REVISION_MASK 0x0000000f /* Individual CPUs are probably best IDed by everything but the revision. */ #define CPU_ID_CPU_MASK 0xfffffff0 /* Fake CPU IDs for ARMs without CP15 */ #define CPU_ID_ARM2 0x41560200 #define CPU_ID_ARM250 0x41560250 /* Pre-ARM7 CPUs -- [15:12] == 0 */ #define CPU_ID_ARM3 0x41560300 #define CPU_ID_ARM600 0x41560600 #define CPU_ID_ARM610 0x41560610 #define CPU_ID_ARM620 0x41560620 /* ARM7 CPUs -- [15:12] == 7 */ #define CPU_ID_ARM700 0x41007000 /* XXX This is a guess. */ #define CPU_ID_ARM710 0x41007100 #define CPU_ID_ARM7500 0x41027100 #define CPU_ID_ARM710A 0x41047100 /* inc ARM7100 */ #define CPU_ID_ARM7500FE 0x41077100 #define CPU_ID_ARM710T 0x41807100 #define CPU_ID_ARM720T 0x41807200 #define CPU_ID_ARM740T8K 0x41807400 /* XXX no MMU, 8KB cache */ #define CPU_ID_ARM740T4K 0x41817400 /* XXX no MMU, 4KB cache */ /* Post-ARM7 CPUs */ #define CPU_ID_ARM810 0x41018100 #define CPU_ID_ARM920T 0x41129200 #define CPU_ID_ARM920T_ALT 0x41009200 #define CPU_ID_ARM922T 0x41029220 #define CPU_ID_ARM926EJS 0x41069260 #define CPU_ID_ARM940T 0x41029400 /* XXX no MMU */ #define CPU_ID_ARM946ES 0x41049460 /* XXX no MMU */ #define CPU_ID_ARM966ES 0x41049660 /* XXX no MMU */ #define CPU_ID_ARM966ESR1 0x41059660 /* XXX no MMU */ #define CPU_ID_ARM1020E 0x4115a200 /* (AKA arm10 rev 1) */ #define CPU_ID_ARM1022ES 0x4105a220 #define CPU_ID_ARM1026EJS 0x4106a260 #define CPU_ID_ARM1136JS 0x4107b360 #define CPU_ID_ARM1136JSR1 0x4117b360 +#define CPU_ID_CORTEXA8R1 0x411fc080 +#define CPU_ID_CORTEXA8R2 0x412fc080 +#define CPU_ID_CORTEXA8R3 0x413fc080 +#define CPU_ID_CORTEXA9R1 0x411fc090 +#define CPU_ID_CORTEXA9R2 0x412fc090 #define CPU_ID_SA110 0x4401a100 #define CPU_ID_SA1100 0x4401a110 #define CPU_ID_TI925T 0x54029250 #define CPU_ID_MV88FR131 0x56251310 /* Marvell Feroceon 88FR131 Core */ #define CPU_ID_MV88FR331 0x56153310 /* Marvell Feroceon 88FR331 Core */ #define CPU_ID_MV88FR571_VD 0x56155710 /* Marvell Feroceon 88FR571-VD Core (ID from datasheet) */ /* * LokiPlus core has also ID set to 0x41159260 and this define cause execution of unsupported * L2-cache instructions so need to disable it. 0x41159260 is a generic ARM926E-S ID. */ #ifdef SOC_MV_LOKIPLUS #define CPU_ID_MV88FR571_41 0x00000000 #else #define CPU_ID_MV88FR571_41 0x41159260 /* Marvell Feroceon 88FR571-VD Core (actual ID from CPU reg) */ #endif #define CPU_ID_MV88SV581X_V6 0x560F5810 /* Marvell Sheeva 88SV581x v6 Core */ #define CPU_ID_MV88SV581X_V7 0x561F5810 /* Marvell Sheeva 88SV581x v7 Core */ #define CPU_ID_MV88SV584X 0x561F5840 /* Marvell Sheeva 88SV584x v6 Core */ /* Marvell's CPUIDs with ARM ID in implementor field */ #define CPU_ID_ARM_88SV581X_V6 0x410fb760 /* Marvell Sheeva 88SV581x v6 Core */ #define CPU_ID_ARM_88SV581X_V7 0x413FC080 /* Marvell Sheeva 88SV581x v7 Core */ #define CPU_ID_ARM_88SV584X 0x410FB024 /* Marvell Sheeva 88SV584x v6 Core */ #define CPU_ID_FA526 0x66015260 #define CPU_ID_FA626TE 0x66056260 #define CPU_ID_SA1110 0x6901b110 #define CPU_ID_IXP1200 0x6901c120 #define CPU_ID_80200 0x69052000 #define CPU_ID_PXA250 0x69052100 /* sans core revision */ #define CPU_ID_PXA210 0x69052120 #define CPU_ID_PXA250A 0x69052100 /* 1st version Core */ #define CPU_ID_PXA210A 0x69052120 /* 1st version Core */ #define CPU_ID_PXA250B 0x69052900 /* 3rd version Core */ #define CPU_ID_PXA210B 0x69052920 /* 3rd version Core */ #define CPU_ID_PXA250C 0x69052d00 /* 4th version Core */ #define CPU_ID_PXA210C 0x69052d20 /* 4th version Core */ #define CPU_ID_PXA27X 0x69054110 #define CPU_ID_80321_400 0x69052420 #define CPU_ID_80321_600 0x69052430 #define CPU_ID_80321_400_B0 0x69052c20 #define CPU_ID_80321_600_B0 0x69052c30 #define CPU_ID_80219_400 0x69052e20 /* A0 stepping/revision. */ #define CPU_ID_80219_600 0x69052e30 /* A0 stepping/revision. */ #define CPU_ID_81342 0x69056810 #define CPU_ID_IXP425 0x690541c0 #define CPU_ID_IXP425_533 0x690541c0 #define CPU_ID_IXP425_400 0x690541d0 #define CPU_ID_IXP425_266 0x690541f0 #define CPU_ID_IXP435 0x69054040 #define CPU_ID_IXP465 0x69054200 /* ARM3-specific coprocessor 15 registers */ #define ARM3_CP15_FLUSH 1 #define ARM3_CP15_CONTROL 2 #define ARM3_CP15_CACHEABLE 3 #define ARM3_CP15_UPDATEABLE 4 #define ARM3_CP15_DISRUPTIVE 5 /* ARM3 Control register bits */ #define ARM3_CTL_CACHE_ON 0x00000001 #define ARM3_CTL_SHARED 0x00000002 #define ARM3_CTL_MONITOR 0x00000004 /* CPUID registers */ #define ARM_PFR0_ARM_ISA_MASK 0x0000000f #define ARM_PFR0_THUMB_MASK 0x000000f0 #define ARM_PFR0_THUMB 0x10 #define ARM_PFR0_THUMB2 0x30 #define ARM_PFR0_JAZELLE_MASK 0x00000f00 #define ARM_PFR0_THUMBEE_MASK 0x0000f000 #define ARM_PFR1_ARMV4_MASK 0x0000000f #define ARM_PFR1_SEC_EXT_MASK 0x000000f0 #define ARM_PFR1_MICROCTRL_MASK 0x00000f00 /* * Post-ARM3 CP15 registers: * * 1 Control register * * 2 Translation Table Base * * 3 Domain Access Control * * 4 Reserved * * 5 Fault Status * * 6 Fault Address * * 7 Cache/write-buffer Control * * 8 TLB Control * * 9 Cache Lockdown * * 10 TLB Lockdown * * 11 Reserved * * 12 Reserved * * 13 Process ID (for FCSE) * * 14 Reserved * * 15 Implementation Dependent */ /* Some of the definitions below need cleaning up for V3/V4 architectures */ /* CPU control register (CP15 register 1) */ #define CPU_CONTROL_MMU_ENABLE 0x00000001 /* M: MMU/Protection unit enable */ #define CPU_CONTROL_AFLT_ENABLE 0x00000002 /* A: Alignment fault enable */ #define CPU_CONTROL_DC_ENABLE 0x00000004 /* C: IDC/DC enable */ #define CPU_CONTROL_WBUF_ENABLE 0x00000008 /* W: Write buffer enable */ #define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */ #define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */ #define CPU_CONTROL_LABT_ENABLE 0x00000040 /* L: Late abort enable */ #define CPU_CONTROL_BEND_ENABLE 0x00000080 /* B: Big-endian mode */ #define CPU_CONTROL_SYST_ENABLE 0x00000100 /* S: System protection bit */ #define CPU_CONTROL_ROM_ENABLE 0x00000200 /* R: ROM protection bit */ #define CPU_CONTROL_CPCLK 0x00000400 /* F: Implementation defined */ #define CPU_CONTROL_BPRD_ENABLE 0x00000800 /* Z: Branch prediction enable */ #define CPU_CONTROL_IC_ENABLE 0x00001000 /* I: IC enable */ #define CPU_CONTROL_VECRELOC 0x00002000 /* V: Vector relocation */ #define CPU_CONTROL_ROUNDROBIN 0x00004000 /* RR: Predictable replacement */ #define CPU_CONTROL_V4COMPAT 0x00008000 /* L4: ARMv4 compat LDR R15 etc */ #define CPU_CONTROL_V6_EXTPAGE 0x00800000 /* XP: ARMv6 extended page tables */ #define CPU_CONTROL_L2_ENABLE 0x04000000 /* L2 Cache enabled */ #define CPU_CONTROL_IDC_ENABLE CPU_CONTROL_DC_ENABLE /* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */ #define XSCALE_AUXCTL_K 0x00000001 /* dis. write buffer coalescing */ #define XSCALE_AUXCTL_P 0x00000002 /* ECC protect page table access */ /* Note: XSCale core 3 uses those for LLR DCcahce attributes */ #define XSCALE_AUXCTL_MD_WB_RA 0x00000000 /* mini-D$ wb, read-allocate */ #define XSCALE_AUXCTL_MD_WB_RWA 0x00000010 /* mini-D$ wb, read/write-allocate */ #define XSCALE_AUXCTL_MD_WT 0x00000020 /* mini-D$ wt, read-allocate */ #define XSCALE_AUXCTL_MD_MASK 0x00000030 /* Xscale Core 3 only */ #define XSCALE_AUXCTL_LLR 0x00000400 /* Enable L2 for LLR Cache */ /* Marvell Extra Features Register (CP15 register 1, opcode2 0) */ #define MV_DC_REPLACE_LOCK 0x80000000 /* Replace DCache Lock */ #define MV_DC_STREAM_ENABLE 0x20000000 /* DCache Streaming Switch */ #define MV_WA_ENABLE 0x10000000 /* Enable Write Allocate */ #define MV_L2_PREFETCH_DISABLE 0x01000000 /* L2 Cache Prefetch Disable */ #define MV_L2_INV_EVICT_ERR 0x00800000 /* L2 Invalidates Uncorrectable Error Line Eviction */ #define MV_L2_ENABLE 0x00400000 /* L2 Cache enable */ #define MV_IC_REPLACE_LOCK 0x00080000 /* Replace ICache Lock */ #define MV_BGH_ENABLE 0x00040000 /* Branch Global History Register Enable */ #define MV_BTB_DISABLE 0x00020000 /* Branch Target Buffer Disable */ #define MV_L1_PARERR_ENABLE 0x00010000 /* L1 Parity Error Enable */ /* Cache type register definitions */ #define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */ #define CPU_CT_DSIZE(x) (((x) >> 12) & 0xfff) /* D$ info */ #define CPU_CT_S (1U << 24) /* split cache */ #define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */ #define CPU_CT_FORMAT(x) ((x) >> 29) #define CPU_CT_CTYPE_WT 0 /* write-through */ #define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */ #define CPU_CT_CTYPE_WB2 2 /* w/b, clean w/ cp15,7 */ #define CPU_CT_CTYPE_WB6 6 /* w/b, cp15,7, lockdown fmt A */ #define CPU_CT_CTYPE_WB7 7 /* w/b, cp15,7, lockdown fmt B */ #define CPU_CT_xSIZE_LEN(x) ((x) & 0x3) /* line size */ #define CPU_CT_xSIZE_M (1U << 2) /* multiplier */ #define CPU_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x7) /* associativity */ #define CPU_CT_xSIZE_SIZE(x) (((x) >> 6) & 0x7) /* size */ #define CPU_CT_ARMV7 0x4 /* ARM v7 Cache type definitions */ #define CPUV7_CT_CTYPE_WT (1 << 31) #define CPUV7_CT_CTYPE_WB (1 << 30) #define CPUV7_CT_CTYPE_RA (1 << 29) #define CPUV7_CT_CTYPE_WA (1 << 28) #define CPUV7_CT_xSIZE_LEN(x) ((x) & 0x7) /* line size */ #define CPUV7_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x3ff) /* associativity */ #define CPUV7_CT_xSIZE_SET(x) (((x) >> 13) & 0x7fff) /* num sets */ #define CPU_CLIDR_CTYPE(reg,x) (((reg) >> ((x) * 3)) & 0x7) #define CPU_CLIDR_LOUIS(reg) (((reg) >> 21) & 0x7) #define CPU_CLIDR_LOC(reg) (((reg) >> 24) & 0x7) #define CPU_CLIDR_LOUU(reg) (((reg) >> 27) & 0x7) #define CACHE_ICACHE 1 #define CACHE_DCACHE 2 #define CACHE_SEP_CACHE 3 #define CACHE_UNI_CACHE 4 /* Fault status register definitions */ #define FAULT_TYPE_MASK 0x0f #define FAULT_USER 0x10 #define FAULT_WRTBUF_0 0x00 /* Vector Exception */ #define FAULT_WRTBUF_1 0x02 /* Terminal Exception */ #define FAULT_BUSERR_0 0x04 /* External Abort on Linefetch -- Section */ #define FAULT_BUSERR_1 0x06 /* External Abort on Linefetch -- Page */ #define FAULT_BUSERR_2 0x08 /* External Abort on Non-linefetch -- Section */ #define FAULT_BUSERR_3 0x0a /* External Abort on Non-linefetch -- Page */ #define FAULT_BUSTRNL1 0x0c /* External abort on Translation -- Level 1 */ #define FAULT_BUSTRNL2 0x0e /* External abort on Translation -- Level 2 */ #define FAULT_ALIGN_0 0x01 /* Alignment */ #define FAULT_ALIGN_1 0x03 /* Alignment */ #define FAULT_TRANS_S 0x05 /* Translation -- Section */ #define FAULT_TRANS_P 0x07 /* Translation -- Page */ #define FAULT_DOMAIN_S 0x09 /* Domain -- Section */ #define FAULT_DOMAIN_P 0x0b /* Domain -- Page */ #define FAULT_PERM_S 0x0d /* Permission -- Section */ #define FAULT_PERM_P 0x0f /* Permission -- Page */ #define FAULT_IMPRECISE 0x400 /* Imprecise exception (XSCALE) */ /* * Address of the vector page, low and high versions. */ #define ARM_VECTORS_LOW 0x00000000U #define ARM_VECTORS_HIGH 0xffff0000U /* * ARM Instructions * * 3 3 2 2 2 * 1 0 9 8 7 0 * +-------+-------------------------------------------------------+ * | cond | instruction dependant | * |c c c c| | * +-------+-------------------------------------------------------+ */ #define INSN_SIZE 4 /* Always 4 bytes */ #define INSN_COND_MASK 0xf0000000 /* Condition mask */ #define INSN_COND_AL 0xe0000000 /* Always condition */ #define THUMB_INSN_SIZE 2 /* Some are 4 bytes. */ #endif /* !MACHINE_ARMREG_H */ Index: projects/armv6/sys/arm/include/cpuconf.h =================================================================== --- projects/armv6/sys/arm/include/cpuconf.h (revision 225145) +++ projects/armv6/sys/arm/include/cpuconf.h (revision 225146) @@ -1,184 +1,199 @@ /* $NetBSD: cpuconf.h,v 1.8 2003/09/06 08:55:42 rearnsha Exp $ */ /*- * Copyright (c) 2002 Wasabi Systems, Inc. * All rights reserved. * * Written by Jason R. Thorpe for Wasabi Systems, Inc. * * 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 for the NetBSD Project by * Wasabi Systems, Inc. * 4. The name of Wasabi Systems, Inc. may not be used to endorse * or promote products derived from this software without specific prior * written permission. * * 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. * * $FreeBSD$ * */ #ifndef _MACHINE_CPUCONF_H_ #define _MACHINE_CPUCONF_H_ /* * IF YOU CHANGE THIS FILE, MAKE SURE TO UPDATE THE DEFINITION OF * "PMAP_NEEDS_PTE_SYNC" IN FOR THE CPU TYPE * YOU ARE ADDING SUPPORT FOR. */ /* * Step 1: Count the number of CPU types configured into the kernel. */ #define CPU_NTYPES (defined(CPU_ARM7TDMI) + \ defined(CPU_ARM8) + defined(CPU_ARM9) + \ defined(CPU_ARM9E) + \ defined(CPU_ARM10) + \ defined(CPU_ARM11) + \ defined(CPU_SA110) + defined(CPU_SA1100) + \ defined(CPU_SA1110) + \ defined(CPU_IXP12X0) + \ defined(CPU_XSCALE_80200) + \ defined(CPU_XSCALE_80321) + \ defined(CPU_XSCALE_PXA2X0) + \ defined(CPU_FA526) + \ defined(CPU_FA626TE) + \ defined(CPU_XSCALE_IXP425)) + \ + defined(CPU_CORTEXA) + \ defined(CPU_MV_PJ4B) /* * Step 2: Determine which ARM architecture versions are configured. */ #if (defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \ defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ defined(CPU_IXP12X0) || defined(CPU_FA526)) #define ARM_ARCH_4 1 #else #define ARM_ARCH_4 0 #endif #if (defined(CPU_ARM9E) || defined(CPU_ARM10) || \ defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ defined(CPU_FA626TE)) #define ARM_ARCH_5 1 #else #define ARM_ARCH_5 0 #endif #if defined(CPU_ARM11) || defined(CPU_MV_PJ4B) #define ARM_ARCH_6 1 #else #define ARM_ARCH_6 0 #endif -#define ARM_NARCH (ARM_ARCH_4 + ARM_ARCH_5 + ARM_ARCH_6) +#if defined(CPU_CORTEXA) +#define ARM_ARCH_7A 1 +#else +#define ARM_ARCH_7A 0 +#endif + +#define ARM_NARCH (ARM_ARCH_4 + ARM_ARCH_5 + ARM_ARCH_6 | ARM_ARCH_7A) #if ARM_NARCH == 0 && !defined(KLD_MODULE) && defined(_KERNEL) #error ARM_NARCH is 0 #endif -#if ARM_ARCH_5 || ARM_ARCH_6 +#if ARM_ARCH_5 || ARM_ARCH_6 || ARM_ARCH_7A /* * We could support Thumb code on v4T, but the lack of clean interworking * makes that hard. */ #define THUMB_CODE #endif /* * Step 3: Define which MMU classes are configured: * * ARM_MMU_MEMC Prehistoric, external memory controller * and MMU for ARMv2 CPUs. * * ARM_MMU_GENERIC Generic ARM MMU, compatible with ARM6. * * ARM_MMU_V6 ARMv6 MMU. * + * ARM_MMU_V7 ARMv7 MMU. + * * ARM_MMU_SA1 StrongARM SA-1 MMU. Compatible with generic * ARM MMU, but has no write-through cache mode. * * ARM_MMU_XSCALE XScale MMU. Compatible with generic ARM * MMU, but also has several extensions which * require different PTE layout to use. */ #if (defined(CPU_ARM2) || defined(CPU_ARM250) || defined(CPU_ARM3)) #define ARM_MMU_MEMC 1 #else #define ARM_MMU_MEMC 0 #endif #if (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_FA626TE)) #define ARM_MMU_GENERIC 1 #else #define ARM_MMU_GENERIC 0 #endif #if defined(CPU_ARM11) || defined(CPU_MV_PJ4B) #define ARM_MMU_V6 1 #else #define ARM_MMU_V6 0 #endif +#if defined(CPU_CORTEXA) +#define ARM_MMU_V7 1 +#else +#define ARM_MMU_V7 0 +#endif + #if (defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) ||\ defined(CPU_IXP12X0)) #define ARM_MMU_SA1 1 #else #define ARM_MMU_SA1 0 #endif #if (defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)) #define ARM_MMU_XSCALE 1 #else #define ARM_MMU_XSCALE 0 #endif #define ARM_NMMUS (ARM_MMU_MEMC + ARM_MMU_GENERIC + ARM_MMU_V6 + \ - ARM_MMU_SA1 + ARM_MMU_XSCALE) + ARM_MMU_V7 + ARM_MMU_SA1 + ARM_MMU_XSCALE) #if ARM_NMMUS == 0 && !defined(KLD_MODULE) && defined(_KERNEL) #error ARM_NMMUS is 0 #endif /* * Step 4: Define features that may be present on a subset of CPUs * * ARM_XSCALE_PMU Performance Monitoring Unit on 80200 and 80321 */ #if (defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)) #define ARM_XSCALE_PMU 1 #else #define ARM_XSCALE_PMU 0 #endif #if defined(CPU_XSCALE_81342) #define CPU_XSCALE_CORE3 #endif #endif /* _MACHINE_CPUCONF_H_ */ Index: projects/armv6/sys/arm/include/md_var.h =================================================================== --- projects/armv6/sys/arm/include/md_var.h (revision 225145) +++ projects/armv6/sys/arm/include/md_var.h (revision 225146) @@ -1,79 +1,80 @@ /*- * Copyright (c) 1995 Bruce D. Evans. * 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. Neither the name of the author 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 THE 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 THE 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. * * from: FreeBSD: src/sys/i386/include/md_var.h,v 1.40 2001/07/12 * $FreeBSD$ */ #ifndef _MACHINE_MD_VAR_H_ #define _MACHINE_MD_VAR_H_ extern char sigcode[]; extern int szsigcode; extern uint32_t *vm_page_dump; extern int vm_page_dump_size; extern int (*_arm_memcpy)(void *, void *, int, int); extern int (*_arm_bzero)(void *, int, int); extern int _min_memcpy_size; extern int _min_bzero_size; #define DST_IS_USER 0x1 #define SRC_IS_USER 0x2 #define IS_PHYSICAL 0x4 enum cpu_class { CPU_CLASS_NONE, CPU_CLASS_ARM2, CPU_CLASS_ARM2AS, CPU_CLASS_ARM3, CPU_CLASS_ARM6, CPU_CLASS_ARM7, CPU_CLASS_ARM7TDMI, CPU_CLASS_ARM8, CPU_CLASS_ARM9TDMI, CPU_CLASS_ARM9ES, CPU_CLASS_ARM9EJS, CPU_CLASS_ARM10E, CPU_CLASS_ARM10EJ, + CPU_CLASS_CORTEXA, CPU_CLASS_SA1, CPU_CLASS_XSCALE, CPU_CLASS_ARM11J, CPU_CLASS_MARVELL }; extern enum cpu_class cpu_class; struct dumperinfo; extern int busdma_swi_pending; void busdma_swi(void); void dump_add_page(vm_paddr_t); void dump_drop_page(vm_paddr_t); void minidumpsys(struct dumperinfo *); #endif /* !_MACHINE_MD_VAR_H_ */ Index: projects/armv6/sys/arm/include/pmap.h =================================================================== --- projects/armv6/sys/arm/include/pmap.h (revision 225145) +++ projects/armv6/sys/arm/include/pmap.h (revision 225146) @@ -1,632 +1,633 @@ /*- * Copyright (c) 1991 Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer * Science Department and William Jolitz of UUNET Technologies Inc. * * 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 the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * Derived from hp300 version by Mike Hibler, this version by William * Jolitz uses a recursive map [a pde points to the page directory] to * map the page tables using the pagetables themselves. This is done to * reduce the impact on kernel virtual memory for lots of sparse address * space, and to reduce the cost of memory to each process. * * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90 * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91 * from: FreeBSD: src/sys/i386/include/pmap.h,v 1.70 2000/11/30 * * $FreeBSD$ */ #ifndef _MACHINE_PMAP_H_ #define _MACHINE_PMAP_H_ #include #include /* * Pte related macros */ #define PTE_NOCACHE 1 #define PTE_CACHE 6 #define PTE_PAGETABLE 4 enum mem_type { STRONG_ORD = 0, DEVICE_NOSHARE, DEVICE_SHARE, NRML_NOCACHE, NRML_IWT_OWT, NRML_IWB_OWB, NRML_IWBA_OWBA }; #ifndef LOCORE #include #include #include #include #define PDESIZE sizeof(pd_entry_t) /* for assembly files */ #define PTESIZE sizeof(pt_entry_t) /* for assembly files */ #ifdef _KERNEL #define vtophys(va) pmap_extract(pmap_kernel(), (vm_offset_t)(va)) #define pmap_kextract(va) pmap_extract(pmap_kernel(), (vm_offset_t)(va)) #endif #define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) #define pmap_page_set_memattr(m, ma) (void)0 /* * Pmap stuff */ /* * This structure is used to hold a virtual<->physical address * association and is used mostly by bootstrap code */ struct pv_addr { SLIST_ENTRY(pv_addr) pv_list; vm_offset_t pv_va; vm_paddr_t pv_pa; }; struct pv_entry; struct md_page { int pvh_attrs; vm_offset_t pv_kva; /* first kernel VA mapping */ TAILQ_HEAD(,pv_entry) pv_list; }; #define VM_MDPAGE_INIT(pg) \ do { \ TAILQ_INIT(&pg->pv_list); \ mtx_init(&(pg)->md_page.pvh_mtx, "MDPAGE Mutex", NULL, MTX_DEV);\ (pg)->mdpage.pvh_attrs = 0; \ } while (/*CONSTCOND*/0) struct l1_ttable; struct l2_dtable; /* * The number of L2 descriptor tables which can be tracked by an l2_dtable. * A bucket size of 16 provides for 16MB of contiguous virtual address * space per l2_dtable. Most processes will, therefore, require only two or * three of these to map their whole working set. */ #define L2_BUCKET_LOG2 4 #define L2_BUCKET_SIZE (1 << L2_BUCKET_LOG2) /* * Given the above "L2-descriptors-per-l2_dtable" constant, the number * of l2_dtable structures required to track all possible page descriptors * mappable by an L1 translation table is given by the following constants: */ #define L2_LOG2 ((32 - L1_S_SHIFT) - L2_BUCKET_LOG2) #define L2_SIZE (1 << L2_LOG2) struct pmap { struct mtx pm_mtx; u_int8_t pm_domain; struct l1_ttable *pm_l1; struct l2_dtable *pm_l2[L2_SIZE]; pd_entry_t *pm_pdir; /* KVA of page directory */ cpuset_t pm_active; /* active on cpus */ struct pmap_statistics pm_stats; /* pmap statictics */ TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ }; typedef struct pmap *pmap_t; #ifdef _KERNEL extern struct pmap kernel_pmap_store; #define kernel_pmap (&kernel_pmap_store) #define pmap_kernel() kernel_pmap #define PMAP_ASSERT_LOCKED(pmap) \ mtx_assert(&(pmap)->pm_mtx, MA_OWNED) #define PMAP_LOCK(pmap) mtx_lock(&(pmap)->pm_mtx) #define PMAP_LOCK_DESTROY(pmap) mtx_destroy(&(pmap)->pm_mtx) #define PMAP_LOCK_INIT(pmap) mtx_init(&(pmap)->pm_mtx, "pmap", \ NULL, MTX_DEF | MTX_DUPOK) #define PMAP_OWNED(pmap) mtx_owned(&(pmap)->pm_mtx) #define PMAP_MTX(pmap) (&(pmap)->pm_mtx) #define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx) #define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx) #endif /* * For each vm_page_t, there is a list of all currently valid virtual * mappings of that page. An entry is a pv_entry_t, the list is pv_list. */ typedef struct pv_entry { pmap_t pv_pmap; /* pmap where mapping lies */ vm_offset_t pv_va; /* virtual address for mapping */ TAILQ_ENTRY(pv_entry) pv_list; TAILQ_ENTRY(pv_entry) pv_plist; int pv_flags; /* flags (wired, etc...) */ } *pv_entry_t; #ifdef _KERNEL boolean_t pmap_get_pde_pte(pmap_t, vm_offset_t, pd_entry_t **, pt_entry_t **); /* * virtual address to page table entry and * to physical address. Likewise for alternate address space. * Note: these work recursively, thus vtopte of a pte will give * the corresponding pde that in turn maps it. */ /* * The current top of kernel VM. */ extern vm_offset_t pmap_curmaxkvaddr; struct pcb; void pmap_set_pcb_pagedir(pmap_t, struct pcb *); /* Virtual address to page table entry */ static __inline pt_entry_t * vtopte(vm_offset_t va) { pd_entry_t *pdep; pt_entry_t *ptep; if (pmap_get_pde_pte(pmap_kernel(), va, &pdep, &ptep) == FALSE) return (NULL); return (ptep); } extern vm_paddr_t phys_avail[]; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; void pmap_bootstrap(vm_offset_t, vm_offset_t, struct pv_addr *); int pmap_change_attr(vm_offset_t, vm_size_t, int); void pmap_kenter(vm_offset_t va, vm_paddr_t pa); void pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa); void *pmap_kenter_temp(vm_paddr_t pa, int i); void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa); void pmap_kremove(vm_offset_t); void *pmap_mapdev(vm_offset_t, vm_size_t); void pmap_unmapdev(vm_offset_t, vm_size_t); vm_page_t pmap_use_pt(pmap_t, vm_offset_t); void pmap_debug(int); void pmap_map_section(vm_offset_t, vm_offset_t, vm_offset_t, int, int); void pmap_link_l2pt(vm_offset_t, vm_offset_t, struct pv_addr *); vm_size_t pmap_map_chunk(vm_offset_t, vm_offset_t, vm_offset_t, vm_size_t, int, int); void pmap_map_entry(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa, int prot, int cache); int pmap_fault_fixup(pmap_t, vm_offset_t, vm_prot_t, int); int pmap_dmap_iscurrent(pmap_t pmap); /* * Definitions for MMU domains */ #define PMAP_DOMAINS 15 /* 15 'user' domains (1-15) */ #define PMAP_DOMAIN_KERNEL 0 /* The kernel uses domain #0 */ /* * The new pmap ensures that page-tables are always mapping Write-Thru. * Thus, on some platforms we can run fast and loose and avoid syncing PTEs * on every change. * * Unfortunately, not all CPUs have a write-through cache mode. So we * define PMAP_NEEDS_PTE_SYNC for C code to conditionally do PTE syncs, * and if there is the chance for PTE syncs to be needed, we define * PMAP_INCLUDE_PTE_SYNC so e.g. assembly code can include (and run) * the code. */ extern int pmap_needs_pte_sync; /* * These macros define the various bit masks in the PTE. * * We use these macros since we use different bits on different processor * models. */ #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_XSCALE_TEX(TEX_XSCALE_X)|\ L1_S_XSCALE_TEX(TEX_XSCALE_T)) #define L2_L_CACHE_MASK_generic (L2_B|L2_C) #define L2_L_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_L_TEX(TEX_XSCALE_X) | \ L2_XSCALE_L_TEX(TEX_XSCALE_T)) #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_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_CACHE_MASK_generic (L2_B|L2_C) #define L2_S_CACHE_MASK_xscale (L2_B|L2_C|L2_XSCALE_T_TEX(TEX_XSCALE_X)| \ L2_XSCALE_T_TEX(TEX_XSCALE_X)) #define L1_S_PROTO_generic (L1_TYPE_S | L1_S_IMP) #define L1_S_PROTO_xscale (L1_TYPE_S) #define L1_C_PROTO_generic (L1_TYPE_C | L1_C_IMP2) #define L1_C_PROTO_xscale (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_XSCALE_XS) /* * User-visible names for the ones that vary with MMU class. */ -#if ARM_MMU_V6 == 1 +#if (ARM_MMU_V6 + ARM_MMU_V7) != 0 #define L2_AP(x) (L2_AP0(x)) #else #define L2_AP(x) (L2_AP0(x) | L2_AP1(x) | L2_AP2(x) | L2_AP3(x)) #endif #if ARM_NMMUS > 1 /* More than one MMU class configured; use variables. */ #define L2_S_PROT_U pte_l2_s_prot_u #define L2_S_PROT_W pte_l2_s_prot_w #define L2_S_PROT_MASK pte_l2_s_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 #define L1_S_PROTO pte_l1_s_proto #define L1_C_PROTO pte_l1_c_proto #define L2_S_PROTO pte_l2_s_proto #elif (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 #define L2_S_PROT_U L2_S_PROT_U_generic #define L2_S_PROT_W L2_S_PROT_W_generic #define L2_S_PROT_MASK L2_S_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 #define L1_S_PROTO L1_S_PROTO_generic #define L1_C_PROTO L1_C_PROTO_generic #define L2_S_PROTO L2_S_PROTO_generic #elif ARM_MMU_XSCALE == 1 #define L2_S_PROT_U L2_S_PROT_U_xscale #define L2_S_PROT_W L2_S_PROT_W_xscale #define L2_S_PROT_MASK L2_S_PROT_MASK_xscale #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 #define L1_S_PROTO L1_S_PROTO_xscale #define L1_C_PROTO L1_C_PROTO_xscale #define L2_S_PROTO L2_S_PROTO_xscale -#elif ARM_MMU_V6 == 1 +#elif (ARM_MMU_V6 + ARM_MMU_V7) != 0 #define L2_S_PROT_U (L2_AP0(2)) /* user access */ #define L2_S_PROT_R (L2_APX|L2_AP0(1)) /* read access */ #define L2_S_PROT_MASK (L2_S_PROT_U|L2_S_PROT_R) #define L2_S_WRITABLE(pte) (!(pte & L2_APX)) #define L1_S_CACHE_MASK (L1_S_TEX_MASK|L1_S_B|L1_S_C) #define L2_L_CACHE_MASK (L2_L_TEX_MASK|L2_B|L2_C) #define L2_S_CACHE_MASK (L2_S_TEX_MASK|L2_B|L2_C) #define L1_S_PROTO (L1_TYPE_S) #define L1_C_PROTO (L1_TYPE_C) #define L2_S_PROTO (L2_TYPE_S) #define ARM_L1S_STRONG_ORD (0) #define ARM_L1S_DEVICE_NOSHARE (L1_S_TEX(2)) #define ARM_L1S_DEVICE_SHARE (L1_S_B) #define ARM_L1S_NRML_NOCACHE (L1_S_TEX(1)) #define ARM_L1S_NRML_IWT_OWT (L1_S_C) #define ARM_L1S_NRML_IWB_OWB (L1_S_C|L1_S_B) #define ARM_L1S_NRML_IWBA_OWBA (L1_S_TEX(1)|L1_S_C|L1_S_B) #define ARM_L2L_STRONG_ORD (0) #define ARM_L2L_DEVICE_NOSHARE (L2_L_TEX(2)) #define ARM_L2L_DEVICE_SHARE (L2_B) #define ARM_L2L_NRML_NOCACHE (L2_L_TEX(1)) #define ARM_L2L_NRML_IWT_OWT (L2_C) #define ARM_L2L_NRML_IWB_OWB (L2_C|L2_B) #define ARM_L2L_NRML_IWBA_OWBA (L2_L_TEX(1)|L2_C|L2_B) #define ARM_L2S_STRONG_ORD (0) #define ARM_L2S_DEVICE_NOSHARE (L2_S_TEX(2)) #define ARM_L2S_DEVICE_SHARE (L2_B) #define ARM_L2S_NRML_NOCACHE (L2_S_TEX(1)) #define ARM_L2S_NRML_IWT_OWT (L2_C) #define ARM_L2S_NRML_IWB_OWB (L2_C|L2_B) #define ARM_L2S_NRML_IWBA_OWBA (L2_S_TEX(1)|L2_C|L2_B) #endif /* ARM_NMMUS > 1 */ #if (ARM_MMU_SA1 == 1) && (ARM_NMMUS == 1) #define PMAP_NEEDS_PTE_SYNC 1 #define PMAP_INCLUDE_PTE_SYNC #elif defined(CPU_XSCALE_81342) #define PMAP_NEEDS_PTE_SYNC 1 #define PMAP_INCLUDE_PTE_SYNC #elif (ARM_MMU_SA1 == 0) #define PMAP_NEEDS_PTE_SYNC 0 #endif /* * These macros return various bits based on kernel/user and protection. * Note that the compiler will usually fold these at compile time. */ -#if ARM_MMU_V6 == 0 +#if (ARM_MMU_V6 + ARM_MMU_V7) == 0 + #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_WRITABLE(pd) ((pd) & L1_S_PROT_W) #define L1_S_PROT(ku, pr) ((((ku) == PTE_USER) ? L1_S_PROT_U : 0) | \ (((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : 0)) #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(ku, pr) ((((ku) == PTE_USER) ? L2_L_PROT_U : 0) | \ (((pr) & VM_PROT_WRITE) ? L2_L_PROT_W : 0)) #define L2_S_PROT(ku, pr) ((((ku) == PTE_USER) ? L2_S_PROT_U : 0) | \ (((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : 0)) #else #define L1_S_PROT_U (L1_S_AP(AP_U)) #define L1_S_PROT_MASK (L1_S_APX|L1_S_AP(0x3)) #define L1_S_WRITABLE(pd) (!((pd) & L1_S_APX)) #define L1_S_PROT(ku, pr) (L1_S_PROT_MASK & ~((((ku) == PTE_KERNEL) ? L1_S_PROT_U : 0) | \ (((pr) & VM_PROT_WRITE) ? L1_S_APX : 0))) #define L2_L_PROT_MASK (L2_APX|L2_AP0(0x3)) #define L2_L_PROT(ku, pr) (L2_L_PROT_MASK & ~((((ku) == PTE_KERNEL) ? L2_S_PROT_U : 0) | \ (((pr) & VM_PROT_WRITE) ? L2_APX : 0))) #define L2_S_PROT(ku, pr) (L2_S_PROT_MASK & ~((((ku) == PTE_KERNEL) ? L2_S_PROT_U : 0) | \ (((pr) & VM_PROT_WRITE) ? L2_APX : 0))) #endif /* * Macros to test if a mapping is mappable with an L1 Section mapping * or an L2 Large Page mapping. */ #define L1_S_MAPPABLE_P(va, pa, size) \ ((((va) | (pa)) & L1_S_OFFSET) == 0 && (size) >= L1_S_SIZE) #define L2_L_MAPPABLE_P(va, pa, size) \ ((((va) | (pa)) & L2_L_OFFSET) == 0 && (size) >= L2_L_SIZE) /* * Provide a fallback in case we were not able to determine it at * compile-time. */ #ifndef PMAP_NEEDS_PTE_SYNC #define PMAP_NEEDS_PTE_SYNC pmap_needs_pte_sync #define PMAP_INCLUDE_PTE_SYNC #endif #define PTE_SYNC(pte) \ do { \ if (PMAP_NEEDS_PTE_SYNC) { \ cpu_dcache_wb_range((vm_offset_t)(pte), sizeof(pt_entry_t));\ cpu_l2cache_wb_range((vm_offset_t)(pte), sizeof(pt_entry_t));\ }\ } while (/*CONSTCOND*/0) #define PTE_SYNC_RANGE(pte, cnt) \ do { \ if (PMAP_NEEDS_PTE_SYNC) { \ cpu_dcache_wb_range((vm_offset_t)(pte), \ (cnt) << 2); /* * sizeof(pt_entry_t) */ \ cpu_l2cache_wb_range((vm_offset_t)(pte), \ (cnt) << 2); /* * sizeof(pt_entry_t) */ \ } \ } while (/*CONSTCOND*/0) extern pt_entry_t pte_l1_s_cache_mode; extern pt_entry_t pte_l1_s_cache_mask; extern pt_entry_t pte_l2_l_cache_mode; extern pt_entry_t pte_l2_l_cache_mask; extern pt_entry_t pte_l2_s_cache_mode; extern pt_entry_t pte_l2_s_cache_mask; extern pt_entry_t pte_l1_s_cache_mode_pt; 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_l2_s_prot_u; extern pt_entry_t pte_l2_s_prot_w; extern pt_entry_t pte_l2_s_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; extern void (*pmap_copy_page_func)(vm_paddr_t, vm_paddr_t); extern void (*pmap_zero_page_func)(vm_paddr_t, int, int); -#if (ARM_MMU_GENERIC + ARM_MMU_V6 + ARM_MMU_SA1) != 0 || defined(CPU_XSCALE_81342) +#if (ARM_MMU_GENERIC + ARM_MMU_V6 + ARM_MMU_V7 + ARM_MMU_SA1) != 0 || defined(CPU_XSCALE_81342) void pmap_copy_page_generic(vm_paddr_t, vm_paddr_t); void pmap_zero_page_generic(vm_paddr_t, int, int); void pmap_pte_init_generic(void); #if defined(CPU_ARM8) void pmap_pte_init_arm8(void); #endif #if defined(CPU_ARM9) void pmap_pte_init_arm9(void); #endif /* CPU_ARM9 */ #if defined(CPU_ARM10) void pmap_pte_init_arm10(void); #endif /* CPU_ARM10 */ -#if defined(ARM_MMU_V6) +#if (ARM_MMU_V6 + ARM_MMU_V7) != 0 void pmap_pte_init_mmu_v6(void); #endif /* CPU_ARM11 */ #endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 */ #if /* ARM_MMU_SA1 == */1 void pmap_pte_init_sa1(void); #endif /* ARM_MMU_SA1 == 1 */ #if ARM_MMU_XSCALE == 1 void pmap_copy_page_xscale(vm_paddr_t, vm_paddr_t); void pmap_zero_page_xscale(vm_paddr_t, int, int); void pmap_pte_init_xscale(void); void xscale_setup_minidata(vm_offset_t, vm_offset_t, vm_offset_t); void pmap_use_minicache(vm_offset_t, vm_size_t); #endif /* ARM_MMU_XSCALE == 1 */ #if defined(CPU_XSCALE_81342) #define ARM_HAVE_SUPERSECTIONS #endif #define PTE_KERNEL 0 #define PTE_USER 1 #define l1pte_valid(pde) ((pde) != 0) #define l1pte_section_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_S) #define l1pte_page_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_C) #define l1pte_fpage_p(pde) (((pde) & L1_TYPE_MASK) == L1_TYPE_F) #define l2pte_index(v) (((v) & L2_ADDR_BITS) >> L2_S_SHIFT) #define l2pte_valid(pte) ((pte) != 0) #define l2pte_pa(pte) ((pte) & L2_S_FRAME) #define l2pte_minidata(pte) (((pte) & \ (L2_B | L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X)))\ == (L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X))) /* L1 and L2 page table macros */ #define pmap_pde_v(pde) l1pte_valid(*(pde)) #define pmap_pde_section(pde) l1pte_section_p(*(pde)) #define pmap_pde_page(pde) l1pte_page_p(*(pde)) #define pmap_pde_fpage(pde) l1pte_fpage_p(*(pde)) #define pmap_pte_v(pte) l2pte_valid(*(pte)) #define pmap_pte_pa(pte) l2pte_pa(*(pte)) /* * Flags that indicate attributes of pages or mappings of pages. * * The PVF_MOD and PVF_REF flags are stored in the mdpage for each * page. PVF_WIRED, PVF_WRITE, and PVF_NC are kept in individual * pv_entry's for each page. They live in the same "namespace" so * that we can clear multiple attributes at a time. * * Note the "non-cacheable" flag generally means the page has * multiple mappings in a given address space. */ #define PVF_MOD 0x01 /* page is modified */ #define PVF_REF 0x02 /* page is referenced */ #define PVF_WIRED 0x04 /* mapping is wired */ #define PVF_WRITE 0x08 /* mapping is writable */ #define PVF_EXEC 0x10 /* mapping is executable */ #define PVF_NC 0x20 /* mapping is non-cacheable */ #define PVF_MWC 0x40 /* mapping is used multiple times in userland */ #define PVF_UNMAN 0x80 /* mapping is unmanaged */ void vector_page_setprot(int); void pmap_update(pmap_t); /* * This structure is used by machine-dependent code to describe * static mappings of devices, created at bootstrap time. */ struct pmap_devmap { vm_offset_t pd_va; /* virtual address */ vm_paddr_t pd_pa; /* physical address */ vm_size_t pd_size; /* size of region */ vm_prot_t pd_prot; /* protection code */ int pd_cache; /* cache attributes */ }; const struct pmap_devmap *pmap_devmap_find_pa(vm_paddr_t, vm_size_t); const struct pmap_devmap *pmap_devmap_find_va(vm_offset_t, vm_size_t); void pmap_devmap_bootstrap(vm_offset_t, const struct pmap_devmap *); void pmap_devmap_register(const struct pmap_devmap *); #define SECTION_CACHE 0x1 #define SECTION_PT 0x2 void pmap_kenter_section(vm_offset_t, vm_paddr_t, int flags); #ifdef ARM_HAVE_SUPERSECTIONS void pmap_kenter_supersection(vm_offset_t, uint64_t, int flags); #endif extern char *_tmppt; void pmap_postinit(void); #ifdef ARM_USE_SMALL_ALLOC void arm_add_smallalloc_pages(void *, void *, int, int); vm_offset_t arm_ptovirt(vm_paddr_t); void arm_init_smallalloc(void); struct arm_small_page { void *addr; TAILQ_ENTRY(arm_small_page) pg_list; }; #endif #define ARM_NOCACHE_KVA_SIZE 0x1000000 extern vm_offset_t arm_nocache_startaddr; void *arm_remap_nocache(void *, vm_size_t); void arm_unmap_nocache(void *, vm_size_t); extern vm_paddr_t dump_avail[]; #endif /* _KERNEL */ #endif /* !LOCORE */ #endif /* !_MACHINE_PMAP_H_ */ Index: projects/armv6/sys/conf/files.arm =================================================================== --- projects/armv6/sys/conf/files.arm (revision 225145) +++ projects/armv6/sys/conf/files.arm (revision 225146) @@ -1,81 +1,81 @@ # $FreeBSD$ crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb arm/arm/autoconf.c standard arm/arm/bcopy_page.S standard arm/arm/bcopyinout.S standard arm/arm/blockio.S standard arm/arm/bootconfig.c standard arm/arm/bus_space_asm_generic.S standard arm/arm/busdma_machdep.c optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_sa1100 | cpu_sa1110 | cpu_xscale_80219 | cpu_xscale_80321 | cpu_xscale_81342 | cpu_xscale_ixp425 | cpu_xscale_ixp435 | cpu_xscale_pxa2x0 -arm/arm/busdma_machdep-v6.c optional cpu_arm11 | cpu_mv_pj4b +arm/arm/busdma_machdep-v6.c optional cpu_arm11 | cpu_cortexa | cpu_mv_pj4b arm/arm/copystr.S standard arm/arm/cpufunc.c standard arm/arm/cpufunc_asm.S standard arm/arm/cpufunc_asm_armv4.S standard arm/arm/db_disasm.c optional ddb arm/arm/db_interface.c optional ddb arm/arm/db_trace.c optional ddb arm/arm/disassem.c optional ddb arm/arm/dump_machdep.c standard arm/arm/elf_machdep.c standard arm/arm/exception.S standard arm/arm/fiq.c standard arm/arm/fiq_subr.S standard arm/arm/fusu.S standard arm/arm/gdb_machdep.c optional gdb arm/arm/identcpu.c standard arm/arm/in_cksum.c optional inet | inet6 arm/arm/in_cksum_arm.S optional inet | inet6 arm/arm/intr.c standard arm/arm/locore.S standard no-obj arm/arm/machdep.c standard arm/arm/mem.c optional mem arm/arm/minidump_machdep.c optional mem arm/arm/mp_machdep.c optional smp arm/arm/nexus.c standard arm/arm/pmap.c optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_sa1100 | cpu_sa1110 | cpu_xscale_80219 | cpu_xscale_80321 | cpu_xscale_81342 | cpu_xscale_ixp425 | cpu_xscale_ixp435 | cpu_xscale_pxa2x0 -arm/arm/pmap-v6.c optional cpu_arm11 | cpu_mv_pj4b +arm/arm/pmap-v6.c optional cpu_arm11 | cpu_cortexa | cpu_mv_pj4b arm/arm/setcpsr.S standard arm/arm/setstack.s standard arm/arm/stack_machdep.c optional ddb | stack arm/arm/support.S standard arm/arm/swtch.S standard arm/arm/sys_machdep.c standard arm/arm/trap.c standard arm/arm/uio_machdep.c standard arm/arm/undefined.c standard arm/arm/vectors.S standard arm/arm/vm_machdep.c standard arm/fpe-arm/armfpe_glue.S optional armfpe arm/fpe-arm/armfpe_init.c optional armfpe arm/fpe-arm/armfpe.S optional armfpe dev/hwpmc/hwpmc_arm.c optional hwpmc dev/ofw/openfirm.c optional fdt dev/ofw/openfirmio.c optional fdt dev/ofw/ofw_bus_if.m optional fdt dev/ofw/ofw_if.m optional fdt dev/ofw/ofw_bus_subr.c optional fdt dev/ofw/ofw_fdt.c optional fdt geom/geom_bsd.c optional geom_bsd geom/geom_bsd_enc.c optional geom_bsd geom/geom_mbr.c optional geom_mbr geom/geom_mbr_enc.c optional geom_mbr libkern/arm/divsi3.S standard libkern/arm/ffs.S standard libkern/arm/muldi3.c standard libkern/ashldi3.c standard libkern/ashrdi3.c standard libkern/divdi3.c standard libkern/ffsl.c standard libkern/fls.c standard libkern/flsl.c standard libkern/lshrdi3.c standard libkern/memchr.c optional fdt libkern/moddi3.c standard libkern/qdivrem.c standard libkern/udivdi3.c standard libkern/umoddi3.c standard #XXX: We can't use these versions, as strcmp.c is included conf/files #libkern/arm/strcmp.S standard #libkern/arm/strncmp.S standard Index: projects/armv6/sys/conf/options.arm =================================================================== --- projects/armv6/sys/conf/options.arm (revision 225145) +++ projects/armv6/sys/conf/options.arm (revision 225146) @@ -1,43 +1,44 @@ #$FreeBSD$ ARM9_CACHE_WRITE_THROUGH opt_global.h ARM_CACHE_LOCK_ENABLE opt_global.h ARMFPE opt_global.h ARM_KERN_DIRECTMAP opt_vm.h ARM_USE_SMALL_ALLOC opt_global.h AT91C_MASTER_CLOCK opt_global.h AT91C_MAIN_CLOCK opt_at91.h COUNTS_PER_SEC opt_timer.h CPU_ARM9 opt_global.h CPU_ARM9E opt_global.h CPU_ARM11 opt_global.h +CPU_CORTEXA opt_global.h CPU_FA526 opt_global.h CPU_FA626TE opt_global.h CPU_MV_PJ4B opt_global.h CPU_SA1100 opt_global.h CPU_SA1110 opt_global.h CPU_XSCALE_80219 opt_global.h CPU_XSCALE_80321 opt_global.h CPU_XSCALE_81342 opt_global.h CPU_XSCALE_IXP425 opt_global.h CPU_XSCALE_IXP435 opt_global.h CPU_XSCALE_PXA2X0 opt_global.h FLASHADDR opt_global.h IXP4XX_FLASH_SIZE opt_global.h KERNPHYSADDR opt_global.h KERNVIRTADDR opt_global.h LOADERRAMADDR opt_global.h PHYSADDR opt_global.h SKYEYE_WORKAROUNDS opt_global.h SOC_MV_DISCOVERY opt_global.h SOC_MV_KIRKWOOD opt_global.h SOC_MV_ORION opt_global.h STARTUP_PAGETABLE_ADDR opt_global.h XSCALE_CACHE_READ_WRITE_ALLOCATE opt_global.h XSACLE_DISABLE_CCNT opt_timer.h VERBOSE_INIT_ARM opt_global.h AT91_ATE_USE_RMII opt_at91.h AT91_BWCT opt_at91.h AT91_TSC opt_at91.h AT91_KWIKBYTE opt_at91.h AT91_MCI_HAS_4WIRE opt_at91.h AT91_MCI_SLOT_B opt_at91.h