From be13b85887ff7e8d0dd8052591163d1a8d488d9f Mon Sep 17 00:00:00 2001 From: thorpej Date: Wed, 14 Nov 2001 01:00:05 +0000 Subject: [PATCH] * Give the XScale its own cpu_control() entry point; we have to flush the Branch Target Buffer of the BPRD bit changes. * Enable Branch Prediction on the XScale by default. * Don't invalidate the Branch Target Buffer explicitly. the i80200 manual (section 5.1, Branch Target Buffer Operation) notes that manual software management of the BTB is unnecessary; it is flushed implicitly when: * processor resets * FCSE process ID is written * I-cache is invalidated --- sys/arch/arm/arm/cpufunc.c | 10 +++++++--- sys/arch/arm/arm/cpufunc_asm_xscale.S | 23 +++++++++++++++++------ sys/arch/arm/include/cpufunc.h | 4 +++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c index efd8a72b9a8c..c5c0532bf225 100644 --- a/sys/arch/arm/arm/cpufunc.c +++ b/sys/arch/arm/arm/cpufunc.c @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.c,v 1.14 2001/11/10 23:12:41 thorpej Exp $ */ +/* $NetBSD: cpufunc.c,v 1.15 2001/11/14 01:00:05 thorpej Exp $ */ /* * arm7tdmi support code Copyright (c) 2001 John Fremlin @@ -557,7 +557,7 @@ struct cpu_functions xscale_cpufuncs = { /* MMU functions */ - cpufunc_control, /* control */ + xscale_control, /* control */ cpufunc_domains, /* domain */ xscale_setttb, /* setttb */ cpufunc_faultstatus, /* faultstatus */ @@ -1449,10 +1449,13 @@ sa110_setup(args) #ifdef CPU_XSCALE struct cpu_option xscale_options[] = { #ifdef COMPAT_12 + { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, #endif /* COMPAT_12 */ + { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, + { "xscale.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, { "xscale.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, { "xscale.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, { "xscale.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, @@ -1474,7 +1477,8 @@ xscale_setup(args) cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE - | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE; + | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE + | CPU_CONTROL_BPRD_ENABLE; cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE diff --git a/sys/arch/arm/arm/cpufunc_asm_xscale.S b/sys/arch/arm/arm/cpufunc_asm_xscale.S index f88eca302578..5f7e824511a6 100644 --- a/sys/arch/arm/arm/cpufunc_asm_xscale.S +++ b/sys/arch/arm/arm/cpufunc_asm_xscale.S @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc_asm_xscale.S,v 1.3 2001/11/11 17:18:27 thorpej Exp $ */ +/* $NetBSD: cpufunc_asm_xscale.S,v 1.4 2001/11/14 01:00:05 thorpej Exp $ */ /* * Copyright (c) 2001 Matt Thomas @@ -53,6 +53,22 @@ Lblock_userspace_access: mov r0, r0 /* wait for it to complete */ ;\ sub pc, pc, #4 /* branch to next insn */ +/* + * We need a separate cpu_control() entry point, since we have to + * invalidate the Branch Target Buffer in the event the BPRD bit + * changes in the control register. + */ +ENTRY(xscale_control) + mrc p15, 0, r3, c1, c0, 0 /* Read the control register */ + bic r2, r3, r0 /* Clear bits */ + eor r2, r2, r1 /* XOR bits */ + + teq r2, r3 /* Only write if there was a change */ + mcrne p15, 0, r0, c7, c5, 6 /* Invalidate the BTB */ + mcrne p15, 0, r2, c1, c0, 0 /* Write new control register */ + mov r0, r3 /* Return old value */ + mov pc, lr + /* * Functions to set the MMU Translation Table Base register * @@ -100,7 +116,6 @@ ENTRY(xscale_setttb) ENTRY(xscale_tlb_flushID_SE) mcr p15, 0, r0, c8, c6, 1 /* flush D tlb single entry */ mcr p15, 0, r0, c8, c5, 1 /* flush I tlb single entry */ - mcr p15, 0, r0, c7, c5, 6 /* inv. BTB */ mov pc, lr /* @@ -120,7 +135,6 @@ ENTRY(xscale_cache_flushD) ENTRY(xscale_cache_flushI_SE) mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ - mcr p15, 0, r0, c7, c5, 6 /* inv. BTB */ mov pc, lr ENTRY(xscale_cache_flushD_SE) @@ -240,7 +254,6 @@ ENTRY(xscale_cache_purgeID_E) mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */ mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ - mcr p15, 0, r0, c7, c5, 6 /* inv. BTB */ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */ mov pc, lr @@ -283,7 +296,6 @@ ENTRY(xscale_cache_purgeID_rng) 1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */ mcr p15, 0, r0, c7, c6, 1 /* flush D cache single entry */ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ - mcr p15, 0, r0, c7, c5, 6 /* inv. BTB */ add r0, r0, #32 subs r1, r1, #32 bpl 1b @@ -318,7 +330,6 @@ ENTRY(xscale_cache_syncI_rng) 1: mcr p15, 0, r0, c7, c10, 1 /* clean D cache entry */ mcr p15, 0, r0, c7, c5, 1 /* flush I cache single entry */ - mcr p15, 0, r0, c7, c5, 6 /* inv. BTB */ add r0, r0, #32 subs r1, r1, #32 bpl 1b diff --git a/sys/arch/arm/include/cpufunc.h b/sys/arch/arm/include/cpufunc.h index 0ecf07510d7f..c4f5e51f735a 100644 --- a/sys/arch/arm/include/cpufunc.h +++ b/sys/arch/arm/include/cpufunc.h @@ -1,4 +1,4 @@ -/* $NetBSD: cpufunc.h,v 1.10 2001/10/18 14:10:07 rearnsha Exp $ */ +/* $NetBSD: cpufunc.h,v 1.11 2001/11/14 01:00:06 thorpej Exp $ */ /* * Copyright (c) 1997 Mark Brinicombe. @@ -307,6 +307,8 @@ void sa110_setup __P((char *string)); #endif /* CPU_SA110 */ #ifdef CPU_XSCALE +u_int xscale_control __P((u_int clear, u_int bic)); + void xscale_setttb __P((u_int ttb)); void xscale_tlb_flushID_SE __P((u_int va));