diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c index 6da57b3072f8..e773269f51a5 100644 --- a/sys/arch/arm/arm/cpufunc.c +++ b/sys/arch/arm/arm/cpufunc.c @@ -1,6 +1,7 @@ -/* $NetBSD: cpufunc.c,v 1.8 2001/06/03 13:38:14 bjh21 Exp $ */ +/* $NetBSD: cpufunc.c,v 1.9 2001/06/03 18:32:33 chris Exp $ */ /* + * arm7tdmi support code Copyright (c) 2001 John Fremlin * arm8 support code Copyright (c) 1997 ARM Limited * arm8 support code Copyright (c) 1997 Causality Limited * Copyright (c) 1997 Mark Brinicombe. @@ -269,6 +270,76 @@ struct cpu_functions arm7_cpufuncs = { }; #endif /* CPU_ARM7 */ +#ifdef CPU_ARM7TDMI +struct cpu_functions arm7tdmi_cpufuncs = { + /* CPU functions */ + + cpufunc_id, /* id */ + + /* MMU functions */ + + cpufunc_control, /* control */ + cpufunc_domains, /* domain */ + arm7tdmi_setttb, /* setttb */ + cpufunc_faultstatus, /* faultstatus */ + cpufunc_faultaddress, /* faultaddress */ + + /* TLB functions */ + + arm7tdmi_tlb_flushID, /* tlb_flushID */ + arm7tdmi_tlb_flushID_SE, /* tlb_flushID_SE */ + arm7tdmi_tlb_flushID, /* tlb_flushI */ + arm7tdmi_tlb_flushID_SE, /* tlb_flushI_SE */ + arm7tdmi_tlb_flushID, /* tlb_flushD */ + arm7tdmi_tlb_flushID_SE, /* tlb_flushD_SE */ + + /* Cache functions */ + + arm7tdmi_cache_flushID, /* cache_flushID */ + (void *)arm7tdmi_cache_flushID, /* cache_flushID_SE */ + arm7tdmi_cache_flushID, /* cache_flushI */ + (void *)arm7tdmi_cache_flushID, /* cache_flushI_SE */ + arm7tdmi_cache_flushID, /* cache_flushD */ + (void *)arm7tdmi_cache_flushID, /* cache_flushD_SE */ + + cpufunc_nullop, /* cache_cleanID s*/ + (void *)cpufunc_nullop, /* cache_cleanID_E s*/ + cpufunc_nullop, /* cache_cleanD s*/ + (void *)cpufunc_nullop, /* cache_cleanD_E */ + + arm7tdmi_cache_flushID, /* cache_purgeID s*/ + (void *)arm7tdmi_cache_flushID, /* cache_purgeID_E s*/ + arm7tdmi_cache_flushID, /* cache_purgeD s*/ + (void *)arm7tdmi_cache_flushID, /* cache_purgeD_E s*/ + + /* Other functions */ + + cpufunc_nullop, /* flush_prefetchbuf */ + cpufunc_nullop, /* drain_writebuf */ + cpufunc_nullop, /* flush_brnchtgt_C */ + (void *)cpufunc_nullop, /* flush_brnchtgt_E */ + + (void *)cpufunc_nullop, /* sleep */ + + /* Soft functions */ + + cpufunc_nullop, /* cache_syncI */ + (void *)cpufunc_nullop, /* cache_cleanID_rng */ + (void *)cpufunc_nullop, /* cache_cleanD_rng */ + (void *)arm7tdmi_cache_flushID, /* cache_purgeID_rng */ + (void *)arm7tdmi_cache_flushID, /* cache_purgeD_rng */ + (void *)cpufunc_nullop, /* cache_syncI_rng */ + + arm7_dataabt_fixup, /* dataabt_fixup */ + cpufunc_null_fixup, /* prefetchabt_fixup */ + + arm7tdmi_context_switch, /* context_switch */ + + arm7tdmi_setup /* cpu setup */ + +}; +#endif /* CPU_ARM7TDMI */ + #ifdef CPU_ARM8 struct cpu_functions arm8_cpufuncs = { /* CPU functions */ @@ -452,6 +523,15 @@ set_cpufuncs() return 0; } #endif /* CPU_ARM7 */ +#ifdef CPU_ARM7TDMI + if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && + CPU_ID_IS7(cputype) && + (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) { + cpufuncs = arm7tdmi_cpufuncs; + cpu_reset_needs_v4_MMU_disable = 0; + return 0; + } +#endif #ifdef CPU_ARM8 if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && (cputype & 0x0000f000) == 0x00008000) { @@ -471,7 +551,7 @@ set_cpufuncs() /* * Bzzzz. And the answer was ... */ -/* panic("No support for this CPU type (%08x) in kernel\n", cputype);*/ +/* panic("No support for this CPU type (%08x) in kernel", cputype);*/ return(ARCHITECTURE_NOT_PRESENT); } @@ -501,19 +581,19 @@ cpufunc_null_fixup(arg) return(ABORT_FIXUP_OK); } -#if defined(CPU_ARM6) || defined(CPU_ARM7) +#if defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) #ifdef DEBUG_FAULT_CORRECTION extern int pmap_debug_level; #endif #endif #if defined(CPU_ARM2) || defined(CPU_ARM250) || defined(CPU_ARM3) || \ - defined(CPU_ARM6) || defined(CPU_ARM7) + defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) /* * "Early" data abort fixup. * * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode). Also used - * indirectly by ARM6 (in late-abort mode) and ARM7. + * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI]. * * In early aborts, we may have to fix up LDM, STM, LDC and STC. */ @@ -672,7 +752,8 @@ early_abort_fixup(arg) } #endif /* CPU_ARM2/250/3/6/7 */ -#if (defined(CPU_ARM6) && defined(ARM6_LATE_ABORT)) || defined(CPU_ARM7) +#if (defined(CPU_ARM6) && defined(ARM6_LATE_ABORT)) || defined(CPU_ARM7) || \ + defined(CPU_ARM7TDMI) /* * "Late" (base updated) data abort fixup * @@ -863,14 +944,14 @@ late_abort_fixup(arg) return early_abort_fixup(arg); } -#endif /* CPU_ARM6(LATE)/7 */ +#endif /* CPU_ARM6(LATE)/7/7TDMI */ /* * CPU Setup code */ -#if defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM8) || \ - defined(CPU_SA110) +#if defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) || \ + defined(CPU_ARM8) || defined(CPU_SA110) int cpuctrl; #define IGN 0 @@ -911,9 +992,10 @@ parse_cpu_options(args, optlist, cpuctrl) } return(cpuctrl); } -#endif +#endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 */ -#if defined (CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM8) +#if defined (CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) \ + || defined(CPU_ARM8) struct cpu_option arm678_options[] = { #ifdef COMPAT_12 { "nocache", IGN, BIC, CPU_CONTROL_IDC_ENABLE }, @@ -926,7 +1008,7 @@ struct cpu_option arm678_options[] = { { NULL, IGN, IGN, 0 } }; -#endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM8 */ +#endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */ #ifdef CPU_ARM6 struct cpu_option arm6_options[] = { @@ -1008,6 +1090,38 @@ arm7_setup(args) } #endif /* CPU_ARM7 */ +#ifdef CPU_ARM7TDMI +struct cpu_option arm7tdmi_options[] = { + { "arm7.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, + { "arm7.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, + { "arm7.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, + { "arm7.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, +#ifdef COMPAT_12 + { "fpaclk2", BIC, OR, CPU_CONTROL_CPCLK }, +#endif /* COMPAT_12 */ + { "arm700.fpaclk", BIC, OR, CPU_CONTROL_CPCLK }, + { NULL, IGN, IGN, 0 } +}; + +void +arm7tdmi_setup(args) + char *args; +{ + cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE + | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE + | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; + + cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); + cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl); + + /* Clear out the cache */ + cpu_cache_purgeID(); + + /* Set the control register */ + cpu_control(0xffffffff, cpuctrl); +} +#endif /* CPU_ARM7TDMI */ + #ifdef CPU_ARM8 struct cpu_option arm8_options[] = { { "arm8.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, diff --git a/sys/arch/arm/arm/cpufunc_asm.S b/sys/arch/arm/arm/cpufunc_asm.S index d9bd29735531..319cf51fb09d 100644 --- a/sys/arch/arm/arm/cpufunc_asm.S +++ b/sys/arch/arm/arm/cpufunc_asm.S @@ -1,6 +1,7 @@ -/* $NetBSD: cpufunc_asm.S,v 1.2 2001/06/02 19:01:03 bjh21 Exp $ */ +/* $NetBSD: cpufunc_asm.S,v 1.3 2001/06/03 18:32:33 chris Exp $ */ /* + * arm7tdmi support code Copyright (c) 2001 John Fremlin * arm8 support code Copyright (c) 1997 ARM Limited * arm8 support code Copyright (c) 1997 Causality Limited * Copyright (c) 1997,1998 Mark Brinicombe. @@ -186,6 +187,25 @@ ENTRY(arm67_setttb) mov pc, lr #endif /* CPU_ARM6 || CPU_ARM7 */ +#ifdef CPU_ARM7TDMI + +ENTRY(arm7tdmi_setttb) + mov r1,r0 /* store the ttb in a safe place */ + mov r2,lr /* ditto with lr */ + + bl _C_LABEL(arm7tdmi_cache_flushID) + + /* Write the TTB */ + mcr p15, 0, r1, c2, c0, 0 + + /* If we have updated the TTB we must flush the TLB */ + bl _C_LABEL(arm7tdmi_tlb_flushID) + /* For good measure we will flush the IDC as well */ + bl _C_LABEL(arm7tdmi_cache_flushID) + + mov pc, r2 +#endif /* CPU_7TDMI */ + #ifdef CPU_ARM8 ENTRY(arm8_setttb) /* We need to clean and flush the cache as it uses virtual @@ -274,6 +294,16 @@ ENTRY(arm67_tlb_purge) mov pc, lr #endif /* CPU_ARM6 || CPU_ARM7 */ +#ifdef CPU_ARM7TDMI +ENTRY(arm7tdmi_tlb_flushID) + mov r0,#0 + mcr p15, 0, r0, c8, c7, 0 + mov pc,lr + +ENTRY(arm7tdmi_tlb_flushID_SE) + mcr p15, 0, r0, c8, c7, 1 + mov pc,lr +#endif #ifdef CPU_ARM8 ENTRY(arm8_tlb_flushID) mcr 15, 0, r0, c8, c7, 0 /* flush I+D tlb */ @@ -323,6 +353,18 @@ ENTRY(arm67_cache_flush) mov pc, lr #endif /* CPU_ARM6 || CPU_ARM7 */ +#ifdef CPU_ARM7TDMI +ENTRY(arm7tdmi_cache_flushID) + mov r0, #0 + + mcr p15, 0, r0, c7, c7, 0 + /* Make sure that the pipeline is emptied */ + mov r0, r0 + mov r0, r0 + + mov pc,lr +#endif + #ifdef CPU_ARM8 ENTRY(arm8_cache_flushID) mcr 15, 0, r0, c7, c7, 0 /* flush I+D cache */ @@ -775,6 +817,10 @@ ENTRY(arm67_context_switch) mov pc, lr #endif +#ifdef CPU_ARM7TDMI +ENTRY(arm7tdmi_context_switch) + b arm7tdmi_setttb +#endif #ifdef CPU_ARM8 ENTRY(arm8_context_switch) /* Switch the memory to the new process */ diff --git a/sys/arch/arm/arm32/cpu.c b/sys/arch/arm/arm32/cpu.c index 59aeb391c8da..937be2674e47 100644 --- a/sys/arch/arm/arm32/cpu.c +++ b/sys/arch/arm/arm32/cpu.c @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.2 2001/05/13 13:53:08 bjh21 Exp $ */ +/* $NetBSD: cpu.c,v 1.3 2001/06/03 18:32:34 chris Exp $ */ /* * Copyright (c) 1995 Mark Brinicombe. @@ -294,7 +294,7 @@ const struct cpu_classtab cpu_classes[] = { { "ARM3", "CPU_ARM3" }, /* CPU_CLASS_ARM3 */ { "ARM6", "CPU_ARM6" }, /* CPU_CLASS_ARM6 */ { "ARM7", "CPU_ARM7" }, /* CPU_CLASS_ARM7 */ - { "ARM7TDMI", NULL }, /* CPU_CLASS_ARM7TDMI */ + { "ARM7TDMI", "CPU_ARM7TDMI" },/* CPU_CLASS_ARM7TDMI */ { "ARM8", "CPU_ARM8" }, /* CPU_CLASS_ARM8 */ { "ARM9TDMI", NULL }, /* CPU_CLASS_ARM9TDMI */ { "ARM9E-S", NULL }, /* CPU_CLASS_ARM9ES */ @@ -340,6 +340,7 @@ identify_arm_cpu(dv, cpu_number) switch (cpu->cpu_class) { case CPU_CLASS_ARM6: case CPU_CLASS_ARM7: + case CPU_CLASS_ARM7TDMI: case CPU_CLASS_ARM8: if ((cpu->cpu_ctrl & CPU_CONTROL_IDC_ENABLE) == 0) strcat(cpu->cpu_model, " IDC disabled"); @@ -390,6 +391,9 @@ identify_arm_cpu(dv, cpu_number) #ifdef CPU_ARM7 case CPU_CLASS_ARM7: #endif +#ifdef CPU_ARM7TDMI + case CPU_CLASS_ARM7TDMI: +#endif #ifdef CPU_ARM8 case CPU_CLASS_ARM8: #endif diff --git a/sys/arch/arm/conf/files.arm b/sys/arch/arm/conf/files.arm index 19522cd57c0f..382d7e8e8002 100644 --- a/sys/arch/arm/conf/files.arm +++ b/sys/arch/arm/conf/files.arm @@ -1,4 +1,4 @@ -# $NetBSD: files.arm,v 1.29 2001/05/29 23:03:20 bjh21 Exp $ +# $NetBSD: files.arm,v 1.30 2001/06/03 18:32:33 chris Exp $ # temporary define to allow easy moving to ../arch/arm/arm32 defopt ARM32 @@ -7,8 +7,8 @@ defopt ARM32 defopt opt_progmode.h PROG26 PROG32 # CPU types defopt opt_cputypes.h CPU_ARM2 CPU_ARM250 CPU_ARM3 : PROG26 -defopt opt_cputypes.h CPU_ARM6 CPU_ARM7 CPU_ARM7500 CPU_ARM8 CPU_SA110 - CPU_SA1110 : PROG32 +defopt opt_cputypes.h CPU_ARM6 CPU_ARM7 CPU_ARM7TDMI CPU_ARM7500 CPU_ARM8 + CPU_SA110 CPU_SA1110 : PROG32 # Floating point emulator defopt ARMFPE diff --git a/sys/arch/arm/include/cpufunc.h b/sys/arch/arm/include/cpufunc.h index d8bb6fcd91df..de8dffcbee4d 100644 --- a/sys/arch/arm/include/cpufunc.h +++ b/sys/arch/arm/include/cpufunc.h @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.h,v 1.4 2001/06/02 21:03:32 bjh21 Exp $ */ +/* $NetBSD: cpufunc.h,v 1.5 2001/06/03 18:32:34 chris Exp $ */ /* * Copyright (c) 1997 Mark Brinicombe. @@ -207,6 +207,16 @@ void arm6_setup __P((char *string)); void arm7_setup __P((char *string)); #endif /* CPU_ARM7 */ +#ifdef CPU_ARM7TDMI +int arm7_dataabt_fixup __P((void *arg)); +void arm7tdmi_setup __P((char *string)); +void arm7tdmi_setttb __P((u_int ttb)); +void arm7tdmi_tlb_flushID __P((void)); +void arm7tdmi_tlb_flushID_SE __P((u_int va)); +void arm7tdmi_cache_flushID __P((void)); +void arm7tdmi_context_switch __P((void)); +#endif /* CPU_ARM7TDMI */ + #ifdef CPU_ARM8 void arm8_setttb __P((u_int ttb)); void arm8_tlb_flushID __P((void));