summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/cpu/bcmcore/src
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/cpu/bcmcore/src')
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/Makefile8
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c170
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S490
-rwxr-xr-xcfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S219
4 files changed, 887 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/Makefile b/cfe/cfe/arch/mips/cpu/bcmcore/src/Makefile
new file mode 100755
index 0000000..76662a0
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/Makefile
@@ -0,0 +1,8 @@
+
+ALLOBJS += bcmcore_cpuinit.o bcmcore_l1cache.o
+ifeq ($(strip ${CFG_RAMAPP}),1)
+ALLOBJS += bcmcore_arena.o
+endif
+CFLAGS += -mips32 -D_MIPSREGS32_ -mno-abicalls -fPIC
+# CFLAGS += -mips2 -D_MIPSREGS32_
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c
new file mode 100755
index 0000000..b368158
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_arena.c
@@ -0,0 +1,170 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical Memory (arena) manager File: bcmcore_arena.c
+ *
+ * This module describes the physical memory available to the
+ * firmware.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+#include "sbmips.h"
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "lib_arena.h"
+
+#include "cfe_error.h"
+
+#include "cfe.h"
+#include "cfe_mem.h"
+
+#include "initdata.h"
+
+#define _NOPROTOS_
+#include "cfe_boot.h"
+#undef _NOPROTOS_
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define ARENA_RANGE(bottom,top,type) arena_markrange(&cfe_arena,(uint64_t)(bottom), \
+ (uint64_t)(top)-(uint64_t)bottom+1,(type),NULL)
+
+#define MEG (1024*1024)
+#define KB 1024
+#define PAGESIZE 4096
+#define CFE_BOOTAREA_SIZE (256*KB)
+#define CFE_BOOTAREA_ADDR 0x20000000
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+extern arena_t cfe_arena;
+
+unsigned int mem_bootarea_start;
+unsigned int mem_bootarea_size;
+
+void bcmcore_arena_init(void);
+void bcmcore_pagetable_init(uint64_t *ptaddr,unsigned int physaddr);
+
+
+/* *********************************************************************
+ * bcmcore_arena_init()
+ *
+ * Create the initial map of physical memory
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void bcmcore_arena_init(void)
+{
+ int64_t memleft;
+
+#if 1 /* defined(CONFIG_MIPS_BRCM) */
+ arena_init(&cfe_arena,0x0,0x0); /* 2^32 physical bytes */
+#else
+ arena_init(&cfe_arena,0x0,0x100000000); /* 2^32 physical bytes */
+#endif
+
+ /*
+ * Mark the ranges from the SB1250's memory map
+ */
+
+ ARENA_RANGE(0x0000000000,0x000FFFFFFF,MEMTYPE_DRAM_NOTINSTALLED);
+
+ /*
+ * Now, fix up the map with what is known about *this* system.
+ *
+ * Do each 256MB chunk.
+ */
+
+ memleft = ((int64_t) mem_totalsize) << 20;
+
+ arena_markrange(&cfe_arena,0x00000000,memleft,MEMTYPE_DRAM_AVAILABLE,NULL);
+
+ /*
+ * Do the boot ROM
+ */
+
+ arena_markrange(&cfe_arena,0x1FC00000,2*1024*1024,MEMTYPE_BOOTROM,NULL);
+
+}
+
+
+/* *********************************************************************
+ * BCMCORE_PAGETABLE_INIT(ptaddr,physaddr)
+ *
+ * This routine constructs the page table. 256KB is mapped
+ * starting at physical address 'physaddr' - the resulting
+ * table entries are placed at 'ptaddr'
+ *
+ * Input parameters:
+ * ptaddr - base of page table
+ * physaddr - starting physical addr of area to map
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void bcmcore_pagetable_init(uint64_t *ptaddr,unsigned int physaddr)
+{
+ int idx;
+
+ for (idx = 0; idx < (CFE_BOOTAREA_SIZE/PAGESIZE); idx++) {
+ ptaddr[idx] = (physaddr >> 6) |
+ V_TLBLO_CALG(K_CALG_NONCOHERENT) |
+ M_TLBLO_V |
+ M_TLBLO_D;
+ physaddr += PAGESIZE;
+ }
+
+}
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S
new file mode 100755
index 0000000..7c04b51
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_cpuinit.S
@@ -0,0 +1,490 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * CPU initialization File: bcmcore_cpuinit.S
+ *
+ * This module contains code to initialize the CPU cores.
+ *
+ * Note: all the routines in this module rely on registers only,
+ * since DRAM may not be active yet.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * XX Copyright 2000,2001
+ * Broadcom Corporation. All rights reserved.
+ *
+ * BROADCOM PROPRIETARY AND CONFIDENTIAL
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the license.
+ ********************************************************************* */
+
+#include "sbmips.h"
+#include "exception.h"
+#include "bsp_config.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for ERET and HAZARD */
+
+
+ .text
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define LINESIZE 16
+
+#define CACHEOP(cachename,op) ((cachename) | ((op) << 2))
+
+#define CACHE_OP_IDXINVAL 0
+#define CACHE_OP_IDXLOADTAG 1
+#define CACHE_OP_IDXSTORETAG 2
+#define CACHE_OP_IMPLRSVD 3
+#define CACHE_OP_HITINVAL 4
+#define CACHE_OP_FILL 5
+#define CACHE_OP_HITWRITEBACK_INVAL 5
+#define CACHE_OP_HITWRITEBACK 6
+#define CACHE_OP_FETCHLOCK 7
+
+#define L2C 3
+#define L1C_I 0
+#define L1C_D 1
+
+
+/*
+ * Duplicates from cfe_iocb.h -- warning!
+ */
+
+#define CFE_CACHE_FLUSH_D 1
+#define CFE_CACHE_INVAL_I 2
+#define CFE_CACHE_INVAL_D 4
+#define CFE_CACHE_INVAL_L2 8
+#define CFE_CACHE_FLUSH_L2 16
+#define CFE_CACHE_INVAL_RANGE 32
+#define CFE_CACHE_FLUSH_RANGE 64
+
+#define BCMCORE_NTLBENTRIES 32
+
+
+
+#define SENDCHAR(c) \
+ li t0,0xBF800000 ; \
+ li t1,c ; \
+ sb t1,0(t0)
+
+
+#define R_CPU_CP0INIT _TBLIDX(0)
+#define R_CPU_L1CINIT _TBLIDX(1)
+#define R_CPU_SETLEDS _TBLIDX(2)
+#define R_CPU_L1CFLASHD _TBLIDX(3)
+#define R_CPU_L1CINVALI _TBLIDX(4)
+
+#define SETLEDS1(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_SETLEDS)
+#define SETLEDS(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG0(cpuinit_table,R_CPU_SETLEDS)
+
+cpuinit_table:
+ _LONG_ bcmcore_cp0_init # [ 0 ] R_CPU_CP0INIT
+ _LONG_ bcmcore_l1cache_init # [ 1 ] R_CPU_L1CINIT
+ _LONG_ board_setleds # [ 2 ] R_CPU_SETLEDS
+ _LONG_ bcmcore_l1cache_flush_d # [ 3 ] R_CPU_L1CFLASHD
+ _LONG_ bcmcore_l1cache_inval_i # [ 4 ] R_CPU_L1CINVALI
+
+
+/* *********************************************************************
+ * BCMCORE_CP0_INIT()
+ *
+ * Initialize an BCMCORE CPU's CP0 registers
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * all
+ ********************************************************************* */
+
+
+LEAF(bcmcore_cp0_init)
+
+ .set noreorder
+
+ mtc0 zero,C0_WATCHLO # Watch registers.
+ mtc0 zero,C0_WATCHHI
+ mtc0 zero,C0_CAUSE # must clear before writing SR
+
+ mfc0 v0,C0_SR # Get status register
+ and v0,M_SR_SR # preserve soft reset
+#ifdef DEBUG_ENV_ICE
+ and v0,~M_SR_BEV
+#else
+ or v0,M_SR_BEV # exceptions to boot vector
+#endif
+ mtc0 v0,C0_SR # set up the status register
+
+
+ mfc0 v0,C0_CONFIG # get current CONFIG register
+ srl v0,v0,3 # strip out K0 bits
+ sll v0,v0,3 # k0 bits now zero
+ or v0,v0,K_CFG_K0COH_CACHEABLE # K0 is cacheable.
+ mtc0 v0,C0_CONFIG
+ nop
+
+ mtc0 zero,C0_WATCHLO # Watch registers.
+ mtc0 zero,C0_WATCHHI
+
+ mtc0 zero,C0_TLBHI # TLB entry (high half)
+ nop
+
+
+ #
+ # This is probably not the right init value for C0_COMPARE,
+ # but it seems to be necessary for the sim model right now.
+ #
+
+ li v0,-1
+ mtc0 v0,C0_COMPARE
+ nop
+
+ #
+ # Initialize all the TLB entries to some invalid value
+ #
+
+ mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */
+ nop
+ mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */
+ nop
+ mtc0 zero,C0_PGMASK /* 4K pages */
+ nop
+
+ li t0,K1BASE /* tlbhi = impossible vpn */
+ li t1,(BCMCORE_NTLBENTRIES-1) /* index */
+
+
+ nop
+1: mtc0 t0,C0_TLBHI
+ nop
+ mtc0 t1,C0_INX
+ nop
+ addu t0,0x2000 /* inc vpn */
+ tlbwi
+ bnez t1,1b
+ subu t1,1 # BDSLOT
+ .set reorder
+
+
+/*
+ * XXX What other CP0 initialization do I need?
+ */
+
+ jr ra
+
+
+END(bcmcore_cp0_init)
+
+
+/* *********************************************************************
+ * BCMCORE_CPUINIT
+ *
+ * Do initialization of the Broadcom core
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+LEAF(bcmcore_cpuinit)
+
+ move fp,ra
+
+ SETLEDS1('C','P','U','I')
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_CP0INIT)
+
+ SETLEDS1('L','1','C','I')
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINIT)
+
+ move ra,fp
+ j ra
+
+END(bcmcore_cpuinit)
+
+
+/* *********************************************************************
+ * BCMCORE_KSEG0_SWITCH
+ *
+ * Return to the address of the routine that called us, except
+ * in K0seg instead of K1seg
+ *
+ * Input parameters:
+ * nothing - ra is return address
+ *
+ * Return value:
+ * ra = same return address in K0
+ ********************************************************************* */
+
+LEAF(bcmcore_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(bcmcore_kseg0_switch)
+
+/* *********************************************************************
+ * BCMCORE_NULL
+ *
+ * Dummy handler for routines we don't need to implement, like
+ * the multiprocessor stuff
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * none
+ ********************************************************************* */
+
+LEAF(bcmcore_null)
+
+ j ra
+
+END(bcmcore_null)
+
+
+/* *********************************************************************
+ * BCMCORE_CPURESTART
+ *
+ * This routine is called when someone soft-exits to CFE. We
+ * reinitialize any CP0 stuff here.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(bcmcore_cpurestart)
+
+ j ra
+
+END(bcmcore_cpurestart)
+
+
+/* *********************************************************************
+ * BCMCORE_CACHEOPS
+ *
+ * Perform various cache operations on a BCM Core
+ *
+ * Input parameters:
+ * a0 - flag bits (CFE_CACHE_xxx)
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2,t3,v1,s0
+ ********************************************************************* */
+
+LEAF(bcmcore_cacheops)
+
+ move s0,ra
+
+ move v1,a0
+
+ /*
+ * With no flags, we flush L1D and invalid L1I
+ */
+
+ bne v1,zero,1f
+ li v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I
+1:
+
+ /*
+ * Flush the D-Cache, since the program we loaded is "data".
+ */
+
+ and a0,v1,CFE_CACHE_FLUSH_D
+ beq a0,zero,1f
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CFLASHD)
+1:
+
+ /*
+ * Invalidate the I-Cache, so that addresses in the program
+ * region will miss and need to be filled from the data we
+ * just flushed above.
+ */
+
+ and a0,v1,CFE_CACHE_INVAL_I
+ beq a0,zero,1f
+ CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINVALI)
+1:
+
+
+ .set push
+ .set mips32
+
+ /*
+ * Invalidate cache range
+ */
+
+ and a0,v1,CFE_CACHE_INVAL_RANGE
+ beq a0,zero,2f
+
+ move t0,a1
+1: cache CACHEOP(L1C_D,CACHE_OP_HITINVAL),0(t0)
+ add t0,LINESIZE
+ blt t0,a2,1b
+
+ /*
+ * Flush cache range
+ */
+
+
+2:
+ and a0,v1,CFE_CACHE_FLUSH_RANGE
+ beq a0,zero,2f
+
+ move t0,a1
+1: cache CACHEOP(L1C_D,CACHE_OP_HITWRITEBACK_INVAL),0(t0)
+ add t0,LINESIZE
+ blt t0,a2,1b
+
+2:
+
+ .set pop
+
+
+ move ra,s0
+ j ra
+
+END(bcmcore_cacheops)
+
+
+
+/* *********************************************************************
+ * BCMCORE_TLBHANDLER
+ *
+ * This is the TLB exception handler for the bcmcore
+ *
+ * Note: only K0 and K1 are available to us at this time.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+LEAF(bcmcore_tlbhandler)
+ .set noreorder
+ .set noat
+
+/*
+ * XXX XXX XXX XXX XXX
+ *
+ * This won't work as-is on the BCMCORE. The CONTEXT register is not
+ * wide enough! In fact, it's broken on all pre-mips4 CPUs.
+ *
+ * XXX XXX XXX XXX XXX
+ */
+
+/*
+ * This requires a bit of explanation: We only support 256KB
+ * of mapped space for the boot program. This space will be
+ * mapped from 0x2000_0000 to 0x2004_0000 to some physical
+ * memory allocated by the firmware. This is 64 pages
+ * of 4KB each.
+ *
+ * We know our BadVPN2 will be in the range
+ * 0x100000 to 0x1001F0, since the memory is mapped from
+ * 0x2000_0000 to 0x2004_0000. BadVPN2 plus the four bits
+ * of zeroes at the end are bits 31..9
+ *
+ * We also want to place the PTEbase on something other than
+ * a 16MB boundary. Each entry is 16 bytes, and there
+ * are 64 entries, so we need only 10 bits to address
+ * the entire table (it can therefore be aligned on a
+ * 1KB boundary).
+ *
+ * To make this work, we'll shift PTEbase to the right, leaving
+ * the bottom ten bits for the page number, as:
+ *
+ * Bits 31..10: PTEbase
+ * Bits 9..4: BadVPN
+ * Bits 3..0: 16 bytes for table entry
+ *
+ * Therefore:
+ * PTEbase gets shifted right 13 bits.
+ * BadVPN gets masked at 6 bits (mask is 0x3F0)
+ * The bottom 4 bits are zero.
+ *
+ * To range check the address, we can shift the Bad VPN
+ * right by 9 bits, and check for values of 0x1000 and
+ * 0x1001.
+ */
+
+
+ /*
+ * This part range checks the VPN2 field in the
+ * context register. We only handle
+ * VPN2s in the range 0x100000 to 0x1001F0
+ */
+ mfc0 k0,C0_TLBHI
+
+ mfc0 k0,C0_CTEXT # Get context
+ sra k0,8 # keep hi part
+ and k0,0x1FFF # of VPN2
+ li k1,0x1000 # 0x1000 is ok
+ beq k0,k1,1f #
+ nop # BDSLOT
+ li k1,0x1001 # 0x1001 is ok
+ beq k0,k1,1f #
+ nop # BDSLOT
+
+ li k0,XTYPE_TLBFILL # all other bits are not
+ b _exc_entry
+ nop # BDSLOT
+
+1: mfc0 k0,C0_CTEXT # Get context
+ sra k0,13 # Shift PTEbase
+ li k1,0x3FF # Generate mask to kill
+ not k1 # BadVPN2 bits
+ and k0,k1 # keep only PTEBase part.
+
+ mfc0 k1,C0_CTEXT # Get Context
+ and k1,0x3F0 # Keep only BadVPN2 bits
+ or k1,k0 # Replace PTEBase
+
+ ld k0,0(k1) # Load entrylo0
+ ld k1,8(k1) # Load entrylo1
+ mtc0 k0,C0_TLBLO0 # and write to CP0
+ mtc0 k1,C0_TLBLO1
+ tlbwr # put it in the TLB
+ ERET
+ nop
+
+ .set reorder
+ .set at
+
+END(bcmcore_tlbhandler)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
diff --git a/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S
new file mode 100755
index 0000000..fa39bfd
--- /dev/null
+++ b/cfe/cfe/arch/mips/cpu/bcmcore/src/bcmcore_l1cache.S
@@ -0,0 +1,219 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * L1C initialization File: bcmcore_l1cache.S
+ *
+ * This module contains code to initialize the CPU's caches
+ *
+ * Note: all the routines in this module rely on registers only,
+ * since DRAM may not be active yet.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * XX Copyright 2000,2001
+ * Broadcom Corporation. All rights reserved.
+ *
+ * BROADCOM PROPRIETARY AND CONFIDENTIAL
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the license.
+ ********************************************************************* */
+
+#include "sbmips.h"
+#include "bsp_config.h"
+
+ .text
+
+ .set push
+ .set mips32
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define CP0_CFG_ISMSK (0x7 << 22)
+#define CP0_CFG_ISSHF 22
+#define CP0_CFG_ILMSK (0x7 << 19)
+#define CP0_CFG_ILSHF 19
+#define CP0_CFG_IAMSK (0x7 << 16)
+#define CP0_CFG_IASHF 16
+#define CP0_CFG_DSMSK (0x7 << 13)
+#define CP0_CFG_DSSHF 13
+#define CP0_CFG_DLMSK (0x7 << 10)
+#define CP0_CFG_DLSHF 10
+#define CP0_CFG_DAMSK (0x7 << 7)
+#define CP0_CFG_DASHF 7
+
+#define cacheop(kva, size, linesize, op) \
+ .set noreorder; \
+ addu t1, kva, size; \
+ subu t2, linesize, 1; \
+ not t2; \
+ and t0, kva, t2; \
+ addu t1, -1; \
+ and t1, t2; \
+10: cache op, 0(t0); \
+ bne t0, t1, 10b; \
+ addu t0, linesize; \
+11: \
+ .set reorder
+
+#define size_icache(size, linesize) \
+ mfc0 t7, C0_CONFIG, 1; \
+ and t0, t7, CP0_CFG_ILMSK; \
+ srl t0, t0, CP0_CFG_ILSHF; \
+ move linesize, zero; \
+ beq t0, zero,1f; \
+ add t0, 1; \
+ li linesize, 1; \
+ sll linesize, t0; \
+1: and t0, t7, CP0_CFG_ISMSK; \
+ srl t0, t0, CP0_CFG_ISSHF; \
+ li size, 64; \
+ sll size, t0; \
+ and t0, t7, CP0_CFG_IAMSK; \
+ srl t0, t0, CP0_CFG_IASHF; \
+ add t0, 1; \
+ mult size, t0; \
+ mflo size; \
+ mult size, linesize; \
+ mflo size
+
+#define size_dcache(size, linesize) \
+ mfc0 t7, C0_CONFIG, 1; \
+ and t0, t7, CP0_CFG_DLMSK; \
+ srl t0, t0, CP0_CFG_DLSHF; \
+ move linesize, zero; \
+ beq t0, zero,1f; \
+ add t0, 1; \
+ li linesize, 1; \
+ sll linesize, t0; \
+1: and t0, t7, CP0_CFG_DSMSK; \
+ srl t0, t0, CP0_CFG_DSSHF; \
+ li size, 64; \
+ sll size, t0; \
+ and t0, t7, CP0_CFG_DAMSK; \
+ srl t0, t0, CP0_CFG_DASHF; \
+ add t0, 1; \
+ mult size, t0; \
+ mflo size; \
+ mult size, linesize; \
+ mflo size
+
+
+/* *********************************************************************
+ * BCMCORE_L1CACHE_INIT()
+ *
+ * Initialize the L1 Cache
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2
+ ********************************************************************* */
+
+LEAF(bcmcore_l1cache_init)
+
+ mtc0 zero, C0_TAGLO # Initialize TAGLO register
+ mtc0 zero, C0_TAGLO,1 # Initialize DataLo register
+
+ li a0, K0BASE # Initialise primary instruction cache.
+ size_icache(a1, a2)
+ cacheop(a0, a1, a2, Index_Store_Tag_I)
+
+ li a0, K0BASE # Initialise primary data cache.
+ size_dcache(a1, a2)
+ cacheop(a0, a1, a2, Index_Store_Tag_D)
+
+ jr ra
+
+END(bcmcore_l1cache_init)
+
+/* *********************************************************************
+ * BCMCORE_L1CACHE_INVAL_I()
+ *
+ * Invalidate the entire ICache
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2
+ ********************************************************************* */
+LEAF(bcmcore_l1cache_inval_i)
+
+ li a0, K0BASE
+ size_icache(a1, a2)
+ cacheop(a0, a1, a2, Index_Invalidate_I)
+
+ j ra
+
+END(bcmcore_l1cache_inval_i)
+
+/* *********************************************************************
+ * BCMCORE_L1CACHE_FLUSH_D()
+ *
+ * Flush the entire DCache
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * t0,t1,t2
+ ********************************************************************* */
+LEAF(bcmcore_l1cache_flush_d)
+
+ li a0, K0BASE
+ size_dcache(a1, a2)
+
+# before flushing cache clear tags pointing to flash memory to avoid writes into flash
+ addu t1, a0, a1
+ subu t2, a2, 1
+ not t2
+ and t0, a0, t2
+ addu t1, -1
+ and t1, t2
+1:
+ cache Index_Load_Tag_D, 0(t0)
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ mfc0 t2, C0_TAGLO # Read TAGLO register
+ and t2, 0x1f000000 # check address
+ li t3, 0x1f000000
+ bne t2, t3, 2f
+ mtc0 zero, C0_TAGLO
+ cache Index_Store_Tag_D, 0(t0) # Reset tag for flash memory locations
+2:
+ .set noreorder;
+ bne t0, t1, 1b
+ addu t0, a2
+ .set reorder
+
+ cacheop(a0, a1, a2, Index_Writeback_Inv_D)
+
+ j ra
+
+END(bcmcore_l1cache_flush_d)
+
+ .set pop
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+