, Ben Harris <bjh21@netbsd.org>
From: John Fremlin <vii@users.sourceforge.net>
List: port-arm32
Date: 06/02/2001 23:59:37
--=-=-=
Chris Gilbert <chris@paradox.demon.co.uk> writes:
[...]
> > > It's because ARM7TDMI is a very different core from ARM7. They
> > > have different register assignments in CP15 for one thing. To
> > > support ARM7TDMI, you'll need to add another batch of cpufunc
> > > routines.
> >
> > OK I've written them (from the 710 T docs). I do hope that the
> > abort fixups are no different, because I am disinclined to try to
> > audit those ;-)
> >
> > Is anybody willing to check over and or commit the code? I don't want
> > to keep it in my private tree.
>
> If you send the patches to the list everyone can take a look and
> someone (possibly me :)) will commit them.
Here is the patch, about as ready as it's going to be for a while,
because I'll need some userspace before the data abort fixups get
tested. I'm sending it out now to avoid it getting stuck in my tree
(and possibly never to be seen again if I lose interest in the psionw
port).
Included:
Add support for ARM 7TDMI CPU
Fix some panic strings with \n at the end (which Ben should
probably get rid of when fixing the disassem stuff)
Pending changes to sys/arch/arm:
Inline asm versions of cpufunc.h funcs, which will make the
hpcarm crews's lives easier - currently they inline the stuff
by hand actually in the middle of C code :-(
Pmap panic string fixes.
--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment;
filename=netbsd-20010602-arm-7tdmi.patch
Index: arm/cpufunc.c
===================================================================
RCS file: /pub/NetBSD-CVS/syssrc/sys/arch/arm/arm/cpufunc.c,v
retrieving revision 1.3
diff -u -r1.3 cpufunc.c
--- cpufunc.c 2001/05/13 14:41:56 1.3
+++ cpufunc.c 2001/06/02 22:44:15
@@ -1,6 +1,7 @@
/* $NetBSD: cpufunc.c,v 1.3 2001/05/13 14:41:56 bjh21 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.
@@ -195,6 +196,76 @@
};
#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 */
@@ -370,6 +441,15 @@
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) {
@@ -425,7 +505,7 @@
#endif
#endif
-#ifdef CPU_ARM6
+#if defined(CPU_ARM6)
/*
* ARM6 data abort fixup
*
@@ -507,11 +587,11 @@
base = (fault_instruction >> 16) & 0x0f;
if (base == 13 && (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
if (base == 15) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
#ifdef DEBUG_FAULT_CORRECTION
if (pmap_debug_level >=0)
@@ -533,7 +613,7 @@
offset = fault_instruction & 0x0f;
if (offset == base) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
/* Register offset - hard we have to cope with shifts ! */
@@ -544,12 +624,12 @@
else {
if ((fault_instruction & (1 << 7)) != 0) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
shift = ((fault_instruction >> 8) & 0xf);
if (base == shift) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
#ifdef DEBUG_FAULT_CORRECTION
if (pmap_debug_level >=0)
@@ -575,7 +655,7 @@
break;
case 3 : /* Rotate right */
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
break;
}
@@ -617,7 +697,7 @@
base = (fault_instruction >> 16) & 0x0f;
if (base == 15) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
/* Count registers transferred */
count = 0;
@@ -663,11 +743,11 @@
base = (fault_instruction >> 16) & 0x0f;
if (base == 13 && (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
if (base == 15) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
offset = (fault_instruction & 0xff) << 2;
@@ -718,7 +798,7 @@
}
#endif /* CPU_ARM6 */
-#ifdef CPU_ARM7
+#if defined(CPU_ARM7) || defined(CPU_ARM7TDMI)
/*
* ARM7 data abort fixup
*
@@ -794,11 +874,11 @@
base = (fault_instruction >> 16) & 0x0f;
if (base == 13 && (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
if (base == 15) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
#ifdef DEBUG_FAULT_CORRECTION
if (pmap_debug_level >=0)
@@ -820,7 +900,7 @@
offset = fault_instruction & 0x0f;
if (offset == base) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
/* Register offset - hard we have to cope with shifts ! */
@@ -831,12 +911,12 @@
else {
if ((fault_instruction & (1 << 7)) != 0) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
shift = ((fault_instruction >> 8) & 0xf);
if (base == shift) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
#ifdef DEBUG_FAULT_CORRECTION
if (pmap_debug_level >=0)
@@ -862,7 +942,7 @@
break;
case 3 : /* Rotate right */
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
break;
}
@@ -903,7 +983,7 @@
base = (fault_instruction >> 16) & 0x0f;
if (base == 15) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
/* Count registers transferred */
count = 0;
@@ -949,11 +1029,11 @@
base = (fault_instruction >> 16) & 0x0f;
if (base == 13 && (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
if (base == 15) {
disassemble(fault_pc);
- panic("Abort handler cannot fix this :-(\n");
+ panic("Abort handler cannot fix this :-(");
}
offset = (fault_instruction & 0xff) << 2;
@@ -1002,14 +1082,14 @@
return(ABORT_FIXUP_OK);
}
-#endif /* CPU_ARM7 */
+#endif /* CPU_ARM7 || CPU_ARM7TDMI */
/*
* 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
@@ -1050,9 +1130,10 @@
}
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 },
@@ -1065,7 +1146,7 @@
{ 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[] = {
@@ -1146,6 +1227,38 @@
cpu_control(0xffffffff, cpuctrl);
}
#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[] = {
Index: arm/cpufunc_asm.S
===================================================================
RCS file: /pub/NetBSD-CVS/syssrc/sys/arch/arm/arm/cpufunc_asm.S,v
retrieving revision 1.1
diff -u -r1.1 cpufunc_asm.S
--- cpufunc_asm.S 2001/05/06 18:01:44 1.1
+++ cpufunc_asm.S 2001/06/02 22:44:21
@@ -1,6 +1,7 @@
/* $NetBSD: cpufunc_asm.S,v 1.1 2001/05/06 18:01:44 bjh21 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.
@@ -173,6 +174,25 @@
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
@@ -261,6 +281,16 @@
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 */
@@ -304,6 +334,18 @@
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 */
@@ -756,6 +798,10 @@
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 */
Index: arm32/cpu.c
===================================================================
RCS file: /pub/NetBSD-CVS/syssrc/sys/arch/arm/arm32/cpu.c,v
retrieving revision 1.2
diff -u -r1.2 cpu.c
--- cpu.c 2001/05/13 13:53:08 1.2
+++ cpu.c 2001/06/02 22:44:25
@@ -294,7 +294,7 @@
{ "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 @@
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 @@
#ifdef CPU_ARM7
case CPU_CLASS_ARM7:
#endif
+#ifdef CPU_ARM7TDMI
+ case CPU_CLASS_ARM7TDMI:
+#endif
#ifdef CPU_ARM8
case CPU_CLASS_ARM8:
#endif
Index: include/cpufunc.h
===================================================================
RCS file: /pub/NetBSD-CVS/syssrc/sys/arch/arm/include/cpufunc.h,v
retrieving revision 1.2
diff -u -r1.2 cpufunc.h
--- cpufunc.h 2001/03/06 22:29:13 1.2
+++ cpufunc.h 2001/06/02 22:44:50
@@ -202,6 +202,16 @@
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));
--=-=-=
--
http://ape.n3.net
--=-=-=--