summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/arch/mips/common
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/arch/mips/common')
-rw-r--r--cfe/cfe/arch/mips/common/include/addrspace.h63
-rw-r--r--cfe/cfe/arch/mips/common/include/disasm.h61
-rw-r--r--cfe/cfe/arch/mips/common/include/exception.h223
-rw-r--r--cfe/cfe/arch/mips/common/include/exchandler.h85
-rw-r--r--cfe/cfe/arch/mips/common/include/initdata.h68
-rw-r--r--cfe/cfe/arch/mips/common/include/lib_hssubr.h84
-rw-r--r--cfe/cfe/arch/mips/common/include/lib_physio.h100
-rw-r--r--cfe/cfe/arch/mips/common/include/lib_setjmp.h81
-rwxr-xr-xcfe/cfe/arch/mips/common/include/mipsmacros.h376
-rwxr-xr-xcfe/cfe/arch/mips/common/include/segtable.h97
-rwxr-xr-xcfe/cfe/arch/mips/common/src/Makefile38
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds40
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds40
-rwxr-xr-xcfe/cfe/arch/mips/common/src/cfe_ramapp.lds41
-rwxr-xr-xcfe/cfe/arch/mips/common/src/cfe_rom_cached.lds40
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds43
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds49
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds41
-rw-r--r--cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds39
-rw-r--r--cfe/cfe/arch/mips/common/src/dev_flash_all.S220
-rw-r--r--cfe/cfe/arch/mips/common/src/dev_flashop_engine.S695
-rw-r--r--cfe/cfe/arch/mips/common/src/disasm.c2111
-rw-r--r--cfe/cfe/arch/mips/common/src/exception.S546
-rw-r--r--cfe/cfe/arch/mips/common/src/exchandler.c580
-rwxr-xr-xcfe/cfe/arch/mips/common/src/init_mips.S683
-rwxr-xr-xcfe/cfe/arch/mips/common/src/init_ram.S889
-rw-r--r--cfe/cfe/arch/mips/common/src/lib_hssubr.S194
-rw-r--r--cfe/cfe/arch/mips/common/src/lib_physio.S173
-rw-r--r--cfe/cfe/arch/mips/common/src/lib_setjmp.S94
-rw-r--r--cfe/cfe/arch/mips/common/src/mips_arena.c186
-rwxr-xr-xcfe/cfe/arch/mips/common/src/tools.mk83
-rw-r--r--cfe/cfe/arch/mips/common/src/ui_memtest.c282
32 files changed, 8345 insertions, 0 deletions
diff --git a/cfe/cfe/arch/mips/common/include/addrspace.h b/cfe/cfe/arch/mips/common/include/addrspace.h
new file mode 100644
index 0000000..6330851
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/addrspace.h
@@ -0,0 +1,63 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Address space macros File: addrspace.h
+ *
+ * Macros to deal with physical, virtual, and uncached addresses.
+ * for MIPS, these map to the appropriate KSEG0/KSEG1 macros
+ *
+ * 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"
+
+#define PHYSADDR(x) K0_TO_PHYS(x)
+
+/* If running uncached, force all kernel addresses to be uncached */
+#if CFG_RUNFROMKSEG0
+#define KERNADDR(x) PHYS_TO_K0(x)
+#else
+#define KERNADDR(x) PHYS_TO_K1(x)
+#endif
+
+#define UNCADDR(x) PHYS_TO_K1(x)
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/disasm.h b/cfe/cfe/arch/mips/common/include/disasm.h
new file mode 100644
index 0000000..8a8e7b7
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/disasm.h
@@ -0,0 +1,61 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS disassembler File: disasm.h
+ *
+ * MIPS disassembler (used by ui_examcmds.c)
+ *
+ * Author: Justin Carlson (carlson@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.
+ ********************************************************************* */
+
+#ifndef DISASM_H
+#define DISASM_H
+
+/* Returns a pointer to a read-only string containing the intstruction name */
+char *disasm_inst_name(uint32_t inst);
+
+/* Copies a disassembled version of the instruction into buf, null terminating the
+string. Will not exceed buf_size bytes written; if the disassembled string is
+longer than buf_size, buf_size-1 bytes of the string will be written and that string
+will be null-terminated */
+void disasm_inst(char *buf, int buf_size, uint32_t inst, uint64_t pc);
+#endif
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/exception.h b/cfe/cfe/arch/mips/common/include/exception.h
new file mode 100644
index 0000000..70e87c2
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/exception.h
@@ -0,0 +1,223 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Exception/trap handler defs File: exception.h
+ *
+ * This module describes the exception handlers, exception
+ * trap frames, and dispatch.
+ *
+ * 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.
+ ********************************************************************* */
+
+#ifdef __ASSEMBLER__
+#define _XAIDX(x) (8*(x))
+#else
+#define _XAIDX(x) (x)
+#endif
+
+
+/* *********************************************************************
+ * Exception vectors from the MIPS specification
+ ********************************************************************* */
+
+#define MIPS_ROM_VEC_RESET 0x0000
+#define MIPS_ROM_VEC_TLBFILL 0x0200
+#define MIPS_ROM_VEC_XTLBFILL 0x0280
+#define MIPS_ROM_VEC_CACHEERR 0x0300
+#define MIPS_ROM_VEC_EXCEPTION 0x0380
+#define MIPS_ROM_VEC_INTERRUPT 0x0400
+#define MIPS_ROM_VEC_EJTAG 0x0480
+
+#define MIPS_RAM_VEC_TLBFILL 0x0000
+#define MIPS_RAM_VEC_XTLBFILL 0x0080
+#define MIPS_RAM_VEC_EXCEPTION 0x0180
+#define MIPS_RAM_VEC_INTERRUPT 0x0200
+#define MIPS_RAM_VEC_CACHEERR 0x0100
+#define MIPS_RAM_VEC_END 0x0300
+
+#define MIPS_RAM_EXL_VEC_TLBFILL 0x0100
+#define MIPS_RAM_EXL_VEC_XTLBFILL 0x0180
+
+
+/* *********************************************************************
+ * Fixed locations of other low-memory objects. We stuff some
+ * important data in the spaces between the vectors.
+ ********************************************************************* */
+
+#define CFE_LOCORE_GLOBAL_GP 0x0040 /* our "handle" */
+#define CFE_LOCORE_GLOBAL_SP 0x0048 /* Stack pointer for exceptions */
+#define CFE_LOCORE_GLOBAL_K0TMP 0x0050 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_K1TMP 0x0058 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_RATMP 0x0060 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_GPTMP 0x0068 /* Used by cache error handler */
+#define CFE_LOCORE_GLOBAL_CERRH 0x0070 /* Pointer to cache error handler */
+
+#define CFE_LOCORE_GLOBAL_T0TMP 0x0240 /* used by cache error handler */
+#define CFE_LOCORE_GLOBAL_T1TMP 0x0248 /* used by cache error handler */
+#define CFE_LOCORE_GLOBAL_T2TMP 0x0250 /* used by cache error handler */
+#define CFE_LOCORE_GLOBAL_T3TMP 0x0258 /* used by cache error handler */
+
+/* *********************************************************************
+ * Offsets into our exception handler table.
+ ********************************************************************* */
+
+#define XTYPE_RESET 0
+#define XTYPE_TLBFILL 8
+#define XTYPE_XTLBFILL 16
+#define XTYPE_CACHEERR 24
+#define XTYPE_EXCEPTION 32
+#define XTYPE_INTERRUPT 40
+#define XTYPE_EJTAG 48
+
+/* *********************************************************************
+ * Exception frame definitions.
+ ********************************************************************* */
+
+/*
+ * The exception frame is divided up into pieces, representing the different
+ * parts of the processor that the data comes from:
+ *
+ * CP0: Words 0..7
+ * Int Regs: Words 8..41
+ * FP Regs: Words 42..73
+ * Total size: 74 words
+ */
+
+#define EXCEPTION_SIZE _XAIDX(74)
+
+#define XCP0_BASE 0
+#define XGR_BASE 8
+#define XFR_BASE 42
+
+#define _XCP0IDX(x) _XAIDX((x)+XCP0_BASE)
+#define XCP0_SR _XCP0IDX(0)
+#define XCP0_CAUSE _XCP0IDX(1)
+#define XCP0_EPC _XCP0IDX(2)
+#define XCP0_VADDR _XCP0IDX(3)
+#define XCP0_PRID _XCP0IDX(4)
+
+#define _XGRIDX(x) _XAIDX((x)+XGR_BASE)
+#define XGR_ZERO _XGRIDX(0)
+#define XGR_AT _XGRIDX(1)
+#define XGR_V0 _XGRIDX(2)
+#define XGR_V1 _XGRIDX(3)
+#define XGR_A0 _XGRIDX(4)
+#define XGR_A1 _XGRIDX(5)
+#define XGR_A2 _XGRIDX(6)
+#define XGR_A3 _XGRIDX(7)
+#define XGR_T0 _XGRIDX(8)
+#define XGR_T1 _XGRIDX(9)
+#define XGR_T2 _XGRIDX(10)
+#define XGR_T3 _XGRIDX(11)
+#define XGR_T4 _XGRIDX(12)
+#define XGR_T5 _XGRIDX(13)
+#define XGR_T6 _XGRIDX(14)
+#define XGR_T7 _XGRIDX(15)
+#define XGR_S0 _XGRIDX(16)
+#define XGR_S1 _XGRIDX(17)
+#define XGR_S2 _XGRIDX(18)
+#define XGR_S3 _XGRIDX(19)
+#define XGR_S4 _XGRIDX(20)
+#define XGR_S5 _XGRIDX(21)
+#define XGR_S6 _XGRIDX(22)
+#define XGR_S7 _XGRIDX(23)
+#define XGR_T8 _XGRIDX(24)
+#define XGR_T9 _XGRIDX(25)
+#define XGR_K0 _XGRIDX(26)
+#define XGR_K1 _XGRIDX(27)
+#define XGR_GP _XGRIDX(28)
+#define XGR_SP _XGRIDX(29)
+#define XGR_FP _XGRIDX(30)
+#define XGR_RA _XGRIDX(31)
+#define XGR_LO _XGRIDX(32)
+#define XGR_HI _XGRIDX(33)
+
+
+#define _XFRIDX(x) _XAIDX((x)+XFR_BASE)
+#define XR_F0 _XFRIDX(0)
+#define XR_F1 _XFRIDX(1)
+#define XR_F2 _XFRIDX(2)
+#define XR_F3 _XFRIDX(3)
+#define XR_F4 _XFRIDX(4)
+#define XR_F5 _XFRIDX(5)
+#define XR_F6 _XFRIDX(6)
+#define XR_F7 _XFRIDX(7)
+#define XR_F8 _XFRIDX(8)
+#define XR_F9 _XFRIDX(9)
+#define XR_F10 _XFRIDX(10)
+#define XR_F11 _XFRIDX(11)
+#define XR_F12 _XFRIDX(12)
+#define XR_F13 _XFRIDX(13)
+#define XR_F14 _XFRIDX(14)
+#define XR_F15 _XFRIDX(15)
+#define XR_F16 _XFRIDX(16)
+#define XR_F17 _XFRIDX(17)
+#define XR_F18 _XFRIDX(18)
+#define XR_F19 _XFRIDX(19)
+#define XR_F20 _XFRIDX(20)
+#define XR_F21 _XFRIDX(21)
+#define XR_F22 _XFRIDX(22)
+#define XR_F23 _XFRIDX(23)
+#define XR_F24 _XFRIDX(24)
+#define XR_F25 _XFRIDX(25)
+#define XR_F26 _XFRIDX(26)
+#define XR_F27 _XFRIDX(27)
+#define XR_F28 _XFRIDX(28)
+#define XR_F29 _XFRIDX(29)
+#define XR_F30 _XFRIDX(30)
+#define XR_F31 _XFRIDX(31)
+#define XR_FCR _XFRIDX(32)
+#define XR_FID _XFRIDX(33)
+
+
+#ifndef __ASSEMBLER__
+extern void _exc_setvector(int vectype, void *vecaddr);
+extern void _exc_crash_sim(void);
+extern void _exc_cache_crash_sim(void);
+extern void _exc_restart(void);
+extern void _exc_clear_sr_exl(void);
+extern void _exc_clear_sr_erl(void);
+void cfe_exception(int code,uint64_t *info);
+void cfe_setup_exceptions(void);
+#endif
+
+
+
+
+
diff --git a/cfe/cfe/arch/mips/common/include/exchandler.h b/cfe/cfe/arch/mips/common/include/exchandler.h
new file mode 100644
index 0000000..af268f1
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/exchandler.h
@@ -0,0 +1,85 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Exception Handler definitions File: exchandler.h
+ *
+ * Exception handler functions and constants
+ *
+ * Author: Binh Vo (binh@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.
+ ********************************************************************* */
+
+
+#ifndef _LIB_SETJMP_H
+#include "lib_setjmp.h"
+#endif
+
+#ifndef _LIB_QUEUE_H
+#include "lib_queue.h"
+#endif
+
+#define MEM_BYTE 1
+#define MEM_HALFWORD 2
+#define MEM_WORD 3
+#define MEM_QUADWORD 4
+
+#define EXC_NORMAL_RETURN 0
+#define EXC_CHAIN_EXC 1
+
+typedef struct jmpbuf_s {
+ queue_t stack;
+ jmp_buf jmpbuf;
+} jmpbuf_t;
+
+typedef struct exc_handler_s {
+ int catch_exc;
+ int chain_exc;
+ queue_t jmpbuf_stack;
+} exc_handler_t;
+
+extern exc_handler_t exc_handler;
+
+jmpbuf_t *exc_initialize_block(void);
+void exc_cleanup_block(jmpbuf_t *);
+void exc_cleanup_handler(jmpbuf_t *, int);
+void exc_longjmp_handler(void);
+int mem_peek(void*, long, int);
+int mem_poke(long, uint64_t, int);
+
+
+#define exc_try(jb) (lib_setjmp(((jb)->jmpbuf)))
diff --git a/cfe/cfe/arch/mips/common/include/initdata.h b/cfe/cfe/arch/mips/common/include/initdata.h
new file mode 100644
index 0000000..c5fc0d8
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/initdata.h
@@ -0,0 +1,68 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Data stored in initialization module File: initdata.h
+ *
+ * This file contains data declared by the init module. It also
+ * contains externs for that data so we can keep the types straight.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#if defined(__ASSEMBLER__)
+#define DECLARE_INITVAR(x) \
+ .globl x ; \
+x: _LONG_ 0
+#else
+#define DECLARE_INITVAR(x) \
+ extern long x;
+#endif
+
+DECLARE_INITVAR(mem_textreloc)
+DECLARE_INITVAR(mem_textbase)
+DECLARE_INITVAR(mem_textsize)
+DECLARE_INITVAR(mem_totalsize)
+DECLARE_INITVAR(mem_topofmem)
+DECLARE_INITVAR(mem_heapstart)
+DECLARE_INITVAR(mem_bottomofmem)
+DECLARE_INITVAR(mem_datareloc)
+DECLARE_INITVAR(cpu_prid)
+
+
diff --git a/cfe/cfe/arch/mips/common/include/lib_hssubr.h b/cfe/cfe/arch/mips/common/include/lib_hssubr.h
new file mode 100644
index 0000000..b4df439
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/lib_hssubr.h
@@ -0,0 +1,84 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * "Hyperspace" access routines File: lib_hssubr.h
+ *
+ * Constants, macros, and definitions for routines to deal with
+ * hyperspace (beyond 256MB) on MIPS processors.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#ifndef _LIB_HSSUBR_H
+#define _LIB_HSSUBR_H
+
+/*
+ * If __long64 we can do this via macros. Otherwise, call
+ * the magic functions.
+ */
+
+#if __long64
+
+typedef long hsaddr_t;
+
+#define hs_write8(a,b) *((volatile uint8_t *) (a)) = (b)
+#define hs_write16(a,b) *((volatile uint16_t *) (a)) = (b)
+#define hs_write32(a,b) *((volatile uint32_t *) (a)) = (b)
+#define hs_write64(a,b) *((volatile uint32_t *) (a)) = (b)
+#define hs_read8(a) *((volatile uint8_t *) (a))
+#define hs_read16(a) *((volatile uint16_t *) (a))
+#define hs_read32(a) *((volatile uint32_t *) (a))
+#define hs_read64(a) *((volatile uint64_t *) (a))
+
+#else /* not __long64 */
+
+typedef long long hsaddr_t;
+
+extern void hs_write8(hsaddr_t a,uint8_t b);
+extern void hs_write16(hsaddr_t a,uint16_t b);
+extern void hs_write32(hsaddr_t a,uint32_t b);
+extern void hs_write64(hsaddr_t a,uint64_t b);
+extern uint8_t hs_read8(hsaddr_t a);
+extern uint16_t hs_read16(hsaddr_t a);
+extern uint32_t hs_read32(hsaddr_t a);
+extern uint64_t hs_read64(hsaddr_t a);
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/common/include/lib_physio.h b/cfe/cfe/arch/mips/common/include/lib_physio.h
new file mode 100644
index 0000000..00d0093
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/lib_physio.h
@@ -0,0 +1,100 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical memory peek/poke routines File: lib_physio.h
+ *
+ * Little stub routines to allow access to arbitrary physical
+ * addresses. In most cases this should not be needed, as
+ * many physical addresses are within kseg1, but this handles
+ * the cases that are not automagically, so we don't need
+ * to mess up the code with icky macros and such.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#ifndef _LIB_PHYSIO_H
+#define _LIB_PHYSIO_H
+
+//#ifndef _SB_MIPS_H
+//#include "sbmips.h"
+//#endif
+
+/*
+ * If __long64 we can do this via macros. Otherwise, call
+ * the magic functions.
+ */
+
+#if __long64
+
+typedef long physaddr_t;
+#define _PHYSADDR_T_DEFINED_
+
+/*#define __UNCADDRX(x) PHYS_TO_XKSEG_UNCACHED(x)*/
+#define __UNCADDRX(x) (((physaddr_t)(x))|0x9000000000000000)
+
+
+#define phys_write8(a,b) *((volatile uint8_t *) __UNCADDRX(a)) = (b)
+#define phys_write16(a,b) *((volatile uint16_t *) __UNCADDRX(a)) = (b)
+#define phys_write32(a,b) *((volatile uint32_t *) __UNCADDRX(a)) = (b)
+#define phys_write64(a,b) *((volatile uint64_t *) __UNCADDRX(a)) = (b)
+#define phys_read8(a) *((volatile uint8_t *) __UNCADDRX(a))
+#define phys_read16(a) *((volatile uint16_t *) __UNCADDRX(a))
+#define phys_read32(a) *((volatile uint32_t *) __UNCADDRX(a))
+#define phys_read64(a) *((volatile uint64_t *) __UNCADDRX(a))
+
+#else /* not __long64 */
+
+#ifdef _MIPSREGS32_
+typedef long physaddr_t; /* 32-bit-only processors can't have >32bit pa's */
+#else
+typedef long long physaddr_t; /* Otherwise, they might. */
+#endif
+
+extern void phys_write8(physaddr_t a,uint8_t b);
+extern void phys_write16(physaddr_t a,uint16_t b);
+extern void phys_write32(physaddr_t a,uint32_t b);
+extern void phys_write64(physaddr_t a,uint64_t b);
+extern uint8_t phys_read8(physaddr_t a);
+extern uint16_t phys_read16(physaddr_t a);
+extern uint32_t phys_read32(physaddr_t a);
+extern uint64_t phys_read64(physaddr_t a);
+#endif
+
+#endif
diff --git a/cfe/cfe/arch/mips/common/include/lib_setjmp.h b/cfe/cfe/arch/mips/common/include/lib_setjmp.h
new file mode 100644
index 0000000..b673222
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/lib_setjmp.h
@@ -0,0 +1,81 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * setjmp/longjmp defs File: lib_setjmp.h
+ *
+ * Description of the jmp_buf structure for setjmp and longjmp
+ *
+ * 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.
+ ********************************************************************* */
+
+
+/*
+ * Note that while lib_setjmp() and lib_longjmp() behave like setjmp()
+ * and longjmp() normally do, gcc 3.1.x (and later) assumes things about
+ * how setjmp() and longjmp() should work (even with -fno-builtins). We
+ * don't want it to do those, so these functions must be named differently.
+ */
+
+#ifdef __ASSEMBLER__
+#define _JBIDX(x) (8*(x))
+#else
+#define _JBIDX(x) (x)
+#endif
+
+
+#define JMPB_S0 _JBIDX(0)
+#define JMPB_S1 _JBIDX(1)
+#define JMPB_S2 _JBIDX(2)
+#define JMPB_S3 _JBIDX(3)
+#define JMPB_S4 _JBIDX(4)
+#define JMPB_S5 _JBIDX(5)
+#define JMPB_S6 _JBIDX(6)
+#define JMPB_S7 _JBIDX(7)
+#define JMPB_FP _JBIDX(8)
+#define JMPB_SP _JBIDX(9)
+#define JMPB_RA _JBIDX(10)
+
+#define JMPB_SIZE _JBIDX(11)
+
+#ifndef __ASSEMBLER__
+typedef long long jmp_buf[JMPB_SIZE];
+extern int lib_setjmp(jmp_buf);
+extern void lib_longjmp(jmp_buf,int val);
+#endif
+
diff --git a/cfe/cfe/arch/mips/common/include/mipsmacros.h b/cfe/cfe/arch/mips/common/include/mipsmacros.h
new file mode 100755
index 0000000..072a5e6
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/mipsmacros.h
@@ -0,0 +1,376 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS Macros File: mipsmacros.h
+ *
+ * Macros to deal with various mips-related things.
+ *
+ * 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.
+ ********************************************************************* */
+
+/* *********************************************************************
+ * 32/64-bit macros
+ ********************************************************************* */
+
+#ifdef __long64
+#define _VECT_ .dword
+#define _LONG_ .dword
+#define SR sd
+#define LR ld
+#define ADD dadd
+#define SUB dsub
+#define MFC0 dmfc0
+#define MTC0 dmtc0
+#define REGSIZE 8
+#define BPWSIZE 3 /* bits per word size */
+#define _TBLIDX(x) ((x)*REGSIZE)
+#else
+#define _VECT_ .word
+#define _LONG_ .word
+#define SR sw
+#define LR lw
+#define ADD add
+#define SUB sub
+#define MFC0 mfc0
+#define MTC0 mtc0
+#define REGSIZE 4
+#define BPWSIZE 2
+#define _TBLIDX(x) ((x)*REGSIZE)
+#endif
+
+
+/* *********************************************************************
+ * NORMAL_VECTOR(addr,vecname,vecdest)
+ * NORMAL_XVECTOR(addr,vecname,vecdest,code)
+ *
+ * Declare a trap or dispatch vector. There are two flavors,
+ * DECLARE_XVECTOR sets up an indentifying code in k0 before
+ * jumping to the dispatch routine.
+ *
+ * Input parameters:
+ * addr - vector address
+ * vecname - for label at that address
+ * vecdest - destination (place vector jumps to)
+ * code - code to place in k0 before jumping
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+#define NORMAL_VECTOR(addr,vecname,vecdest) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: b vecdest ; \
+ nop;
+
+#define NORMAL_XVECTOR(addr,vecname,vecdest,code) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: b vecdest ; \
+ li k0,code ; \
+ nop;
+
+
+/* *********************************************************************
+ * Evil macros for bi-endian support.
+ *
+ * The magic here is in the instruction encoded as 0x10000014.
+ *
+ * This instruction in big-endian is: "b .+0x54"
+ * this instruction in little-endian is: "bne zero,zero,.+0x44"
+ *
+ * So, depending on what the system endianness is, it will either
+ * branch to .+0x54 or not branch at all.
+ *
+ * the instructions that follow are:
+ *
+ * 0x10000014 "magic branch" (either-endian)
+ * 0x00000000 nop (bds) (either-endian)
+ * 0xD0BF1A3C lui k0,0xBFD0 (little-endian)
+ * 0xxxxx5A27 addu k0,vector (little-endian)
+ * 0x08004003 jr k0 (little-endian)
+ * 0x00000000 nop (bds) (little-endian)
+ * ... space up to offset 0x54
+ * ......... b vecaddr (big-endian)
+ *
+ * The idea is that the big-endian firmware is first, from 0..1MB
+ * in the flash, and the little-endian firmware is second,
+ * from 1..2MB in the flash. The little-endian firmware is
+ * set to load at BFD00000, so that its initial routines will
+ * work until relocation is completed.
+ *
+ * the instructions at the vectors will either jump to the
+ * big-endian or little-endian code based on system endianness.
+ *
+ * The ROM is built by compiling CFE twice, first with
+ * CFG_BIENDIAN=1 and CFG_LITTLE=0 (big-endian) and again
+ * with CFG_BIENDIAN=1 and CFG_LITTLE=1. The resulting
+ * cfe.bin files are located at 0xBFC00000 and 0xBFD00000
+ * for big and little-endian versions, respectively.
+ *
+ * More information about how this works can be found in the
+ * CFE Manual.
+ ********************************************************************* */
+
+#define __SWAPW(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))
+
+#define BIENDIAN_VECTOR(addr,vecname,vecdest) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: .word 0x10000014 ; \
+ .word 0 ; \
+ .word ((__SWAPW(BIENDIAN_LE_BASE >> 16)) << 16) | 0x1A3C ; \
+ .word (0x00005A27 | (((addr) & 0xFF) << 24) | (((addr) & 0xFF00) << 8)) ; \
+ .word 0x08004003 ; \
+ .word 0 ; \
+ .org ((addr) + 0x54) ; \
+ b vecdest ; \
+ nop;
+
+#define BIENDIAN_XVECTOR(addr,vecname,vecdest,code) \
+ .globl vecname ; \
+ .org addr ; \
+vecname: .word 0x10000014 ; \
+ .word 0 ; \
+ .word ((__SWAPW(BIENDIAN_LE_BASE >> 16)) << 16) | 0x1A3C ; \
+ .word (0x00005A27 | (((addr) & 0xFF) << 24) | (((addr) & 0xFF00) << 8)) ; \
+ .word 0x08004003 ; \
+ .word 0 ; \
+ .org ((addr) + 0x54) ; \
+ b vecdest ; \
+ li k0,code ; \
+ nop;
+
+
+
+/* *********************************************************************
+ * Declare the right versions of DECLARE_VECTOR and
+ * DECLARE_XVECTOR depending on how we're building stuff.
+ * Generally, we only use the biendian version if we're building
+ * as CFG_BIENDIAN=1 and we're doing the big-endian MIPS version.
+ ********************************************************************* */
+
+#if (CFG_BIENDIAN) && defined(__MIPSEB)
+#define DECLARE_VECTOR BIENDIAN_VECTOR
+#define DECLARE_XVECTOR BIENDIAN_XVECTOR
+#else
+#define DECLARE_VECTOR NORMAL_VECTOR
+#define DECLARE_XVECTOR NORMAL_XVECTOR
+#endif
+
+
+
+/* *********************************************************************
+ * LOADREL(reg,label)
+ *
+ * Load the address of a label, but do it in a position-independent
+ * way.
+ *
+ * Input parameters:
+ * reg - register to load
+ * label - label whose address to load
+ *
+ * Return value:
+ * ra is trashed!
+ ********************************************************************* */
+
+#if (!(CFG_RAMAPP))
+#define LOADREL(reg,label) \
+ la reg, label ; \
+ la ra, 100f ; \
+ sub reg, ra ; \
+ .set push ; \
+ .set noreorder ; \
+ bal 100f ; \
+ nop ; \
+ .set pop ; \
+100: ; \
+ addu reg, ra
+#else
+#define LOADREL(reg,label) \
+ la reg,label
+#endif
+
+#if (CFG_RAMAPP)
+#define FIXUP(addr)
+#else
+#define FIXUP(addr) \
+ addu addr, s6
+#endif
+
+
+
+/* *********************************************************************
+ * CALLINIT_KSEG1(label,table,offset)
+ * CALLINIT_KSEG0(label,table,offset)
+ *
+ * Call an initialization routine (usually in another module).
+ * If initialization routine lives in KSEG1 it may need
+ * special fixing if using the cached version of CFE (this is
+ * the default case). CFE is linked at a KSEG0 address.
+ *
+ * Embedded PIC is especially tricky, since the "la"
+ * instruction expands to calculations involving GP.
+ * In that case, use our table of offsets to
+ * load the routine address from a table in memory.
+ *
+ * Input parameters:
+ * label - routine to call if we can call directly
+ * table - symbol name of table containing routine addresses
+ * offset - offset within the above table
+ *
+ * Return value:
+ * k1,ra is trashed.
+ ********************************************************************* */
+
+
+#if CFG_RUNFROMKSEG0
+/* Cached PIC code - call indirect through table */
+#define CALLINIT_KSEG1(table,tableoffset) \
+ LOADREL(k1,table) ; \
+ or k1,K1BASE ; \
+ LR k1,tableoffset(k1) ; \
+ FIXUP (k1); \
+ or k1,K1BASE ; \
+ jal k1
+#define CALLINIT_KSEG0(table,tableoffset) \
+ LOADREL(k1,table) ; \
+ LR k1,tableoffset(k1) ; \
+ FIXUP (k1); \
+ jal k1
+#else
+/* Uncached PIC code - call indirect through table, always same KSEG */
+#define CALLINIT_KSEG1(table,tableoffset) \
+ LOADREL(k1,table) ; \
+ LR k1,tableoffset(k1) ; \
+ FIXUP (k1); \
+ jal k1
+#define CALLINIT_KSEG0 CALLINIT_KSEG1
+#endif
+
+/*
+ * CALLINIT_RELOC is used once CFE's relocation is complete and
+ * the "mem_textreloc" variable is set up. (yes, this is nasty.)
+ * If 'gp' is set, we can presume that we've relocated
+ * and it's safe to read "mem_textreloc", otherwise use the
+ * address as-is from the table.
+ */
+
+#define CALLINIT_RELOC CALLINIT_KSEG0
+
+/* *********************************************************************
+ * SPIN_LOCK(lock,reg1,reg2)
+ *
+ * Acquire a spin lock.
+ *
+ * Input parameters:
+ * lock - symbol (address) of lock to acquire
+ * reg1,reg2 - registers we can use to acquire lock
+ *
+ * Return value:
+ * nothing (lock acquired)
+ ********************************************************************* */
+
+#define SPIN_LOCK(lock,reg1,reg2) \
+ la reg1,lock ; \
+1: sync ; \
+ ll reg2,0(reg1) ; \
+ bne reg2,zero,1b ; \
+ li reg2,1 ; \
+ sc reg2,0(reg1) ; \
+ beq reg2,zero,1b ; \
+ nop
+
+/* *********************************************************************
+ * SPIN_UNLOCK(lock,reg1)
+ *
+ * Release a spin lock.
+ *
+ * Input parameters:
+ * lock - symbol (address) of lock to release
+ * reg1 - a register we can use
+ *
+ * Return value:
+ * nothing (lock released)
+ ********************************************************************* */
+
+
+#define SPIN_UNLOCK(lock,reg1) \
+ la reg1,lock ; \
+ sw zero,0(reg1)
+
+
+/* *********************************************************************
+ * SETCCAMODE(treg,mode)
+ *
+ * Set cacheability mode. For some of the pass1 workarounds we
+ * do this alot, so here's a handy macro.
+ *
+ * Input parameters:
+ * treg - temporary register we can use
+ * mode - new mode (K_CFG_K0COH_xxx)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+#define SETCCAMODE(treg,mode) \
+ mfc0 treg,C0_CONFIG ; \
+ srl treg,treg,3 ; \
+ sll treg,treg,3 ; \
+ or treg,treg,mode ; \
+ mtc0 treg,C0_CONFIG ; \
+ HAZARD
+
+
+/* *********************************************************************
+ * Declare variables
+ ********************************************************************* */
+
+#define DECLARE_LONG(x) \
+ .global x ; \
+x: _LONG_ 0
+
+
+
+
+/*
+ * end
+ */
diff --git a/cfe/cfe/arch/mips/common/include/segtable.h b/cfe/cfe/arch/mips/common/include/segtable.h
new file mode 100755
index 0000000..8a003f0
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/include/segtable.h
@@ -0,0 +1,97 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Segment Table definitions File: segtable.h
+ *
+ * The 'segment table' (bad name) is just a list of addresses
+ * of important stuff used during initialization. We use these
+ * indirections to make life less complicated during code
+ * relocation.
+ *
+ * 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.
+ ********************************************************************* */
+
+
+#if !defined(__ASSEMBLER__)
+#define _TBLIDX(x) (x) /* C handles indexing for us */
+typedef long segtable_t; /* 32 for long32, 64 for long64 */
+#endif
+
+/*
+ * Definitions for the segment_table
+ */
+
+#define R_SEG_ETEXT _TBLIDX(0) /* end of text segment */
+#define R_SEG_FDATA _TBLIDX(1) /* Beginning of data segment */
+#define R_SEG_EDATA _TBLIDX(2) /* end of data segment */
+#define R_SEG_END _TBLIDX(3) /* End of BSS */
+#define R_SEG_FTEXT _TBLIDX(4) /* Beginning of text segment */
+#define R_SEG_FBSS _TBLIDX(5) /* Beginning of BSS */
+#define R_SEG_GP _TBLIDX(6) /* Global Pointer */
+#define R_SEG_RELOCSTART _TBLIDX(7) /* Start of reloc table */
+#define R_SEG_RELOCEND _TBLIDX(8) /* End of reloc table */
+#define R_SEG_APIENTRY _TBLIDX(9) /* API Entry address */
+
+/*
+ * Definitions for the init_table
+ */
+
+#define R_INIT_EARLYINIT _TBLIDX(0) /* pointer to board_earlyinit */
+#define R_INIT_SETLEDS _TBLIDX(1) /* pointer to board_setleds */
+#define R_INIT_DRAMINFO _TBLIDX(2) /* pointer to board_draminfo */
+#define R_INIT_CPUINIT _TBLIDX(3) /* pointer tp cpuinit */
+#define R_INIT_ALTCPU_START1 _TBLIDX(4) /* pointer to altcpu_start1 */
+#define R_INIT_ALTCPU_START2 _TBLIDX(5) /* pointer to altcpu_start2 */
+#define R_INIT_ALTCPU_RESET _TBLIDX(6) /* pointer to altcpu_reset */
+#define R_INIT_CPURESTART _TBLIDX(7) /* pointer to cpurestart */
+#define R_INIT_DRAMINIT _TBLIDX(8) /* pointer to draminit */
+#define R_INIT_CACHEOPS _TBLIDX(9) /* pointer to cacheops */
+#define R_INIT_TLBHANDLER _TBLIDX(10) /* pointer to TLB fault handler */
+#define R_INIT_CMDSTART _TBLIDX(11) /* pointer to cfe_main */
+#define R_INIT_CMDRESTART _TBLIDX(12) /* pointer to cfe_cmd_restart */
+#define R_INIT_DOXREQ _TBLIDX(13) /* pointer to cfe_doxreq */
+#define R_INIT_TP1_SWITCH _TBLIDX(14) /* pointer to tp1_switch */
+#define R_INIT_SIZERAM _TBLIDX(15) /* pointer to board_sizeram */
+
+/*
+ * Definitions for the diag_table
+ */
+
+#define R_DIAG_TEST1 _TBLIDX(0) /* after CPU and cache init, before DRAM init */
+#define R_DIAG_TEST2 _TBLIDX(1) /* after DRAM init, before main */
diff --git a/cfe/cfe/arch/mips/common/src/Makefile b/cfe/cfe/arch/mips/common/src/Makefile
new file mode 100755
index 0000000..638113d
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/Makefile
@@ -0,0 +1,38 @@
+
+#
+# This is just a Makefile fragment -- it is included by the master
+# makefile, cfe.mk
+#
+# This file should just append object file names to "ALLOBJS",
+# but since it is mean to be linked *first*, it will append
+# modules to "CRT0OBJS"
+#
+
+ifndef INIT_MIPS
+INIT_MIPS = init_mips.o
+endif
+
+ifeq ($(strip ${CFG_RAMAPP}),1)
+CRT0OBJS += init_ram.o exception.o
+else
+CRT0OBJS += $(INIT_MIPS)
+endif
+
+ifeq ($(strip ${CFG_RAMAPP}),1)
+ALLOBJS += lib_hssubr.o lib_setjmp.o mips_arena.o exchandler.o
+ALLOBJS += dev_flash_all.o dev_flashop_engine.o
+ALLOBJS += ui_memtest.o
+endif
+
+makereg : ${TOP}/hosttools/makereg.c
+ gcc -o makereg ${TOP}/hosttools/makereg.c
+
+%.inc : %.regdef makereg
+ ./makereg $< $@
+
+ui_soccmds.o : ${CPU_SRC}/ui_soccmds.c ${CPU}_socregs.inc
+
+vapi.o : ${TOP}/verif/vapi.S sb1250_socregs.inc
+
+
+
diff --git a/cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds b/cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds
new file mode 100644
index 0000000..4b8ce87
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_ram_cached.lds
@@ -0,0 +1,40 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x9fc00000; /* was 0x9fc00000 */
+ .text :
+/* AT ( 0xBFC00000 ) */ /* was 0xbfc00000 */
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds b/cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds
new file mode 100644
index 0000000..4295fe4
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_ram_uncached.lds
@@ -0,0 +1,40 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0xbfc00000; /* was 0x9fc00000 */
+ .text :
+/* AT ( 0xBFC00000 ) */ /* was 0xbfc00000 */
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_ramapp.lds b/cfe/cfe/arch/mips/common/src/cfe_ramapp.lds
new file mode 100755
index 0000000..5a7a377
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_ramapp.lds
@@ -0,0 +1,41 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x80601000;
+ .text :
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ *(.rodata.str1.4)
+ *(.gnu.linkonce.r.*)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_cached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_cached.lds
new file mode 100755
index 0000000..2ca1353
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_cached.lds
@@ -0,0 +1,40 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x80000000;
+ .text :
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data :
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ .reginfo : {}
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds
new file mode 100644
index 0000000..ee94831
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached.lds
@@ -0,0 +1,43 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x9FC00000;
+ .text :
+ AT ( 0xBFC00000 )
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+ .data 0x80001000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _gp = ALIGN(16) + 0x8000;
+ _fdata = .;
+ *(.rdata)
+ *(.data)
+ CONSTRUCTORS
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds
new file mode 100644
index 0000000..78421a4
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_cached_biendian.lds
@@ -0,0 +1,49 @@
+/*
+ * This linker script is exactly the same as cfe_rom_reloc_cached.lds
+ * except our start address is at BFD00000, 1MB into the
+ * ROM. We locate the little-endian version of CFE at this address
+ * in bi-endian ROM support.
+ */
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0x9FD00000;
+ .text :
+ AT ( 0xBFD00000 )
+ {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+ .data 0x80001000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _gp = ALIGN(16) + 0x8000;
+ _fdata = .;
+ *(.rdata)
+ *(.data)
+ CONSTRUCTORS
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds
new file mode 100644
index 0000000..0c62889
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_reloc_uncached.lds
@@ -0,0 +1,41 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0xBFC00000;
+ .text : {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ PROVIDE (__runtime_reloc_start = .);
+ *(.rel.sdata)
+ PROVIDE (__runtime_reloc_stop = .);
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+ .data 0xA0001000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _gp = ALIGN(16) + 0x8000;
+ _fdata = .;
+ *(.rdata)
+ *(.data)
+ CONSTRUCTORS
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds b/cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds
new file mode 100644
index 0000000..a0362ba
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/cfe_rom_uncached.lds
@@ -0,0 +1,39 @@
+OUTPUT_ARCH(mips)
+ENTRY(vec_reset)
+SECTIONS
+{
+ . = 0xBFC00000;
+ .text : {
+ _ftext = . ;
+ *(.init)
+ eprol = .;
+ *(.text)
+ *(.fini)
+ *(.rodata)
+ _etext = .;
+ }
+
+ .data 0xA1F00000 :
+ AT ( ((ADDR(.text)|0xB0000000) + SIZEOF ( .text ) + 15) & 0xFFFFFFF0)
+ {
+ _fdata = ALIGN(16) ;
+ *(.data)
+ CONSTRUCTORS
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ *(.sdata)
+ }
+ . = ALIGN(16);
+ _edata = .;
+ _fbss = .;
+ .sbss : {
+ *(.sbss)
+ *(.scommon)
+ }
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(16);
+ _end = .;
+}
diff --git a/cfe/cfe/arch/mips/common/src/dev_flash_all.S b/cfe/cfe/arch/mips/common/src/dev_flash_all.S
new file mode 100644
index 0000000..6dbb581
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/dev_flash_all.S
@@ -0,0 +1,220 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Flash "self-write" module File: flash_write_all.S
+ *
+ * This module takes care of the case of writing to the flash
+ * memory that CFE is currently reading its code from. It is
+ * assumed that you'll be doing a complete flash update,
+ * so this code erases the affected sectors, reprograms them,
+ * and jumps to the boot sector.
+ *
+ * Note: this code is written to be position-independent, even
+ * for non-PIC versions of CFE! It will be copied (with memcpy)
+ * into the heap for execution.
+ *
+ * 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 "dev_flash.h"
+#include "mipsmacros.h"
+
+#define WRITEFLASH(base,offset,value) \
+ li t0,value ; \
+ sb t0,offset(base)
+
+
+/* *********************************************************************
+ * flash_write_all(data,flashbase,size,secsize)
+ *
+ * Write bytes to flash, erasing affected sectors first.
+ *
+ * Input parameters:
+ * a0 - data - pointer to data to write
+ * a1 - flashbase - base (phys addr) of flash area
+ * a2 - size - number of bytes to write
+ * a3 - secsize - flash sector size
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+#define data a0
+#define flashbase a1
+#define datasize a2
+#define secsize a3
+
+#define secidx t4
+#define secptr t5
+
+LEAF(flash_write_all)
+
+ /*
+ * Mask all interrupts. An exception with BEV set would be very bad.
+ */
+
+ mfc0 v0,C0_SR # Get current interrupt flag
+ li v1,M_SR_IE # master interrupt control
+ not v1 # disable interrupts
+ and v0,v1 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+ /*
+ * Get KSEG1 addr of flash
+ */
+
+ or flashbase,K1BASE
+
+
+ /*
+ * Do an "unlock write" sequence (cycles 1-2)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /*
+ * send the erase command (cycle 3)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /*
+ * Do an "unlock write" sequence (cycles 4-5)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /*
+ * Send the "erase all" qualifier (cycle 6)
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_ALL_6)
+
+ /*
+ * Wait for the erase to complete
+ */
+
+1: lb t0,0(secptr) # get byte
+ and t0,0xFF # test hi byte
+ bne t0,0xFF,1b # go till bit is set
+
+
+ /*
+ * Okay, now loop through the bytes and write them to the
+ * flash.
+ */
+
+ move secptr,flashbase
+ move secidx,datasize
+
+proglp:
+
+ /*
+ * Do an "unlock write" sequence
+ */
+
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /*
+ * Send a program command
+ */
+ WRITEFLASH(flashbase,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /*
+ * Write a byte
+ */
+
+ lbu t0,0(data)
+ sb t0,0(secptr) # t0 = byte written to flash
+
+
+ /*
+ * Wait for write to complete
+ */
+
+1: lbu t2,0(secptr) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /*
+ * next byte...
+ */
+
+ add a0,1 # next source byte
+ add secptr,1 # next dest byte
+ sub datasize,1 # one less count
+ bgt datasize,0,proglp
+
+ /*
+ * All done, reboot system
+ */
+
+ li v0,0xBFC00000
+ j v0
+
+flash_write_all_end:
+ nop
+
+END(flash_write_all)
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+ .sdata
+
+ .globl flash_write_all_ptr
+ .globl flash_write_all_len
+
+flash_write_all_ptr:
+ _VECT_ flash_write_all
+flash_write_all_len:
+ .word flash_write_all_end-flash_write_all
+
+
diff --git a/cfe/cfe/arch/mips/common/src/dev_flashop_engine.S b/cfe/cfe/arch/mips/common/src/dev_flashop_engine.S
new file mode 100644
index 0000000..29ade6a
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/dev_flashop_engine.S
@@ -0,0 +1,695 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Flash "self-write" module File: dev_flashop_engine.S
+ *
+ * This module takes care of the case of writing to the flash
+ * memory that CFE is currently reading its code from.
+ *
+ * Note: this code is written to be position-independent, even
+ * for non-PIC versions of CFE! It will be copied (with memcpy)
+ * into the heap for execution.
+ *
+ * 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 "mipsmacros.h"
+
+#include "bsp_config.h"
+#include "dev_newflash.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define FLASHCMD_8(base,offset,value) \
+ li t0,value ; \
+ sb t0,offset(base)
+
+#define FLASHCMD_16(base,offset,value) \
+ li t0,value ; \
+ sh t0,((offset)<<1)(base)
+
+#define FLASHCMD_16B(base,offset,value) \
+ li t0,value ; \
+ sb t0,((offset)<<1)(base)
+
+
+/* *********************************************************************
+ * flashop_engine
+ *
+ * This routine is written in a PIC method to allow us to do
+ * flash operations without any help from CFE. We need to do
+ * this when we're not relocated and want to muck with the
+ * flash we're running from.
+ *
+ * This routine follows some simple instructions in a table,
+ * so you can batch up the operations in one place.
+ *
+ * Input parameters:
+ * a0 - pointer to instruction list
+ *
+ * Return value:
+ * v0 - 0 if all instructions succeeded
+ * else less than zero, # of failing instructions
+ ********************************************************************* */
+
+ .text
+
+#define reg_op t3
+#define reg_base t4
+#define reg_dest t5
+#define reg_src t6
+#define reg_cnt t7
+
+LEAF(flashop_engine)
+
+instloop: LR reg_op,FEINST_OP(a0) /* Load instruction */
+ LR reg_base,FEINST_BASE(a0)
+ LR reg_dest,FEINST_DEST(a0)
+ LR reg_src,FEINST_SRC(a0)
+ LR reg_cnt,FEINST_CNT(a0)
+ li v0,0 /* total of result values */
+ li v1,0 /* result for this function */
+
+#ifdef __long64
+ dli t0,0x9000000000000000 /* uncached - XKPHYS */
+ or reg_base,t0 /* so we can access flash beyond KSEG */
+#else
+ or reg_base,K1BASE /* 32-bit, regular KSEG */
+#endif
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ bne reg_op,FEOP_RETURN,99f /* Return to main prog */
+
+ j ra
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_REBOOT,99f /* restart system */
+
+ li t0,0xBFC00000 /* jump to boot vector */
+ j t0
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_READ8,99f /* Read, 8-bit mode */
+
+ ADD reg_src,reg_src,reg_base
+
+1: lbu t0,0(reg_src) /* Copy user data */
+ sb t0,0(reg_dest)
+ ADD reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_READ16,99f /* Read, 16-bit mode */
+
+ ADD reg_src,reg_src,reg_base
+
+ li t0,1 /* test bottom bit */
+ and t0,t0,reg_src /* t0 == 1 if odd */
+ beq t0,zero,1f /* no odd byte to worry about */
+
+ SUB reg_src,reg_src,t0 /* make even value */
+ lh t0,0(reg_src) /* interesting byte is odd */
+#ifdef __MIPSEB
+ sb t0,0(reg_dest) /* interesting byte in low 8 bits */
+#else
+ srl t0,t0,8 /* little endian */
+ sb t0,0(reg_dest) /* interesting byte is high 8 bits */
+#endif
+
+ ADD reg_src,2 /* advance one word (we made addr even above) */
+ add reg_dest,1 /* dest always written by bytes */
+ sub reg_cnt,1
+
+1: beq reg_cnt,zero,nextinst
+
+ lh t0,0(reg_src) /* Copy user data */
+
+#ifdef __MIPSEB
+ sb t0,1(reg_dest) /* Big endian to memory */
+ srl t0,t0,8 /* t0 = 0x1234 -> 0x12 0x34 */
+ sb t0,0(reg_dest)
+#else
+ sb t0,0(reg_dest) /* little endian */
+ srl t0,t0,8 /* t0 = 0x1234 -> 0x34 0x12 */
+ sb t0,1(reg_dest)
+#endif
+
+ ADD reg_src,2
+ add reg_dest,2
+ sub reg_cnt,2
+ bgt reg_cnt,1,1b
+
+ beq reg_cnt,zero,nextinst /* no straggler */
+
+ lh t0,0(reg_src) /* interesting byte is odd */
+#ifdef __MIPSEB
+ srl t0,t0,8 /* little endian */
+ sb t0,0(reg_dest) /* interesting byte in high 8 bits */
+#else
+ sb t0,0(reg_dest) /* interesting byte is low 8 bits */
+#endif
+
+ b nextinst
+/* CFI - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if (FLASH_DRIVERS & FLASH_DRIVER_CFI)
+99: bne reg_op,FEOP_CFIQUERY8,99f /* CFI Query 8-bit */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
+
+1: lbu t0,0(reg_src) /* Copy CFI data */
+ sb t0,0(reg_dest)
+ ADD reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ FLASHCMD_8(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_CFIQUERY16,99f /* CFI Query 16-bit in word mode */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
+
+1: lh t0,0(reg_src) /* Copy CFI data */
+ sh t0,0(reg_dest)
+ ADD reg_src,2
+ add reg_dest,2
+ sub reg_cnt,2
+ bgt reg_cnt,zero,1b
+
+ FLASHCMD_16(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_CFIQUERY16B,99f /* CFI Query 16-bit in byte mode */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_MODE)
+
+1: lb t0,0(reg_src) /* Copy CFI data */
+ sb t0,0(reg_dest)
+ ADD reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ FLASHCMD_16B(reg_base,FLASH_CFI_QUERY_ADDR,FLASH_CFI_QUERY_EXIT)
+
+ b nextinst
+#endif
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_MEMCPY,99f /* Generic memcpy */
+
+1: lbu t0,0(reg_src)
+ sb t0,0(reg_dest)
+ add reg_src,1
+ add reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,1b
+
+ b nextinst
+
+
+/* AMD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if (FLASH_DRIVERS & FLASH_DRIVER_AMD)
+99: bne reg_op,FEOP_AMD_ERASE8,99f /* AMD erase (8-bit) */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* send the erase command (cycle 3) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /* Do an "unlock write" sequence (cycles 4-5) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send the "erase sector" qualifier (cycle 6) */
+
+ FLASHCMD_8(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
+
+ /* Wait for the erase to complete */
+
+1: lb t0,0(reg_dest) # get byte
+ and t0,0xFF # test hi byte
+ bne t0,0xFF,1b # go till bit is set
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_ERASE16,99f /* AMD erase (16-bit in word mode) */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* send the erase command (cycle 3) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /* Do an "unlock write" sequence (cycles 4-5) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send the "erase sector" qualifier (cycle 6) */
+
+ FLASHCMD_16(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
+
+ /* Wait for the erase to complete */
+
+1: lh t0,0(reg_dest) # get word
+ and t0,0xFF # test byte
+ bne t0,0xFF,1b # go till erased
+
+ b nextinst
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_ERASE16B,99f /* AMD erase (16-bit in byte mode) */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* send the erase command (cycle 3) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_ERASE_3)
+
+ /* Do an "unlock write" sequence (cycles 4-5) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send the "erase sector" qualifier (cycle 6) */
+
+ FLASHCMD_16B(reg_dest,0,AMD_FLASH_ERASE_SEC_6)
+
+ /* Wait for the erase to complete */
+
+1: lh t0,0(reg_dest) # get word
+ and t0,0xFF # test byte
+ bne t0,0xFF,1b # go till erased
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_PGM8,99f /* AMD 8-bit program */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+11:
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send a program command (cycle 3) */
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /* Write a byte (cycle 4) */
+
+ lbu t0,0(reg_src)
+ sb t0,0(reg_dest) # t0 = byte written to flash
+
+ /* Wait for write to complete */
+
+1: lbu t2,0(reg_dest) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /* next byte... */
+
+ add reg_src,1 # next source byte
+ ADD reg_dest,1 # next dest byte
+ sub reg_cnt,1 # one less count
+ bgt reg_cnt,0,11b
+
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_PGM16,99f /* AMD 16-bit program */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+11:
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send a program command (cycle 3) */
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /* Write a byte (cycle 4) */
+
+ lh t0,0(reg_src)
+ sh t0,0(reg_dest) # t0 = byte written to flash
+
+ /* Wait for write to complete */
+
+1: lh t2,0(reg_dest) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /* next byte... */
+
+ add reg_src,2 # next source word
+ ADD reg_dest,2 # next dest word
+ sub reg_cnt,2 # one less count
+ bgt reg_cnt,0,11b
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_PGM16B,99f /* AMD 16-bit pgm in 8-bit mode */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ /* Do an "unlock write" sequence (cycles 1-2) */
+11:
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+
+ /* Send a program command (cycle 3) */
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_PROGRAM)
+
+ /* Write a byte (cycle 4) */
+
+ lb t0,0(reg_src)
+ sb t0,0(reg_dest) # t0 = byte written to flash
+
+ /* Wait for write to complete */
+
+1: lb t2,0(reg_dest) # t2 = byte from flash
+
+ and t1,t2,0x80 # done if bit7 of flash
+ and t0,t0,0x80 # is same as bit7 of data
+ beq t1,t0,2f
+
+ and t1,t2,0x20 # not done if bit5
+ bne t1,0x20,1b # is still set
+2:
+
+ /* next byte... */
+
+ add reg_src,1 # next source word
+ ADD reg_dest,1 # next dest word
+ sub reg_cnt,1 # one less count
+ bgt reg_cnt,0,11b
+
+ b nextinst
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_DEVCODE8,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lbu t0,AMD_FLASH_DEVCODE8(reg_src)
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_DEVCODE16,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lw t0,0(reg_src)
+#ifdef __MIPSEB
+ srl t0,t0,8 /* ((3-AMD_FLASH_DEVCODE16)*8) */
+#else
+ srl t0,t0,16 /* (AMD_FLASH_DEVCODE16*8) */
+#endif
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_DEVCODE16B,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lw t0,0(reg_src)
+#ifdef __MIPSEB
+#else
+ srl t0,t0,16 /* (AMD_FLASH_DEVCODE16B*8)*/
+#endif
+
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_MANID8,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_8(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lbu t0,AMD_FLASH_MANID(reg_src)
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_MANID16,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lw t0,0(reg_src)
+#ifdef __MIPSEB
+ srl t0,t0,((3-AMD_FLASH_MANID)*8)
+#else
+ srl t0,t0,(AMD_FLASH_MANID*8)
+#endif
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_AMD_MANID16B,99f /* AMD 8-bit - Boot Block Location */
+
+ ADD reg_src,reg_src,reg_base
+
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_MAGIC_1)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_2,AMD_FLASH_MAGIC_2)
+ FLASHCMD_16B(reg_base,AMD_FLASH_MAGIC_ADDR_1,AMD_FLASH_AUTOSEL)
+
+ lbu t0,AMD_FLASH_MANID(reg_src)
+
+ sb t0,0(reg_dest)
+ li t0,AMD_FLASH_RESET
+ sb t0,0(reg_src)
+
+ b nextinst
+
+#endif
+
+/* INTEL - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+#if (FLASH_DRIVERS & FLASH_DRIVER_INTEL)
+99: bne reg_op,FEOP_INTEL_ERASE8,99f /* Intel erase 8-bit */
+
+ ADD reg_dest,reg_dest,reg_base
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
+
+1: lbu t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_INTEL_ERASE16,99f /* Intel erase 16-bit */
+
+ ADD reg_dest,reg_dest,reg_base
+
+/* XXX copy of 8-bit erase, is this right? */
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_BLOCK)
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_ERASE_CONFIRM)
+
+1: lbu t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_INTEL_PGM8,99f /* Intel 8-bit program */
+
+ ADD reg_dest,reg_dest,reg_base
+
+11: FLASHCMD_8(reg_dest,0,INTEL_FLASH_PROGRAM)
+
+ lbu t0,0(reg_src)
+ sb t0,0(reg_dest)
+
+1: lbu t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ lbu t0,0(reg_dest) /* contains final result */
+ /* If good, bits 1, 3, 4 will not be set */
+
+ add reg_src,1
+ ADD reg_dest,1
+ sub reg_cnt,1
+ bgt reg_cnt,zero,11b
+
+ FLASHCMD_8(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: bne reg_op,FEOP_INTEL_PGM16,99f /* Intel 16-bit prog */
+
+ ADD reg_dest,reg_dest,reg_base
+
+11: FLASHCMD_16(reg_dest,0,INTEL_FLASH_PROGRAM)
+
+ lh t0,0(reg_src)
+ sh t0,0(reg_dest)
+
+1: lh t0,0(reg_dest) /* loop till bit 7 is set */
+ andi t0,0x80
+ beq t0,zero,1b
+
+ lh t0,0(reg_dest) /* contains final result */
+ /* If good, bits 1, 3, 4 will not be set */
+
+ add reg_src,2
+ ADD reg_dest,2
+ sub reg_cnt,2
+ bgt reg_cnt,zero,11b
+
+ FLASHCMD_16(reg_dest,0,INTEL_FLASH_READ_MODE)
+
+ b nextinst
+#endif
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+99: li v1,-1 /* invalid command */
+
+nextinst: SR v1,FEINST_RESULT(a0) /* store result of instruction */
+ ADD v0,v0,v1 /* add to total */
+ ADD a0,FEINST_SIZE /* advance to next instr. */
+ b instloop
+
+flashop_engine_end:
+ nop
+
+END(flashop_engine)
+
+ .sdata
+
+ .globl flashop_engine_ptr
+ .globl flashop_engine_len
+
+flashop_engine_ptr:
+ _VECT_ flashop_engine
+flashop_engine_len:
+ .word flashop_engine_end-flashop_engine
+
+
+
+/* *********************************************************************
+ * end
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/disasm.c b/cfe/cfe/arch/mips/common/src/disasm.c
new file mode 100644
index 0000000..1b76fee
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/disasm.c
@@ -0,0 +1,2111 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * MIPS disassembler File: disasm.c
+ *
+ * MIPS disassembler (used by ui_examcmds.c)
+ *
+ * Author: Justin Carlson (carlson@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 "lib_types.h"
+#include "lib_string.h"
+#include "disasm.h"
+#include "lib_printf.h"
+
+#define UINT64_T(x) ((uint64_t) (x))
+#define PF_64 "ll"
+#define PF_32 ""
+/* These aren't guaranteed to be portable, either */
+#define SEXT_32(bit, val) \
+ ((((int32_t)(val))<<(31-(bit)))>>(31-(bit)))
+#define SEXT_64(bit, val) \
+ ((((int64_t)(val))<<(63-(bit)))>>(63-(bit)))
+
+#define DATASEG __attribute__ ((section(".text")))
+
+
+#define REGNAME(r) (&_regnames[(r)*5])
+static const char * const _regnames =
+ "zero\0"
+ "AT\0 "
+ "v0\0 "
+ "v1\0 "
+ "a0\0 "
+ "a1\0 "
+ "a2\0 "
+ "a3\0 "
+ "t0\0 "
+ "t1\0 "
+ "t2\0 "
+ "t3\0 "
+ "t4\0 "
+ "t5\0 "
+ "t6\0 "
+ "t7\0 "
+ "s0\0 "
+ "s1\0 "
+ "s2\0 "
+ "s3\0 "
+ "s4\0 "
+ "s5\0 "
+ "s6\0 "
+ "s7\0 "
+ "t8\0 "
+ "t9\0 "
+ "k0\0 "
+ "k1\0 "
+ "gp\0 "
+ "sp\0 "
+ "fp\0 "
+ "ra\0 ";
+
+#define CP0REGNAME(r) (&_cp0names[(r)*12])
+static const char * const _cp0names =
+ "C0_INX\0 "
+ "C0_RAND\0 "
+ "C0_TLBLO0\0 "
+ "C0_TLBLO1\0 "
+
+ "C0_CTEXT\0 "
+ "C0_PGMASK\0 "
+ "C0_WIRED\0 "
+ "C0_reserved\0"
+
+ "C0_BADVADDR\0"
+ "C0_COUNT\0 "
+ "C0_TLBHI\0 "
+ "C0_COMPARE\0 "
+
+ "C0_SR\0 "
+ "C0_CAUSE\0 "
+ "C0_EPC\0 "
+ "C0_PRID\0 "
+
+ "C0_CONFIG\0 "
+ "C0_LLADDR\0 "
+ "C0_WATCHLO\0 "
+ "C0_WATCHHI\0 "
+
+ "C0_XCTEXT\0 "
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+ "C0_reserved\0"
+
+ "C0_TAGLO\0 "
+ "C0_TAGHI\0 "
+ "C0_ERREPC\0 "
+ "C0_reserved\0";
+
+
+
+/*
+ * MIPS instruction set disassembly module.
+ */
+
+typedef enum {
+ DC_RD_RS_RT,
+ DC_RD_RT_RS,
+ DC_RT_RS_SIMM,
+ DC_RT_RS_XIMM,
+ DC_RS_RT_OFS,
+ DC_RS_OFS,
+ DC_RD_RT_SA,
+ DC_RT_UIMM,
+ DC_RD,
+ DC_J,
+ DC_RD_RS,
+ DC_RS_RT,
+ DC_RT_RS,
+ DC_RT_RD_SEL,
+ DC_RT_CR_SEL,
+ DC_RS,
+ DC_RS_SIMM,
+ DC_RT_OFS_BASE,
+ DC_FT_OFS_BASE,
+ DC_FD_IDX_BASE,
+ DC_FS_IDX_BASE,
+ DC_FD_FS_FT,
+ DC_FD_FS_RT,
+ DC_FD_FS,
+ DC_PREF_OFS,
+ DC_PREF_IDX,
+ DC_CC_OFS,
+ DC_FD_FS_CC,
+ DC_RD_RS_CC,
+ DC_FD_FR_FS_FT,
+ DC_FD_FS_FT_RS,
+ DC_CC_FS_FT,
+ DC_BARE,
+ DC_RT_FS,
+ DC_SYSCALL,
+ DC_BREAK,
+ DC_VD_VS_VT_VEC,
+ DC_VD_VS_VT,
+ DC_VS_VT,
+ DC_VS_VT_VEC,
+ DC_VD_VS_VT_RS,
+ DC_VD_VS_VT_IMM,
+ DC_VD_VT,
+ DC_VD,
+ DC_VS,
+ DC_DEREF,
+ DC_OOPS
+} DISASM_CLASS;
+
+
+
+
+/* We're pulling some trickery here. Most of the time, this structure operates
+ exactly as one would expect. The special case, when type == DC_DREF,
+ means name points to a byte that is an index into a dereferencing array. */
+
+/*
+ * To make matters worse, the whole module has been coded to reduce the
+ * number of relocations present, so we don't actually store pointers
+ * in the dereferencing array. Instead, we store fixed-width strings
+ * and use digits to represent indicies into the deref array.
+ *
+ * This is all to make more things fit in the relocatable version,
+ * since every initialized pointer goes into our small data segment.
+ */
+
+typedef struct {
+ char name[15];
+ char type;
+} disasm_t;
+
+typedef struct {
+ const disasm_t *ptr;
+ int shift;
+ uint32_t mask;
+} disasm_deref_t;
+
+/* Forward declaration of deref array, we need this for the disasm_t definitions */
+
+
+extern const disasm_deref_t disasm_deref[];
+
+static const disasm_t disasm_normal[64] DATASEG =
+{{"$1" , DC_DEREF },
+ {"$2" , DC_DEREF },
+ {"j" , DC_J },
+ {"jal" , DC_J },
+ {"beq" , DC_RS_RT_OFS },
+ {"bne" , DC_RS_RT_OFS },
+ {"blez" , DC_RS_OFS },
+ {"bgtz" , DC_RS_OFS },
+ {"addi" , DC_RT_RS_SIMM },
+ {"addiu" , DC_RT_RS_SIMM },
+ {"slti" , DC_RT_RS_SIMM },
+ {"sltiu" , DC_RT_RS_SIMM },
+ {"andi" , DC_RT_RS_XIMM },
+ {"ori" , DC_RT_RS_XIMM },
+ {"xori" , DC_RT_RS_XIMM },
+ {"lui" , DC_RT_UIMM },
+ {"$4" , DC_DEREF },
+ {"$6" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"$15" , DC_DEREF },
+ {"beql" , DC_RS_RT_OFS },
+ {"bnel" , DC_RS_RT_OFS },
+ {"blezl" , DC_RS_OFS },
+ {"bgtzl" , DC_RS_OFS },
+ {"daddi" , DC_RT_RS_SIMM },
+ {"daddiu" , DC_RT_RS_SIMM },
+ {"ldl" , DC_RT_OFS_BASE },
+ {"ldr" , DC_RT_OFS_BASE },
+ {"$3" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"$18" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"lb" , DC_RT_OFS_BASE },
+ {"lh" , DC_RT_OFS_BASE },
+ {"lwl" , DC_RT_OFS_BASE },
+ {"lw" , DC_RT_OFS_BASE },
+ {"lbu" , DC_RT_OFS_BASE },
+ {"lhu" , DC_RT_OFS_BASE },
+ {"lwr" , DC_RT_OFS_BASE },
+ {"lwu" , DC_RT_OFS_BASE },
+ {"sb" , DC_RT_OFS_BASE },
+ {"sh" , DC_RT_OFS_BASE },
+ {"swl" , DC_RT_OFS_BASE },
+ {"sw" , DC_RT_OFS_BASE },
+ {"sdl" , DC_RT_OFS_BASE },
+ {"sdr" , DC_RT_OFS_BASE },
+ {"swr" , DC_RT_OFS_BASE },
+ {"cache" , DC_BARE },
+ {"ll" , DC_RT_OFS_BASE },
+ {"lwc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"pref" , DC_PREF_OFS },
+ {"lld" , DC_RT_OFS_BASE },
+ {"ldc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"ld" , DC_RT_OFS_BASE },
+ {"sc" , DC_RT_OFS_BASE },
+ {"swc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"scd" , DC_RT_OFS_BASE },
+ {"sdc1" , DC_FT_OFS_BASE },
+ {"invalid" , DC_BARE },
+ {"sd" , DC_RT_OFS_BASE }};
+
+static const disasm_t disasm_special[64] DATASEG =
+{{"sll" , DC_RD_RT_SA },
+ {"$16" , DC_DEREF },
+ {"srl" , DC_RD_RT_SA },
+ {"sra" , DC_RD_RT_SA },
+ {"sllv" , DC_RD_RT_RS },
+ {"invalid" , DC_BARE },
+ {"srlv" , DC_RD_RT_RS },
+ {"srav" , DC_RD_RT_RS },
+ {"jr" , DC_RS },
+ {"jalr" , DC_RD_RS },
+ {"movz" , DC_RD_RS_RT },
+ {"movn" , DC_RD_RS_RT },
+ {"syscall" , DC_SYSCALL },
+ {"break" , DC_BREAK },
+ {"invalid" , DC_BARE },
+ {"sync" , DC_BARE },
+ {"mfhi" , DC_RD },
+ {"mthi" , DC_RS },
+ {"mflo" , DC_RD },
+ {"mtlo" , DC_RS },
+ {"dsllv" , DC_RD_RT_RS },
+ {"invalid" , DC_BARE },
+ {"dsrlv" , DC_RD_RT_RS },
+ {"dsrav" , DC_RD_RT_RS },
+ {"mult" , DC_RS_RT },
+ {"multu" , DC_RS_RT },
+ {"div" , DC_RS_RT },
+ {"divu" , DC_RS_RT },
+ {"dmult" , DC_RS_RT },
+ {"dmultu" , DC_RS_RT },
+ {"ddiv" , DC_RS_RT },
+ {"ddivu" , DC_RS_RT },
+ {"add" , DC_RD_RS_RT },
+ {"addu" , DC_RD_RS_RT },
+ {"sub" , DC_RD_RS_RT },
+ {"subu" , DC_RD_RS_RT },
+ {"and" , DC_RD_RS_RT },
+ {"or" , DC_RD_RS_RT },
+ {"xor" , DC_RD_RS_RT },
+ {"nor" , DC_RD_RS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"slt" , DC_RD_RS_RT },
+ {"sltu" , DC_RD_RS_RT },
+ {"dadd" , DC_RD_RS_RT },
+ {"daddu" , DC_RD_RS_RT },
+ {"dsub" , DC_RD_RS_RT },
+ {"dsubu" , DC_RD_RS_RT },
+ {"tge" , DC_RS_RT },
+ {"tgeu" , DC_RS_RT },
+ {"tlt" , DC_RS_RT },
+ {"tltu" , DC_RS_RT },
+ {"teq" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"tne" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"dsll" , DC_RD_RT_SA },
+ {"invalid" , DC_BARE },
+ {"dsrl" , DC_RD_RT_SA },
+ {"dsra" , DC_RD_RT_SA },
+ {"dsll32" , DC_RD_RT_SA },
+ {"invalid" , DC_BARE },
+ {"dsrl32" , DC_RD_RT_SA },
+ {"dsra32" , DC_RD_RT_SA }};
+
+static const disasm_t disasm_movci[2] DATASEG =
+{{"movf" , DC_RD_RS_CC },
+ {"movt" , DC_RD_RS_CC }};
+
+static const disasm_t disasm_regimm[32] DATASEG =
+{{"bltz" , DC_RS_OFS },
+ {"bgez" , DC_RS_OFS },
+ {"bltzl" , DC_RS_OFS },
+ {"bgezl" , DC_RS_OFS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tgei" , DC_RS_SIMM },
+ {"tgeiu" , DC_RS_SIMM },
+ {"tlti" , DC_RS_SIMM },
+ {"tltiu" , DC_RS_SIMM },
+ {"teqi" , DC_RS_SIMM },
+ {"invalid" , DC_BARE },
+ {"tnei" , DC_RS_SIMM },
+ {"invalid" , DC_BARE },
+ {"bltzal" , DC_RS_OFS },
+ {"bgezal" , DC_RS_OFS },
+ {"bltzall" , DC_RS_OFS },
+ {"bgezall" , DC_RS_OFS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_spec2[64] DATASEG =
+{{"madd" , DC_RS_RT },
+ {"maddu" , DC_RS_RT },
+ {"mul" , DC_RD_RS_RT },
+ {"invalid" , DC_BARE },
+ {"msub" , DC_RS_RT },
+ {"msubu" , DC_RS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"clz" , DC_RT_RS },
+ {"clo" , DC_RT_RS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"dclz" , DC_RT_RS },
+ {"dclo" , DC_RT_RS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"sdbbp" , DC_BARE }};
+
+static const disasm_t disasm_cop0[32] DATASEG =
+{{"mfc0@1" , DC_RT_CR_SEL },
+ {"dmfc0@1" , DC_RT_CR_SEL },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"mtc0@1" , DC_RT_CR_SEL },
+ {"dmtc0@1" , DC_RT_CR_SEL },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF },
+ {"$5" , DC_DEREF }};
+
+static const disasm_t disasm_cop0_c0[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"tlbr" , DC_BARE },
+ {"tlbwi" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tlbwr" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"tlbp" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"eret" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"deret" , DC_BARE },
+ {"wait" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1[32] DATASEG =
+{{"mfc1" , DC_RT_FS },
+ {"dmfc1" , DC_RT_FS },
+ {"cfc1" , DC_RT_FS },
+ {"invalid" , DC_BARE },
+ {"mtc1" , DC_RT_FS },
+ {"dmtc1" , DC_RT_FS },
+ {"ctc1" , DC_RT_FS },
+ {"invalid" , DC_BARE },
+ {"$17" , DC_DEREF },
+ {"$36" , DC_DEREF },
+ {"$37" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$7" , DC_DEREF },
+ {"$9" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$11" , DC_DEREF },
+ {"$12" , DC_DEREF },
+ {"$13" , DC_DEREF },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_bc1[4] DATASEG =
+{{"bc1f" , DC_CC_OFS },
+ {"bc1t" , DC_CC_OFS },
+ {"bc1fl" , DC_CC_OFS },
+ {"bc1tl" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_bc1any2[2] DATASEG =
+{{"bc1any2f" , DC_CC_OFS },
+ {"bc1any2t" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_bc1any4[2] DATASEG =
+{{"bc1any4f" , DC_CC_OFS },
+ {"bc1any4t" , DC_CC_OFS },
+};
+
+static const disasm_t disasm_cop1_s[64] DATASEG =
+{{"add.s" , DC_FD_FS_FT },
+ {"sub.s" , DC_FD_FS_FT },
+ {"mul.s" , DC_FD_FS_FT },
+ {"div.s" , DC_FD_FS_FT },
+ {"sqrt.s" , DC_FD_FS },
+ {"abs.s" , DC_FD_FS },
+ {"mov.s" , DC_FD_FS },
+ {"neg.s" , DC_FD_FS },
+ {"round.l.s" , DC_FD_FS },
+ {"trunc.l.s" , DC_FD_FS },
+ {"ceil.l.s" , DC_FD_FS },
+ {"floor.l.s" , DC_FD_FS },
+ {"round.w.s" , DC_FD_FS },
+ {"trunc.w.s" , DC_FD_FS },
+ {"ceil.w.s" , DC_FD_FS },
+ {"floor.w.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"$8" , DC_DEREF },
+ {"movz.s" , DC_FD_FS_RT },
+ {"movn.s" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"recip.s" , DC_FD_FS },
+ {"rsqrt.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"recip2.s" , DC_FD_FS_FT },
+ {"recip1.s" , DC_FD_FS },
+ {"rsqrt1.s" , DC_FD_FS },
+ {"rsqrt2.s" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"cvt.d.s" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.w.s" , DC_FD_FS },
+ {"cvt.l.s" , DC_FD_FS },
+ {"cvt.ps.s" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$38" , DC_DEREF },
+ {"$39" , DC_DEREF },
+ {"$40" , DC_DEREF },
+ {"$41" , DC_DEREF },
+ {"$42" , DC_DEREF },
+ {"$43" , DC_DEREF },
+ {"$44" , DC_DEREF },
+ {"$45" , DC_DEREF },
+ {"$46" , DC_DEREF },
+ {"$47" , DC_DEREF },
+ {"$48" , DC_DEREF },
+ {"$49" , DC_DEREF },
+ {"$50" , DC_DEREF },
+ {"$51" , DC_DEREF },
+ {"$52" , DC_DEREF },
+ {"$53" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_s_mvcf[2] DATASEG =
+{{"movf.s" , DC_FD_FS_CC },
+ {"movt.s" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1_d[64] DATASEG =
+{{"add.d" , DC_FD_FS_FT },
+ {"sub.d" , DC_FD_FS_FT },
+ {"mul.d" , DC_FD_FS_FT },
+ {"div.d" , DC_FD_FS_FT },
+ {"sqrt.d" , DC_FD_FS },
+ {"abs.d" , DC_FD_FS },
+ {"mov.d" , DC_FD_FS },
+ {"neg.d" , DC_FD_FS },
+ {"round.l.d" , DC_FD_FS },
+ {"trunc.l.d" , DC_FD_FS },
+ {"ceil.l.d" , DC_FD_FS },
+ {"floor.l.d" , DC_FD_FS },
+ {"round.w.d" , DC_FD_FS },
+ {"trunc.w.d" , DC_FD_FS },
+ {"ceil.w.d" , DC_FD_FS },
+ {"floor.w.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"$10" , DC_DEREF },
+ {"movz.d" , DC_FD_FS_RT },
+ {"movn.d" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"recip.d" , DC_FD_FS },
+ {"rsqrt.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"recip2.d" , DC_FD_FS_FT },
+ {"recip1.d" , DC_FD_FS },
+ {"rsqrt1.d" , DC_FD_FS },
+ {"rsqrt2.d" , DC_FD_FS_FT },
+ {"cvt.s.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.w.d" , DC_FD_FS },
+ {"cvt.l.d" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$54" , DC_DEREF },
+ {"$55" , DC_DEREF },
+ {"$56" , DC_DEREF },
+ {"$57" , DC_DEREF },
+ {"$58" , DC_DEREF },
+ {"$59" , DC_DEREF },
+ {"$60" , DC_DEREF },
+ {"$61" , DC_DEREF },
+ {"$62" , DC_DEREF },
+ {"$63" , DC_DEREF },
+ {"$64" , DC_DEREF },
+ {"$65" , DC_DEREF },
+ {"$66" , DC_DEREF },
+ {"$67" , DC_DEREF },
+ {"$68" , DC_DEREF },
+ {"$69" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_d_mvcf[2] DATASEG =
+{{"movf.d" , DC_FD_FS_CC },
+ {"movt.d" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1_w[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.w" , DC_FD_FS },
+ {"cvt.d.w" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.ps.pw" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_l[64] DATASEG =
+{{"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.l" , DC_FD_FS },
+ {"cvt.d.l" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_cop1_ps[64] DATASEG =
+{{"add.ps" , DC_FD_FS_FT },
+ {"sub.ps" , DC_FD_FS_FT },
+ {"mul.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"abs.ps" , DC_FD_FS },
+ {"mov.ps" , DC_FD_FS },
+ {"neg.ps" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"$14" , DC_DEREF },
+ {"movz.ps" , DC_FD_FS_RT },
+ {"movn.ps" , DC_FD_FS_RT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"addr.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"mulr.ps" , DC_FD_FS_FT },
+ {"invalid" , DC_BARE },
+ {"recip2.ps" , DC_FD_FS_FT },
+ {"recip1.ps" , DC_FD_FS },
+ {"rsqrt1.ps" , DC_FD_FS },
+ {"rsqrt2.ps" , DC_FD_FS_FT },
+ {"cvt.s.pu" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.pw.ps" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"cvt.s.pl" , DC_FD_FS },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"pll.ps" , DC_FD_FS_FT },
+ {"plu.ps" , DC_FD_FS_FT },
+ {"pul.ps" , DC_FD_FS_FT },
+ {"puu.ps" , DC_FD_FS_FT },
+ {"$70" , DC_DEREF },
+ {"$71" , DC_DEREF },
+ {"$72" , DC_DEREF },
+ {"$73" , DC_DEREF },
+ {"$74" , DC_DEREF },
+ {"$75" , DC_DEREF },
+ {"$76" , DC_DEREF },
+ {"$77" , DC_DEREF },
+ {"$78" , DC_DEREF },
+ {"$79" , DC_DEREF },
+ {"$80" , DC_DEREF },
+ {"$81" , DC_DEREF },
+ {"$82" , DC_DEREF },
+ {"$83" , DC_DEREF },
+ {"$84" , DC_DEREF },
+ {"$85" , DC_DEREF }};
+
+static const disasm_t disasm_cop1_c_f_s[2] DATASEG =
+{{"c.f.s" , DC_CC_FS_FT },
+ {"cabs.f.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_s[2] DATASEG =
+{{"c.un.s" , DC_CC_FS_FT },
+ {"cabs.un.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_s[2] DATASEG =
+{{"c.eq.s" , DC_CC_FS_FT },
+ {"cabs.eq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_s[2] DATASEG =
+{{"c.ueq.s" , DC_CC_FS_FT },
+ {"cabs.ueq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_s[2] DATASEG =
+{{"c.olt.s" , DC_CC_FS_FT },
+ {"cabs.olt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_s[2] DATASEG =
+{{"c.ult.s" , DC_CC_FS_FT },
+ {"cabs.ult.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_s[2] DATASEG =
+{{"c.ole.s" , DC_CC_FS_FT },
+ {"cabs.ole.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_s[2] DATASEG =
+{{"c.ule.s" , DC_CC_FS_FT },
+ {"cabs.ule.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_s[2] DATASEG =
+{{"c.sf.s" , DC_CC_FS_FT },
+ {"cabs.sf.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_s[2] DATASEG =
+{{"c.ngle.s" , DC_CC_FS_FT },
+ {"cabs.ngle.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_s[2] DATASEG =
+{{"c.seq.s" , DC_CC_FS_FT },
+ {"cabs.seq.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_s[2] DATASEG =
+{{"c.ngl.s" , DC_CC_FS_FT },
+ {"cabs.ngl.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_s[2] DATASEG =
+{{"c.lt.s" , DC_CC_FS_FT },
+ {"cabs.lt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_s[2] DATASEG =
+{{"c.nge.s" , DC_CC_FS_FT },
+ {"cabs.nge.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_s[2] DATASEG =
+{{"c.le.s" , DC_CC_FS_FT },
+ {"cabs.le.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_s[2] DATASEG =
+{{"c.ngt.s" , DC_CC_FS_FT },
+ {"cabs.ngt.s" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_f_d[2] DATASEG =
+{{"c.f.d" , DC_CC_FS_FT },
+ {"cabs.f.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_d[2] DATASEG =
+{{"c.un.d" , DC_CC_FS_FT },
+ {"cabs.un.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_d[2] DATASEG =
+{{"c.eq.d" , DC_CC_FS_FT },
+ {"cabs.eq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_d[2] DATASEG =
+{{"c.ueq.d" , DC_CC_FS_FT },
+ {"cabs.ueq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_d[2] DATASEG =
+{{"c.olt.d" , DC_CC_FS_FT },
+ {"cabs.olt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_d[2] DATASEG =
+{{"c.ult.d" , DC_CC_FS_FT },
+ {"cabs.ult.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_d[2] DATASEG =
+{{"c.ole.d" , DC_CC_FS_FT },
+ {"cabs.ole.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_d[2] DATASEG =
+{{"c.ule.d" , DC_CC_FS_FT },
+ {"cabs.ule.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_d[2] DATASEG =
+{{"c.sf.d" , DC_CC_FS_FT },
+ {"cabs.sf.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_d[2] DATASEG =
+{{"c.ngle.d" , DC_CC_FS_FT },
+ {"cabs.ngle.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_d[2] DATASEG =
+{{"c.seq.d" , DC_CC_FS_FT },
+ {"cabs.seq.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_d[2] DATASEG =
+{{"c.ngl.d" , DC_CC_FS_FT },
+ {"cabs.ngl.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_d[2] DATASEG =
+{{"c.lt.d" , DC_CC_FS_FT },
+ {"cabs.lt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_d[2] DATASEG =
+{{"c.nge.d" , DC_CC_FS_FT },
+ {"cabs.nge.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_d[2] DATASEG =
+{{"c.le.d" , DC_CC_FS_FT },
+ {"cabs.le.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_d[2] DATASEG =
+{{"c.ngt.d" , DC_CC_FS_FT },
+ {"cabs.ngt.d" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_f_ps[2] DATASEG =
+{{"c.f.ps" , DC_CC_FS_FT },
+ {"cabs.f.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_un_ps[2] DATASEG =
+{{"c.un.ps" , DC_CC_FS_FT },
+ {"cabs.un.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_eq_ps[2] DATASEG =
+{{"c.eq.ps" , DC_CC_FS_FT },
+ {"cabs.eq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ueq_ps[2] DATASEG =
+{{"c.ueq.ps" , DC_CC_FS_FT },
+ {"cabs.ueq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_olt_ps[2] DATASEG =
+{{"c.olt.ps" , DC_CC_FS_FT },
+ {"cabs.olt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ult_ps[2] DATASEG =
+{{"c.ult.ps" , DC_CC_FS_FT },
+ {"cabs.ult.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ole_ps[2] DATASEG =
+{{"c.ole.ps" , DC_CC_FS_FT },
+ {"cabs.ole.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ule_ps[2] DATASEG =
+{{"c.ule.ps" , DC_CC_FS_FT },
+ {"cabs.ule.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_sf_ps[2] DATASEG =
+{{"c.sf.ps" , DC_CC_FS_FT },
+ {"cabs.sf.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngle_ps[2] DATASEG =
+{{"c.ngle.ps" , DC_CC_FS_FT },
+ {"cabs.ngle.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_seq_ps[2] DATASEG =
+{{"c.seq.ps" , DC_CC_FS_FT },
+ {"cabs.seq.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngl_ps[2] DATASEG =
+{{"c.ngl.ps" , DC_CC_FS_FT },
+ {"cabs.ngl.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_lt_ps[2] DATASEG =
+{{"c.lt.ps" , DC_CC_FS_FT },
+ {"cabs.lt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_nge_ps[2] DATASEG =
+{{"c.nge.ps" , DC_CC_FS_FT },
+ {"cabs.nge.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_le_ps[2] DATASEG =
+{{"c.le.ps" , DC_CC_FS_FT },
+ {"cabs.le.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_c_ngt_ps[2] DATASEG =
+{{"c.ngt.ps" , DC_CC_FS_FT },
+ {"cabs.ngt.ps" , DC_CC_FS_FT }};
+
+static const disasm_t disasm_cop1_ps_mvcf[2] DATASEG =
+{{"movf.ps" , DC_FD_FS_CC },
+ {"movt.ps" , DC_FD_FS_CC }};
+
+static const disasm_t disasm_cop1x[64] DATASEG =
+{{"lwxc1" , DC_FD_IDX_BASE },
+ {"ldxc1" , DC_FD_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"luxc1" , DC_FD_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"swxc1" , DC_FS_IDX_BASE },
+ {"sdxc1" , DC_FS_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"suxc1" , DC_FS_IDX_BASE },
+ {"invalid" , DC_BARE },
+ {"prefx" , DC_PREF_IDX },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"alnv.ps" , DC_FD_FS_FT_RS },
+ {"invalid" , DC_BARE },
+ {"madd.s" , DC_FD_FR_FS_FT },
+ {"madd.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"madd.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"msub.s" , DC_FD_FR_FS_FT },
+ {"msub.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"msub.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"nmadd.s" , DC_FD_FR_FS_FT },
+ {"nmadd.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"nmadd.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"nmsub.s" , DC_FD_FR_FS_FT },
+ {"nmsub.d" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"invalid" , DC_BARE },
+ {"nmsub.ps" , DC_FD_FR_FS_FT },
+ {"invalid" , DC_BARE }};
+
+static const disasm_t disasm_mdmx[8] DATASEG =
+{{ "$20" , DC_DEREF },
+ { "$19" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$33" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$19" , DC_DEREF },
+ { "$20" , DC_DEREF },
+ { "$33" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_qh[64] DATASEG =
+{{ "msgn.qh" , DC_VD_VS_VT_VEC},
+ { "c.eq.qh" , DC_VS_VT_VEC },
+ { "pickf.qh" , DC_VD_VS_VT_VEC},
+ { "pickt.qh" , DC_VD_VS_VT_VEC},
+ { "c.lt.qh" , DC_VS_VT_VEC },
+ { "c.le.qh" , DC_VS_VT_VEC },
+ { "min.qh" , DC_VD_VS_VT_VEC},
+ { "max.qh" , DC_VD_VS_VT_VEC},
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "sub.qh" , DC_VD_VS_VT_VEC},
+ { "add.qh" , DC_VD_VS_VT_VEC},
+ { "and.qh" , DC_VD_VS_VT_VEC},
+ { "xor.qh" , DC_VD_VS_VT_VEC},
+ { "or.qh" , DC_VD_VS_VT_VEC},
+ { "nor.qh" , DC_VD_VS_VT_VEC},
+
+ { "sll.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "srl.qh" , DC_VD_VS_VT_VEC},
+ { "sra.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$34" , DC_DEREF },
+
+ { "rzu.qh" , DC_VD_VT },
+ { "rnau.qh" , DC_VD_VT },
+ { "rneu.qh" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+ { "rzs.qh" , DC_VD_VT },
+ { "rnas.qh" , DC_VD_VT },
+ { "rnes.qh" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "mul.qh" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "$21" , DC_DEREF },
+ { "$22" , DC_DEREF },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$23" , DC_DEREF },
+ { "$24" , DC_DEREF },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$25" , DC_DEREF },
+ { "$26" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_ob[64] DATASEG =
+{{ "invalid" , DC_BARE },
+ { "c.eq.ob" , DC_VS_VT_VEC },
+ { "pickf.ob" , DC_VD_VS_VT_VEC},
+ { "pickt.ob" , DC_VD_VS_VT_VEC},
+ { "c.lt.ob" , DC_VS_VT_VEC },
+ { "c.le.ob" , DC_VS_VT_VEC },
+ { "min.ob" , DC_VD_VS_VT_VEC},
+ { "max.ob" , DC_VD_VS_VT_VEC},
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "sub.ob" , DC_VD_VS_VT_VEC},
+ { "add.ob" , DC_VD_VS_VT_VEC},
+ { "and.ob" , DC_VD_VS_VT_VEC},
+ { "xor.ob" , DC_VD_VS_VT_VEC},
+ { "or.ob" , DC_VD_VS_VT_VEC},
+ { "nor.ob" , DC_VD_VS_VT_VEC},
+
+ { "sll.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "srl.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$35" , DC_DEREF },
+
+ { "rzu.ob" , DC_VD_VT },
+ { "rnau.ob" , DC_VD_VT },
+ { "rneu.ob" , DC_VD_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "mul.ob" , DC_VD_VS_VT_VEC},
+ { "invalid" , DC_BARE },
+ { "$27" , DC_DEREF },
+ { "$28" , DC_DEREF },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$29" , DC_DEREF },
+ { "$30" , DC_DEREF },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "$31" , DC_DEREF },
+ { "$32" , DC_DEREF },
+};
+
+static const disasm_t disasm_mdmx_alni[64] DATASEG =
+{{ "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "alni.ob" , DC_VD_VS_VT_IMM},
+ { "alnv.ob" , DC_VD_VS_VT_RS },
+ { "alni.qh" , DC_VD_VS_VT_IMM},
+ { "alnv.qh" , DC_VD_VS_VT_RS },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_muls_qh[2] DATASEG =
+{{ "muls.qh" , DC_VS_VT_VEC },
+ { "mulsl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_mul_qh[2] DATASEG =
+{{ "mula.qh" , DC_VS_VT_VEC },
+ { "mull.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_sub_qh[2] DATASEG =
+{{ "suba.qh" , DC_VS_VT_VEC },
+ { "subl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_add_qh[2] DATASEG =
+{{ "adda.qh" , DC_VS_VT_VEC },
+ { "addl.qh" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_wac_qh[4] DATASEG =
+{{ "wacl.qh" , DC_VS_VT },
+ { "invalid" , DC_BARE },
+ { "wach.qh" , DC_VS },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_rac_qh[4] DATASEG =
+{{ "racl.qh" , DC_VD },
+ { "racm.qh" , DC_VD },
+ { "rach.qh" , DC_VD },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_muls_ob[2] DATASEG =
+{{ "muls.ob" , DC_VS_VT_VEC },
+ { "mulsl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_mul_ob[2] DATASEG =
+{{ "mula.ob" , DC_VS_VT_VEC },
+ { "mull.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_sub_ob[2] DATASEG =
+{{ "suba.ob" , DC_VS_VT_VEC },
+ { "subl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_add_ob[2] DATASEG =
+{{ "adda.ob" , DC_VS_VT_VEC },
+ { "addl.ob" , DC_VS_VT_VEC },
+};
+
+static const disasm_t disasm_mdmx_wac_ob[4] DATASEG =
+{{ "wacl.ob" , DC_VS_VT },
+ { "invalid" , DC_BARE },
+ { "wach.ob" , DC_VS },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_rac_ob[4] DATASEG =
+{{ "racl.ob" , DC_VD },
+ { "racm.ob" , DC_VD },
+ { "rach.ob" , DC_VD },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_shfl_ob[16] DATASEG =
+{{ "shfl.upsl.ob" , DC_VD_VS_VT },
+ { "shfl.pach.ob" , DC_VD_VS_VT },
+ { "shfl.mixh.ob" , DC_VD_VS_VT },
+ { "shfl.mixl.ob" , DC_VD_VS_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+static const disasm_t disasm_mdmx_shfl_qh[8] DATASEG =
+{{ "shfl.bfla.qh" , DC_VD_VS_VT },
+ { "shfl.pach.qh" , DC_VD_VS_VT },
+ { "shfl.mixh.qh" , DC_VD_VS_VT },
+ { "shfl.mixl.qh" , DC_VD_VS_VT },
+ { "shfl.repa.qh" , DC_VD_VS_VT },
+ { "shfl.repb.qh" , DC_VD_VS_VT },
+ { "invalid" , DC_BARE },
+ { "invalid" , DC_BARE },
+};
+
+
+
+const disasm_deref_t disasm_deref[] =
+/* Disasm array shft msk */
+{{ disasm_normal , 26, 0x3f }, /* 0 */
+ { disasm_special , 0, 0x3f }, /* 1 */
+ { disasm_regimm , 16, 0x1f }, /* 2 */
+ { disasm_spec2 , 0, 0x3f }, /* 3 */
+ { disasm_cop0 , 21, 0x1f }, /* 4 */
+ { disasm_cop0_c0 , 0, 0x3f }, /* 5 */
+ { disasm_cop1 , 21, 0x1f }, /* 6 */
+ { disasm_cop1_s , 0, 0x3f }, /* 7 */
+ { disasm_cop1_s_mvcf , 16, 0x1 }, /* 8 */
+ { disasm_cop1_d , 0, 0x3f }, /* 9 */
+ { disasm_cop1_d_mvcf , 16, 0x1 }, /* 10 */
+ { disasm_cop1_w , 0, 0x3f }, /* 11 */
+ { disasm_cop1_l , 0, 0x3f }, /* 12 */
+ { disasm_cop1_ps , 0, 0x3f }, /* 13 */
+ { disasm_cop1_ps_mvcf, 16, 0x1 }, /* 14 */
+ { disasm_cop1x , 0, 0x3f }, /* 15 */
+ { disasm_movci , 16, 0x1 }, /* 16 */
+ { disasm_cop1_bc1 , 16, 0x3 }, /* 17 */
+ { disasm_mdmx , 21, 0x7 }, /* 18 */
+ { disasm_mdmx_qh , 0, 0x3f }, /* 19 */
+ { disasm_mdmx_ob , 0, 0x3f }, /* 20 */
+ { disasm_mdmx_muls_qh, 10, 0x1 }, /* 21 */
+ { disasm_mdmx_mul_qh , 10, 0x1 }, /* 22 */
+ { disasm_mdmx_sub_qh , 10, 0x1 }, /* 23 */
+ { disasm_mdmx_add_qh , 10, 0x1 }, /* 24 */
+ { disasm_mdmx_wac_qh , 24, 0x3 }, /* 25 */
+ { disasm_mdmx_rac_qh , 24, 0x3 }, /* 26 */
+ { disasm_mdmx_muls_ob, 10, 0x1 }, /* 27 */
+ { disasm_mdmx_mul_ob , 10, 0x1 }, /* 28 */
+ { disasm_mdmx_sub_ob , 10, 0x1 }, /* 29 */
+ { disasm_mdmx_add_ob , 10, 0x1 }, /* 30 */
+ { disasm_mdmx_wac_ob , 24, 0x3 }, /* 31 */
+ { disasm_mdmx_rac_ob , 24, 0x3 }, /* 32 */
+ { disasm_mdmx_alni , 0, 0x3f }, /* 33 */
+ { disasm_mdmx_shfl_ob, 22, 0xf }, /* 34 */
+ { disasm_mdmx_shfl_qh, 23, 0x7 }, /* 35 */
+ { disasm_cop1_bc1any2, 16, 0x1 }, /* 36 */
+ { disasm_cop1_bc1any4, 16, 0x1 }, /* 37 */
+ { disasm_cop1_c_f_s , 6, 0x1 }, /* 38 */
+ { disasm_cop1_c_un_s , 6, 0x1 }, /* 39 */
+ { disasm_cop1_c_eq_s , 6, 0x1 }, /* 40 */
+ { disasm_cop1_c_ueq_s, 6, 0x1 }, /* 41 */
+ { disasm_cop1_c_olt_s, 6, 0x1 }, /* 42 */
+ { disasm_cop1_c_ult_s, 6, 0x1 }, /* 43 */
+ { disasm_cop1_c_ole_s, 6, 0x1 }, /* 44 */
+ { disasm_cop1_c_ule_s, 6, 0x1 }, /* 45 */
+ { disasm_cop1_c_sf_s , 6, 0x1 }, /* 46 */
+ { disasm_cop1_c_ngle_s, 6, 0x1 }, /* 47 */
+ { disasm_cop1_c_seq_s, 6, 0x1 }, /* 48 */
+ { disasm_cop1_c_ngl_s, 6, 0x1 }, /* 49 */
+ { disasm_cop1_c_lt_s , 6, 0x1 }, /* 50 */
+ { disasm_cop1_c_nge_s, 6, 0x1 }, /* 51 */
+ { disasm_cop1_c_le_s , 6, 0x1 }, /* 52 */
+ { disasm_cop1_c_ngt_s, 6, 0x1 }, /* 53 */
+ { disasm_cop1_c_f_d , 6, 0x1 }, /* 54 */
+ { disasm_cop1_c_un_d , 6, 0x1 }, /* 55 */
+ { disasm_cop1_c_eq_d , 6, 0x1 }, /* 56 */
+ { disasm_cop1_c_ueq_d, 6, 0x1 }, /* 57 */
+ { disasm_cop1_c_olt_d, 6, 0x1 }, /* 58 */
+ { disasm_cop1_c_ult_d, 6, 0x1 }, /* 59 */
+ { disasm_cop1_c_ole_d, 6, 0x1 }, /* 60 */
+ { disasm_cop1_c_ule_d, 6, 0x1 }, /* 61 */
+ { disasm_cop1_c_sf_d , 6, 0x1 }, /* 62 */
+ { disasm_cop1_c_ngle_d, 6, 0x1 }, /* 63 */
+ { disasm_cop1_c_seq_d, 6, 0x1 }, /* 64 */
+ { disasm_cop1_c_ngl_d, 6, 0x1 }, /* 65 */
+ { disasm_cop1_c_lt_d , 6, 0x1 }, /* 66 */
+ { disasm_cop1_c_nge_d, 6, 0x1 }, /* 67 */
+ { disasm_cop1_c_le_d , 6, 0x1 }, /* 68 */
+ { disasm_cop1_c_ngt_d, 6, 0x1 }, /* 69 */
+ { disasm_cop1_c_f_ps , 6, 0x1 }, /* 70 */
+ { disasm_cop1_c_un_ps, 6, 0x1 }, /* 71 */
+ { disasm_cop1_c_eq_ps, 6, 0x1 }, /* 72 */
+ { disasm_cop1_c_ueq_ps, 6, 0x1 }, /* 73 */
+ { disasm_cop1_c_olt_ps, 6, 0x1 }, /* 74 */
+ { disasm_cop1_c_ult_ps, 6, 0x1 }, /* 75 */
+ { disasm_cop1_c_ole_ps, 6, 0x1 }, /* 76 */
+ { disasm_cop1_c_ule_ps, 6, 0x1 }, /* 77 */
+ { disasm_cop1_c_sf_ps, 6, 0x1 }, /* 78 */
+ { disasm_cop1_c_ngle_ps, 6, 0x1 }, /* 79 */
+ { disasm_cop1_c_seq_ps, 6, 0x1 }, /* 80 */
+ { disasm_cop1_c_ngl_ps, 6, 0x1 }, /* 81 */
+ { disasm_cop1_c_lt_ps, 6, 0x1 }, /* 82 */
+ { disasm_cop1_c_nge_ps, 6, 0x1 }, /* 83 */
+ { disasm_cop1_c_le_ps, 6, 0x1 }, /* 84 */
+ { disasm_cop1_c_ngt_ps, 6, 0x1 }, /* 85 */
+};
+
+#define PREFHINT(x) (&pref_hints[(x)*9])
+static char *pref_hints =
+ "load \0"
+ "store \0"
+ "reserved\0"
+ "reserved\0"
+
+ "ld_strm \0"
+ "st_strm \0"
+ "ld_retn \0"
+ "st_retn \0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "wb_inval\0"
+ "reserved\0"
+ "reserved\0"
+
+ "reserved\0"
+ "reserved\0"
+ "reserved\0"
+ "reserved\0";
+
+
+static int snprintf(char *buf,int len,const char *templat,...)
+{
+ va_list marker;
+ int count;
+
+ va_start(marker,templat);
+ count = xvsprintf(buf,templat,marker);
+ va_end(marker);
+
+ return count;
+}
+
+static const disasm_t *get_disasm_field(uint32_t inst)
+{
+ const disasm_deref_t *tmp = &disasm_deref[0];
+ const disasm_t *rec;
+ do {
+ rec = &(tmp->ptr[(inst>>tmp->shift) & tmp->mask]);
+ tmp = &disasm_deref[atoi(&(rec->name[1]))];
+ } while (rec->type == DC_DEREF);
+ return rec;
+}
+
+char *disasm_inst_name(uint32_t inst)
+{
+ return (char *)(get_disasm_field(inst)->name);
+}
+
+void disasm_inst(char *buf, int buf_size, uint32_t inst, uint64_t pc)
+{
+ const disasm_t *tmp;
+ char instname[32];
+ int commentmode = 0;
+ char *x;
+
+ tmp = get_disasm_field(inst);
+
+ strcpy(instname,(char *) tmp->name);
+
+ if ((x = strchr(instname,'@'))) {
+ *x++ = 0;
+ commentmode = atoi(x);
+ }
+
+ switch (tmp->type) {
+ case DC_RD_RS_RT:
+ snprintf(buf, buf_size, "%-8s %s,%s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_RD_RT_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RT_RS_SIMM:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%" PF_32 "d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ SEXT_32(15, inst & 0xffff));
+ break;
+ case DC_RT_RS_XIMM:
+ snprintf(buf, buf_size, "%-8s %s,%s,#0x%" PF_32 "x",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ inst & 0xffff);
+ break;
+ case DC_RS_RT_OFS:
+ snprintf(buf, buf_size, "%-8s %s,%s,0x%" PF_64 "x",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ pc + 4 + (SEXT_64(15, inst & 0xffff)<<2));
+ break;
+ case DC_RS_OFS:
+ snprintf(buf, buf_size, "%-8s %s,0x%" PF_64 "x",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ pc + 4 + (SEXT_64(16, inst & 0xffff)<<2));
+ break;
+ case DC_RD_RT_SA:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%d",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>6) & 0x1f);
+ break;
+ case DC_RT_UIMM:
+ snprintf(buf, buf_size, "%-8s %s,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ inst & 0xffff);
+ break;
+ case DC_RD:
+ snprintf(buf, buf_size, "%-8s %s",
+ instname,
+ REGNAME((inst>>11) & 0x1f));
+ break;
+ case DC_J:
+ snprintf(buf, buf_size, "%-8s 0x%" PF_64 "x",
+ instname,
+ (pc & UINT64_T(0xfffffffff0000000)) | ((inst & 0x3ffffff)<<2));
+ break;
+ case DC_RD_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RS_RT:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_RT_RS:
+ snprintf(buf, buf_size, "%-8s %s,%s",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RT_RD_SEL:
+ snprintf(buf, buf_size, "%-8s %s,%s,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>11) & 0x1f),
+ inst & 0x3);
+ break;
+ case DC_RT_CR_SEL:
+ snprintf(buf, buf_size, "%-8s %s,%d,#%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>11) & 0x1f,
+ inst & 0x3);
+ break;
+ case DC_RS:
+ snprintf(buf, buf_size, "%-8s %s",
+ instname,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_RS_SIMM:
+ snprintf(buf, buf_size, "%-8s %s,#%" PF_32 "d",
+ instname,
+ REGNAME((inst>>21) & 0x1f),
+ SEXT_32(15, inst & 0xffff));
+ break;
+ case DC_RT_OFS_BASE:
+ snprintf(buf, buf_size, "%-8s %s,#%" PF_32 "d(%s)",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ SEXT_32(15, inst),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FT_OFS_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,#%" PF_32 "d(%s)",
+ instname,
+ (inst>>16) & 0x1f,
+ SEXT_32(15, inst),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FD_IDX_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,%s(%s)",
+ instname,
+ (inst>>6) & 0x1f,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FS_IDX_BASE:
+ snprintf(buf, buf_size, "%-8s f%d,%s(%s)",
+ instname,
+ (inst>>11) & 0x1f,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_FD_FS_FT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_FD_FS_RT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ REGNAME((inst>>16) & 0x1f));
+ break;
+ case DC_FD_FS:
+ snprintf(buf, buf_size, "%-8s f%d,f%d",
+ instname,
+ (inst>>6)&0x1f,
+ (inst>>11)&0x1f);
+ break;
+ case DC_PREF_OFS:
+ snprintf(buf, buf_size, "%-8s #%" PF_32 "d(%s) /* %s */",
+ instname,
+ SEXT_32(15, inst & 0xffff),
+ REGNAME((inst>>21) & 0x1f),
+ PREFHINT((inst>>16) & 0x1f));
+ break;
+ case DC_PREF_IDX:
+ snprintf(buf, buf_size, "%-8s %s(%s) /* %s */",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ PREFHINT((inst>>16) & 0x1f));
+ break;
+ case DC_CC_OFS:
+ snprintf(buf, buf_size, "%-8s %d,0x%" PF_64 "x",
+ instname,
+ (inst>>18) & 0x7,
+ pc + 4 + (SEXT_64(15, inst & 0xffff)<<2));
+ break;
+ case DC_RD_RS_CC:
+ snprintf(buf, buf_size, "%-8s %s,%s,%d",
+ instname,
+ REGNAME((inst>>11) & 0x1f),
+ REGNAME((inst>>21) & 0x1f),
+ (inst>>18) & 0x7);
+ break;
+ case DC_FD_FS_CC:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>18) & 0x7);
+ break;
+ case DC_FD_FR_FS_FT:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d,f%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>21) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_FD_FS_FT_RS:
+ snprintf(buf, buf_size, "%-8s f%d,f%d,f%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_CC_FS_FT:
+ snprintf(buf, buf_size, "%-8s %d,f%d,f%d",
+ instname,
+ (inst>>8) & 0x7,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_BARE:
+ snprintf(buf, buf_size, "%-8s", instname);
+ break;
+ case DC_RT_FS:
+ snprintf(buf, buf_size, "%-8s %s,f%d",
+ instname,
+ REGNAME((inst>>16) & 0x1f),
+ (inst>>11) & 0x1f);
+ break;
+ case DC_VS:
+ snprintf(buf, buf_size, "%-8s $v%d",
+ instname,
+ (inst>>11) & 0x1f);
+ break;
+ case DC_VD:
+ snprintf(buf, buf_size, "%-8s $v%d",
+ instname,
+ (inst>>6) & 0x1f);
+ break;
+ case DC_VD_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VD_VS_VT_IMM:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d,#%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>21) & 0x7);
+ break;
+ case DC_VD_VS_VT_RS:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d,%s",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ REGNAME((inst>>21) & 0x1f));
+ break;
+ case DC_VD_VS_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VS_VT:
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case DC_VS_VT_VEC:
+ switch((inst>>24) & 0x3) {
+ case 0:
+ case 1:
+ /* element select */
+ if ((inst>>21) & 1) {
+ /* QH */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d[%d]",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>23) & 0x3);
+ } else {
+ /* OB */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d[%d]",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>22) & 0x7);
+
+ }
+ break;
+ case 2:
+ /* Vector select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case 3:
+ /* immediate select */
+ snprintf(buf, buf_size, "%-8s $v%d,$#%d",
+ instname,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ }
+ break;
+
+ case DC_VD_VS_VT_VEC:
+ switch((inst>>24) & 0x3) {
+ case 0:
+ case 1:
+ /* element select */
+ if ((inst>>21) & 1) {
+ /* QH */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d[%d]",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>23) & 0x3);
+ } else {
+ /* OB */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d[%d]",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f,
+ (inst>>22) & 0x7);
+
+ }
+ break;
+ case 2:
+ /* Vector select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$v%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ case 3:
+ /* immediate select */
+ snprintf(buf, buf_size, "%-8s $v%d,$v%d,$#%d",
+ instname,
+ (inst>>6) & 0x1f,
+ (inst>>11) & 0x1f,
+ (inst>>16) & 0x1f);
+ break;
+ }
+ break;
+
+ case DC_SYSCALL:
+ snprintf(buf, buf_size, "%-8s #%d",
+ instname,
+ (inst>>6) & 0xfffff);
+ break;
+ case DC_BREAK:
+ snprintf(buf, buf_size, "%-8s %d", instname, (inst>>6)&0xfffff);
+ break;
+ case DC_OOPS:
+ snprintf(buf, buf_size, "%s OOPS! FIXME!", instname);
+ break;
+ default:
+ /* Hit something we don't know about...Shouldn't happen. */
+ break;
+ }
+
+ /*
+ * Handle comment field
+ */
+
+
+ switch (commentmode) {
+ case 1: /* CP0 ops */
+ if ((inst & 3) == 0) { /* select 0 */
+ snprintf(buf + strlen(buf),buf_size-strlen(buf)," /* %s */",
+ CP0REGNAME((inst >> 11) & 0x1f));
+ }
+ break;
+ default:
+ break;
+ }
+
+ buf[buf_size-1] = 0;
+
+}
diff --git a/cfe/cfe/arch/mips/common/src/exception.S b/cfe/cfe/arch/mips/common/src/exception.S
new file mode 100644
index 0000000..8036b35
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/exception.S
@@ -0,0 +1,546 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Exception Handler File: exception.S
+ *
+ * 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 "exception.h"
+#include "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD and ERET */
+#include "bsp_config.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#ifdef _MIPSREGS32_
+#define LREG lw
+#define SREG sw
+#define SRL srl
+#define SLL sll
+#else
+#define LREG ld
+#define SREG sd
+#define SRL dsrl
+#define SLL dsll
+#endif
+
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+ .sdata
+
+ .globl _exc_vectab
+_exc_vectab: _LONG_ 0 # XTYPE_RESET
+ _LONG_ 0 # XTYPE_TLBFILL (not used)
+ _LONG_ 0 # XTYPE_XTLBFILL
+ _LONG_ 0 # XTYPE_CACHEERR (not used)
+ _LONG_ 0 # XTYPE_EXCEPTION
+ _LONG_ 0 # XTYPE_INTERRUPT
+ _LONG_ 0 # XTYPE_EJTAG
+
+/* *********************************************************************
+ * Common Data
+ ********************************************************************* */
+
+ .bss
+
+
+/* *********************************************************************
+ * Code
+ ********************************************************************* */
+
+ .text
+
+#define R_EXC_CERR_TEMPLATE _TBLIDX(0)
+#define R_EXC_CERR_TEMPLATE_END _TBLIDX(1)
+
+ .globl _exc_cerr_htable
+_exc_cerr_htable:
+ _LONG_ _exc_cerr_template
+ _LONG_ _exc_cerr_template_end
+
+
+/* *********************************************************************
+ * _exc_cerr_template
+ *
+ * This is a template routine for our cache error handler.
+ * We save a couple of registers in our magic save area, then
+ * dispatch to code elsewhere in CFE.
+ *
+ * This code is copied right to the vector address, so it has
+ * to be kept tiny!
+ *
+ * Input parameters:
+ * nothing - running uncached, all registers trashed
+ *
+ * Return value:
+ * might return, might not
+ ********************************************************************* */
+
+LEAF(_exc_cerr_template)
+
+ /*
+ * Magic! When the cache error handler is running,
+ * we are in a very special state, running uncached
+ * and with translations turned off. We can use offsets
+ * from r0(zero) to store registers we need to use
+ * during the error handler.
+ */
+
+ .set push ; .set noreorder
+
+ SR k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
+ SR k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
+ SR ra,CFE_LOCORE_GLOBAL_RATMP(zero)
+ SR gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
+
+ LR k0,CFE_LOCORE_GLOBAL_CERRH(zero)
+ jal k0
+ nop
+
+ LR k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
+ LR k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
+ LR ra,CFE_LOCORE_GLOBAL_RATMP(zero)
+ LR gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
+ ERET
+
+ .set pop
+
+ /*
+ * Note: make sure this routine does not exceed 128 bytes
+ */
+
+_exc_cerr_template_end:
+
+END(_exc_cerr_template)
+
+/* *********************************************************************
+ * _exc_setup_locore(cerrh)
+ *
+ * Set global data into the low-memory region. We do this in
+ * assembly language so it's easier to deal with the 32-bit/64-bit
+ * issues that arise in the "C" code.
+ *
+ * Input parameters:
+ * a0 - cache error handler
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_setup_locore)
+
+ move t4,ra
+
+ /*
+ * Save GP for easy re-use, using uncached writes.
+ */
+
+ li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_GP)
+ SR gp,0(t0)
+
+ /*
+ * Initialize cache error handler pointer. Make it
+ * uncached, since cache error handlers should not
+ * touch the cache.
+ */
+
+ li t1,(K0SIZE-1)
+ and a0,a0,t1 # keep just physical part
+ li t1,K1BASE
+ or a0,a0,t1 # make into an uncached address
+
+ li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_CERRH)
+ SR a0,0(t0)
+
+ /*
+ * Move the cache error handler into low RAM.
+ */
+
+ li t0,PHYS_TO_K1(MIPS_RAM_VEC_CACHEERR)
+
+ LOADREL(t1,_exc_cerr_htable)
+ LR t2,R_EXC_CERR_TEMPLATE_END(t1)
+ LR t1,R_EXC_CERR_TEMPLATE(t1)
+
+1: lw t3,0(t1) # get a word
+ sw t3,0(t0) # write a word
+ ADD t0,4 # next word...
+ ADD t1,4
+ blt t1,t2,1b # till done
+
+ /*
+ * Now do the whole thing again, but with cached writes.
+ * Writing uncached makes sure the data is actually in memory,
+ * and writing cached makes sure we write the same
+ * stuff again when the cache is evicted.
+ * This way we don't have to bother with cacheops,
+ * a bonus on the BCM1250 with its funky L2.
+ */
+
+ li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
+ SR gp,0(t0)
+
+ li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_CERRH)
+ SR a0,0(t0)
+
+ li t0,PHYS_TO_K0(MIPS_RAM_VEC_CACHEERR)
+
+ LOADREL(t1,_exc_cerr_htable)
+ LR t2,R_EXC_CERR_TEMPLATE_END(t1)
+ LR t1,R_EXC_CERR_TEMPLATE(t1)
+
+1: lw t3,0(t1) # get a word
+ sw t3,0(t0) # write a word
+ ADD t0,4 # next word...
+ ADD t1,4
+ blt t1,t2,1b # till done
+
+
+ /*
+ * done!
+ */
+
+ move ra,t4
+ j ra
+
+END(_exc_setup_locore)
+
+
+
+
+/* *********************************************************************
+ * _exc_setvector(xtype,addr)
+ *
+ * Set an exception vector address
+ *
+ * Input parameters:
+ * xtype - exception vector type
+ * addr - routine address
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_setvector)
+
+ la v0,_exc_vectab
+ srl a0,3 /* convert 8-byte index to array index */
+ sll a0,BPWSIZE /* convert back to index appropriate for word size */
+ add v0,a0
+ SR a1,(v0)
+ j ra
+
+END(_exc_setvector)
+
+
+/* *********************************************************************
+ * _exc_crash_sim()
+ *
+ * Crash the GDB simulator, causing it to exit.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing - does not return
+ ********************************************************************* */
+
+
+LEAF(_exc_crash_sim)
+
+ li $2,1
+ li $3,0xdead
+ li $4,0
+ syscall 0xca
+1: b 1b
+
+END(_exc_crash_sim)
+
+
+/* *********************************************************************
+ * _exc_cache_crash_sim()
+ *
+ * As _exc_crash_sim, but distinguish cache error exception.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing - does not return
+ ********************************************************************* */
+
+
+LEAF(_exc_cache_crash_sim)
+
+ li $2,1
+ li $3,0xbadc
+ li $4,0
+ syscall 0xca
+1: b 1b
+
+END(_exc_cache_crash_sim)
+
+
+/* *********************************************************************
+ * _exc_restart()
+ *
+ * Restart the firmware at the boot address
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_restart)
+
+ li t0,0xBFC00000 # ROM restart vector
+ jr t0
+
+END(_exc_restart)
+
+/* *********************************************************************
+ * _exc_entry(k0)
+ *
+ * Main exception entry point.
+ *
+ * Input parameters:
+ * k0 - exception type
+ *
+ * Return value:
+ * ...
+ ********************************************************************* */
+
+LEAF(_exc_entry)
+
+ .set noreorder
+ .set noat
+
+ subu k1,sp,EXCEPTION_SIZE
+ SRL k1,3
+ SLL k1,3
+
+ SREG zero,XGR_ZERO(k1)
+ SREG AT,XGR_AT(k1)
+
+ SREG v0,XGR_V0(k1)
+ SREG v1,XGR_V1(k1)
+
+ SREG a0,XGR_A0(k1)
+ SREG a1,XGR_A1(k1)
+ SREG a2,XGR_A2(k1)
+ SREG a3,XGR_A3(k1)
+
+ SREG t0,XGR_T0(k1)
+ SREG t1,XGR_T1(k1)
+ SREG t2,XGR_T2(k1)
+ SREG t3,XGR_T3(k1)
+ SREG t4,XGR_T4(k1)
+ SREG t5,XGR_T5(k1)
+ SREG t6,XGR_T6(k1)
+ SREG t7,XGR_T7(k1)
+
+ SREG s0,XGR_S0(k1)
+ SREG s1,XGR_S1(k1)
+ SREG s2,XGR_S2(k1)
+ SREG s3,XGR_S3(k1)
+ SREG s4,XGR_S4(k1)
+ SREG s5,XGR_S5(k1)
+ SREG s6,XGR_S6(k1)
+ SREG s7,XGR_S7(k1)
+
+ SREG t8,XGR_T8(k1)
+ SREG t9,XGR_T9(k1)
+
+ SREG gp,XGR_GP(k1)
+ SREG sp,XGR_SP(k1)
+ SREG fp,XGR_FP(k1)
+ SREG ra,XGR_RA(k1)
+
+ mfc0 t0,C0_CAUSE
+ mfc0 t1,C0_SR
+ MFC0 t2,C0_BADVADDR
+ MFC0 t3,C0_EPC
+ mfc0 t4,C0_PRID
+ mflo t5
+ mfhi t6
+ SREG t0,XCP0_CAUSE(k1)
+ SREG t1,XCP0_SR(k1)
+ SREG t2,XCP0_VADDR(k1)
+ SREG t3,XCP0_EPC(k1)
+ SREG t4,XCP0_PRID(k1)
+ SREG t5,XGR_LO(k1)
+ SREG t6,XGR_HI(k1)
+
+#if CFG_EMBEDDED_PIC
+ la gp,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
+ LR gp,0(gp) # get our GP handle from low memory vector
+#else
+ la gp,_gp # Load up GP, not relocated so it's easy
+#endif
+
+ move a0,k0 # Pass exception type
+ move a1,k1 # Pass frame to exception handler
+ la t0,_exc_vectab # get base of exception vectors
+ srl k0,3 # convert 8-byte index to array index
+ sll k0,BPWSIZE # convert back to index appropriate for word size
+ addu t0,k0 # get vector address
+ LR t0,(t0) # to call handler
+
+ move sp,k1 # "C" gets fresh stack area
+
+ jalr t0 # Call exception handler
+ nop
+
+ move k1, sp
+ LREG AT,XGR_AT(k1)
+
+ LREG t0,XGR_LO(k1)
+ LREG t1,XGR_HI(k1)
+ mtlo t0
+ mthi t1
+
+ LREG a0,XGR_A0(k1)
+ LREG a1,XGR_A1(k1)
+ LREG a2,XGR_A2(k1)
+ LREG a3,XGR_A3(k1)
+
+ LREG t0,XGR_T0(k1)
+ LREG t1,XGR_T1(k1)
+ LREG t2,XGR_T2(k1)
+ LREG t3,XGR_T3(k1)
+ LREG t4,XGR_T4(k1)
+ LREG t5,XGR_T5(k1)
+ LREG t6,XGR_T6(k1)
+ LREG t7,XGR_T7(k1)
+
+ LREG s0,XGR_S0(k1)
+ LREG s1,XGR_S1(k1)
+ LREG s2,XGR_S2(k1)
+ LREG s3,XGR_S3(k1)
+ LREG s4,XGR_S4(k1)
+ LREG s5,XGR_S5(k1)
+ LREG s6,XGR_S6(k1)
+ LREG s7,XGR_S7(k1)
+
+ LREG t8,XGR_T8(k1)
+ LREG t9,XGR_T9(k1)
+
+ LREG gp,XGR_GP(k1)
+ LREG sp,XGR_SP(k1)
+ LREG fp,XGR_FP(k1)
+ LREG ra,XGR_RA(k1)
+
+/* do any CP0 cleanup here */
+
+ LREG v0,XGR_V0(k1)
+ LREG v1,XGR_V1(k1)
+
+ ERET
+
+ .set at
+ .set reorder
+
+
+END(_exc_entry)
+
+
+/* *********************************************************************
+ * _exc_clear_sr_exl()
+ *
+ * Clear SR(EXL) and return to caller.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_clear_sr_exl)
+
+ mfc0 t0,C0_SR
+ and t0,t0,~(0x02) # clear SR(EXL). Bit 1
+ mtc0 t0,C0_SR
+
+ HAZARD
+
+ j ra
+
+END(_exc_clear_sr_exl)
+
+/* *********************************************************************
+ * _exc_clear_sr_erl()
+ *
+ * Clear SR(ERL) and return to caller.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_exc_clear_sr_erl)
+
+ mfc0 t0,C0_SR
+ and t0,t0,~(0x04) # clear SR(ERL). Bit 2
+ mtc0 t0,C0_SR
+
+ HAZARD
+
+ j ra
+
+END(_exc_clear_sr_erl)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/exchandler.c b/cfe/cfe/arch/mips/common/src/exchandler.c
new file mode 100644
index 0000000..d69b980
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/exchandler.c
@@ -0,0 +1,580 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Exception Handler File: exchandler.c
+ *
+ * This is the "C" part of the exception handler and the
+ * associated setup routines. We call these routines from
+ * the assembly-language exception handler.
+ *
+ * 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_printf.h"
+#include "lib_queue.h"
+#include "lib_malloc.h"
+#include "exception.h"
+#include "cfe.h"
+#include "cfe_error.h"
+#include "cfe_iocb.h"
+#include "exchandler.h"
+#include "cpu_config.h"
+#include "bsp_config.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+/*
+ * Temporary until all our CPU packages support a cache error handler
+ */
+
+#ifndef CPUCFG_CERRHANDLER
+#define CPUCFG_CERRHANDLER 0xBFC00000
+#else
+extern void CPUCFG_CERRHANDLER(void);
+#endif
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+exc_handler_t exc_handler;
+extern void _exc_entry(void);
+extern void _exc_setup_locore(long);
+extern void CPUCFG_TLBHANDLER(void);
+extern void cfe_flushcache(uint32_t,long,long);
+extern uint32_t _getstatus(void);
+extern void _setstatus(uint32_t);
+
+static const char *regnames = "0 ATv0v1a0a1a2a3t0t1t2t3t4t5t6t7"
+ "s0s1s2s3s4s5s6s7t8t9k0k1gpspfpra";
+static const char *excnames =
+ "Interrupt" /* 0 */
+ "TLBMod " /* 1 */
+ "TLBMissRd" /* 2 */
+ "TLBMissWr" /* 3 */
+ "AddrErrRd" /* 4 */
+ "AddrErrWr" /* 5 */
+ "BusErrRd " /* 6 */
+ "BusErrWr " /* 7 */
+ "Syscall " /* 8 */
+ "Breakpt " /* 9 */
+ "InvOpcode" /* 10 */
+ "CoProcUnu" /* 11 */
+ "ArithOvfl" /* 12 */
+ "TrapExc " /* 13 */
+ "VCEI " /* 14 */
+ "FPUExc " /* 15 */
+ "CP2Exc " /* 16 */
+ "Exc17 " /* 17 */
+ "Exc18 " /* 18 */
+ "Exc19 " /* 19 */
+ "Exc20 " /* 20 */
+ "Exc21 " /* 21 */
+ "Exc22 " /* 22 */
+ "Watchpt " /* 23 */
+ "Exc24 " /* 24 */
+ "Exc25 " /* 25 */
+ "Exc26 " /* 26 */
+ "Exc27 " /* 27 */
+ "Exc28 " /* 28 */
+ "Exc29 " /* 29 */
+ "Exc30 " /* 30 */
+ "VCED "; /* 31 */
+
+
+
+/* *********************************************************************
+ * cfe_exception(code,info)
+ *
+ * Exception handler. This routine is called when any CPU
+ * exception that is handled by the assembly-language
+ * vectors is reached. The usual thing to do here is just to
+ * reboot.
+ *
+ * Input parameters:
+ * code - exception type
+ * info - exception stack frame
+ *
+ * Return value:
+ * usually reboots
+ ********************************************************************* */
+
+void cfe_exception(int code,uint64_t *info)
+{
+ int idx;
+
+ SETLEDS("EXC!");
+
+ if(exc_handler.catch_exc == 1) {
+ /*Deal with exception without restarting CFE.*/
+
+ /*Clear relevant SR bits*/
+ _exc_clear_sr_exl();
+ _exc_clear_sr_erl();
+
+ /*Reset flag*/
+ exc_handler.catch_exc = 0;
+
+ exc_longjmp_handler();
+ }
+
+
+#ifdef _MIPSREGS32_
+ xprintf("**Exception %d: EPC=%08X, Cause=%08X (%9s)\n",
+ code,(uint32_t)info[XCP0_EPC],
+ (uint32_t)info[XCP0_CAUSE],
+ excnames + G_CAUSE_EXC((uint32_t)info[XCP0_CAUSE])*9);
+ xprintf(" RA=%08X, VAddr=%08X\n",
+ (uint32_t)info[XGR_RA],(uint32_t)info[XCP0_VADDR]);
+ xprintf("\n");
+ for (idx = 0;idx < 32; idx+= 2) {
+ xprintf(" %2s ($%2d) = %08X %2s ($%2d) = %08X\n",
+ regnames+(idx*2),
+ idx,(uint32_t)info[XGR_ZERO+idx],
+ regnames+((idx+1)*2),
+ idx+1,(uint32_t)info[XGR_ZERO+idx+1]);
+ }
+#else
+ xprintf("**Exception %d: EPC=%016llX, Cause=%08X (%9s)\n",
+ code,info[XCP0_EPC],info[XCP0_CAUSE],
+ excnames + G_CAUSE_EXC((uint32_t)info[XCP0_CAUSE])*9);
+ xprintf(" RA=%016llX, VAddr=%016llX\n",
+ info[XGR_RA],info[XCP0_VADDR]);
+ xprintf("\n");
+ for (idx = 0;idx < 32; idx+= 2) {
+ xprintf(" %2s ($%2d) = %016llX %2s ($%2d) = %016llX\n",
+ regnames+(idx*2),
+ idx,info[XGR_ZERO+idx],
+ regnames+((idx+1)*2),
+ idx+1,info[XGR_ZERO+idx+1]);
+ }
+#endif
+
+ xprintf("\n");
+ _exc_restart();
+}
+
+#if (!CFG_BOOTRAM) && (CFG_RUNFROMKSEG0)
+/* *********************************************************************
+ * exc_setup_hw_vector(vecoffset,target,k0code)
+ *
+ * Install a patch of code at the specified offset in low
+ * KSEG0 memory that will jump to 'target' and load k0
+ * with the specified code value. This is used when we
+ * run with RAM vectors.
+ *
+ * Input parameters:
+ * vecoffset - offset into KSEG0
+ * target - location where we should branch when vector is called
+ * k0code - value to load into K0 before branching
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void exc_setup_hw_vector(uint32_t vecoffset,
+ void *target,
+ uint32_t k0code)
+{
+ uint32_t *vec;
+ uint32_t new;
+ uint32_t lower,upper;
+
+ new = (uint32_t) (intptr_t) target; /* warning: assumes compatibility addresses! */
+
+ lower = new & 0xffff;
+ upper = (new >> 16) & 0xffff;
+ if ((lower & 0x8000) != 0) {
+ upper++;
+ }
+
+ /*
+ * Get a KSEG0 version of the vector offset.
+ */
+ vec = (uint32_t *) PHYS_TO_K0(vecoffset);
+
+ /*
+ * Patch in the vector. Note that we have to flush
+ * the L1 Dcache and invalidate the L1 Icache before
+ * we can use this.
+ */
+
+ vec[0] = 0x3c1b0000 | upper; /* lui k1, HIGH(new) */
+ vec[1] = 0x277b0000 | lower; /* addiu k1, k1, LOW(new) */
+ vec[2] = 0x03600008; /* jr k1 */
+ vec[3] = 0x241a0000 | k0code; /* li k0, code */
+
+}
+
+
+/* *********************************************************************
+ * exc_install_ram_vectors()
+ *
+ * Install all of the hardware vectors into low memory,
+ * flush the cache, and clear the BEV bit so we can start
+ * using them.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void exc_install_ram_vectors(void)
+{
+ uint32_t *ptr;
+ int idx;
+
+ /* Debug: blow away the vector area so we can see what we did */
+ ptr = (uint32_t *) PHYS_TO_K0(0);
+ for (idx = 0; idx < 0x1000/sizeof(uint32_t); idx++) *ptr++ = 0;
+
+ /*
+ * Set up the vectors. The cache error handler is set up
+ * specially.
+ */
+
+ exc_setup_hw_vector(MIPS_RAM_VEC_TLBFILL, CPUCFG_TLBHANDLER,XTYPE_TLBFILL);
+ exc_setup_hw_vector(MIPS_RAM_VEC_XTLBFILL, _exc_entry,XTYPE_XTLBFILL);
+ exc_setup_hw_vector(MIPS_RAM_VEC_CACHEERR, _exc_entry,XTYPE_CACHEERR);
+ exc_setup_hw_vector(MIPS_RAM_VEC_EXCEPTION,_exc_entry,XTYPE_EXCEPTION);
+ exc_setup_hw_vector(MIPS_RAM_VEC_INTERRUPT,_exc_entry,XTYPE_INTERRUPT);
+
+ /*
+ * Flush the D-cache and invalidate the I-cache so we can start
+ * using these vectors.
+ */
+
+ cfe_flushcache(CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I,0,0);
+
+ /*
+ * Write the handle into our low memory space. If we need to save
+ * other stuff down there, this is a good place to do it.
+ * This call uses uncached writes - we have not touched the
+ * memory in the handlers just yet, so they should not be
+ * in our caches.
+ */
+
+ _exc_setup_locore((intptr_t) CPUCFG_CERRHANDLER);
+
+ /*
+ * Finally, clear BEV so we'll use the vectors in RAM.
+ */
+
+ _setstatus(_getstatus() & ~M_SR_BEV);
+
+ /*
+ * XXX There's a hazard here, but we're not going to worry about
+ * XXX it. It is unlikely we'll use the vectors any time soon.
+ */
+}
+#endif
+
+/* *********************************************************************
+ * cfe_setup_exceptions()
+ *
+ * Set up the exception handlers.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void cfe_setup_exceptions(void)
+{
+ _exc_setvector(XTYPE_TLBFILL, (void *) cfe_exception);
+ _exc_setvector(XTYPE_XTLBFILL, (void *) cfe_exception);
+ _exc_setvector(XTYPE_CACHEERR, (void *) _exc_cache_crash_sim);
+ _exc_setvector(XTYPE_EXCEPTION,(void *) cfe_exception);
+ _exc_setvector(XTYPE_INTERRUPT,(void *) cfe_exception);
+ _exc_setvector(XTYPE_EJTAG, (void *) cfe_exception);
+
+ exc_handler.catch_exc = 0;
+ q_init( &(exc_handler.jmpbuf_stack));
+
+#if (!CFG_BOOTRAM) && (CFG_RUNFROMKSEG0)
+ /*
+ * Install RAM vectors, and clear the BEV bit in the status
+ * register. Don't do this if we're running from PromICE RAM
+ */
+ exc_install_ram_vectors();
+#endif
+}
+
+
+
+/* *********************************************************************
+ * exc_initialize_block()
+ *
+ * Set up the exception handler. Allow exceptions to be caught.
+ * Allocate memory for jmpbuf and store it away.
+ *
+ * Returns NULL if error in memory allocation.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * jmpbuf_t structure, or NULL if no memory
+ ********************************************************************* */
+jmpbuf_t *exc_initialize_block(void)
+{
+ jmpbuf_t *jmpbuf_local;
+
+ exc_handler.catch_exc = 1;
+
+ /* Create the jmpbuf_t object */
+ jmpbuf_local = (jmpbuf_t *) KMALLOC((sizeof(jmpbuf_t)),0);
+
+ if (jmpbuf_local == NULL) {
+ return NULL;
+ }
+
+ q_enqueue( &(exc_handler.jmpbuf_stack), &((*jmpbuf_local).stack));
+
+ return jmpbuf_local;
+}
+
+/* *********************************************************************
+ * exc_cleanup_block(dq_jmpbuf)
+ *
+ * Remove dq_jmpbuf from the exception handler stack and free
+ * the memory.
+ *
+ * Input parameters:
+ * dq_jmpbuf - block to deallocate
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void exc_cleanup_block(jmpbuf_t *dq_jmpbuf)
+{
+ int count;
+
+ if (dq_jmpbuf == NULL) {
+ return;
+ }
+
+ count = q_count( &(exc_handler.jmpbuf_stack));
+
+ if( count > 0 ) {
+ q_dequeue( &(*dq_jmpbuf).stack );
+ KFREE(dq_jmpbuf);
+ }
+}
+
+/* *********************************************************************
+ * exc_cleanup_handler(dq_jmpbuf,chain_exc)
+ *
+ * Clean a block, then chain to the next exception if required.
+ *
+ * Input parameters:
+ * dq_jmpbuf - current exception
+ * chain_exc - true if we should chain to the next handler
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void exc_cleanup_handler(jmpbuf_t *dq_jmpbuf, int chain_exc)
+{
+ exc_cleanup_block(dq_jmpbuf);
+
+ if( chain_exc == EXC_CHAIN_EXC ) {
+ /*Go to next exception on stack */
+ exc_longjmp_handler();
+ }
+}
+
+
+
+/* *********************************************************************
+ * exc_longjmp_handler()
+ *
+ * This routine long jumps to the exception handler on the top
+ * of the exception stack.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void exc_longjmp_handler(void)
+{
+ int count;
+ jmpbuf_t *jmpbuf_local;
+
+ count = q_count( &(exc_handler.jmpbuf_stack));
+
+ if( count > 0 ) {
+ jmpbuf_local = (jmpbuf_t *) q_getlast(&(exc_handler.jmpbuf_stack));
+
+ SETLEDS("CFE ");
+
+ lib_longjmp( (*jmpbuf_local).jmpbuf, -1);
+ }
+}
+
+
+/* *********************************************************************
+ * mem_peek(d,addr,type)
+ *
+ * Read memory of the specified type at the specified address.
+ * Exceptions are caught in the case of a bad memory reference.
+ *
+ * Input parameters:
+ * d - pointer to where data should be placed
+ * addr - address to read
+ * type - type of read to do (MEM_BYTE, etc.)
+ *
+ * Return value:
+ * 0 if ok
+ * else error code
+ ********************************************************************* */
+
+int mem_peek(void *d, long addr, int type)
+{
+
+ jmpbuf_t *jb;
+
+ jb = exc_initialize_block();
+ if( jb == NULL ) {
+ return CFE_ERR_NOMEM;
+ }
+
+ if (exc_try(jb) == 0) {
+
+ switch (type) {
+ case MEM_BYTE:
+ *(uint8_t *)d = *((volatile uint8_t *) addr);
+ break;
+ case MEM_HALFWORD:
+ *(uint16_t *)d = *((volatile uint16_t *) addr);
+ break;
+ case MEM_WORD:
+ *(uint32_t *)d = *((volatile uint32_t *) addr);
+ break;
+ case MEM_QUADWORD:
+ *(uint64_t *)d = *((volatile uint64_t *) addr);
+ break;
+ default:
+ return CFE_ERR_INV_PARAM;
+ }
+
+ exc_cleanup_block(jb);
+ }
+ else {
+ /*Exception handler*/
+
+ exc_cleanup_handler(jb, EXC_NORMAL_RETURN);
+ return CFE_ERR_GETMEM;
+ }
+
+ return 0;
+}
+
+/* *********************************************************************
+ * Write memory of type at address addr with value val.
+ * Exceptions are caught, handled (error message) and function
+ * returns with 0.
+ *
+ * 1 success
+ * 0 failure
+ ********************************************************************* */
+
+int mem_poke(long addr, uint64_t val, int type)
+{
+
+ jmpbuf_t *jb;
+
+ jb = exc_initialize_block();
+ if( jb == NULL ) {
+ return CFE_ERR_NOMEM;
+ }
+
+ if (exc_try(jb) == 0) {
+
+ switch (type) {
+ case MEM_BYTE:
+ *((volatile uint8_t *) addr) = (uint8_t) val;
+ break;
+ case MEM_HALFWORD:
+ *((volatile uint16_t *) addr) = (uint16_t) val;
+ break;
+ case MEM_WORD:
+ *((volatile uint32_t *) addr) = (uint32_t) val;
+ break;
+ case MEM_QUADWORD:
+ *((volatile uint64_t *) addr) = (uint64_t) val;
+ break;
+ default:
+ return CFE_ERR_INV_PARAM;
+ }
+
+ exc_cleanup_block(jb);
+ }
+ else {
+ /*Exception handler*/
+
+ exc_cleanup_handler(jb, EXC_NORMAL_RETURN);
+ return CFE_ERR_SETMEM;
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/cfe/cfe/arch/mips/common/src/init_mips.S b/cfe/cfe/arch/mips/common/src/init_mips.S
new file mode 100755
index 0000000..3f59539
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/init_mips.S
@@ -0,0 +1,683 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * CPU init module File: init_mips.S
+ *
+ * This module contains the vectors and lowest-level CPU startup
+ * functions for CFE.
+ *
+ * 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 "exception.h"
+
+#include "bsp_config.h"
+#include "cpu_config.h"
+
+#ifdef _CFE_
+#include "cfe_devfuncs.h"
+#else
+
+#define cfe_command_restart 0
+#endif
+
+/* BCM63XX specific change. */
+#include "bcm_hwdefs.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#include "mipsmacros.h"
+
+
+/* *********************************************************************
+ * SETLEDS(a,b,c,d)
+ * SETLEDS1(a,b,c,d)
+ *
+ * Sets the on-board LED display (if present). Two variants
+ * of this routine are provided. If you're running KSEG1,
+ * call the SETLEDS1 variant, else call SETLEDS.
+ *
+ * Input parameters:
+ * a,b,c,d - four ASCII characters (literal constants)
+ *
+ * Return value:
+ * a0,k1,ra trashed
+ ********************************************************************* */
+
+#define SETLEDS(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG0(init_table,R_INIT_SETLEDS)
+
+#define SETLEDS1(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ CALLINIT_KSEG1(init_table,R_INIT_SETLEDS)
+
+
+/* *********************************************************************
+ * Other constants
+ ********************************************************************* */
+
+/*
+ * This is the size of the stack, rounded to KByte boundaries.
+ */
+
+#ifndef CFG_STACK_SIZE
+#error "CFG_STACK_SIZE not defined"
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+#ifdef __MIPSEB
+#define TEXTSECTION 0x2e746578 # ".tex", big-endian
+#else
+#define TEXTSECTION 0x7865742e # ".tex", little-endian
+#endif
+
+/*
+ * 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
+
+
+/*
+ * To make life easier reading this code, define "KSEGBASE"
+ * to either K0BASE or K1BASE depending on whether we're running
+ * uncached.
+ */
+
+#if CFG_RUNFROMKSEG0
+#define KSEGBASE K0BASE
+#else
+#define KSEGBASE K1BASE
+#endif
+
+
+/* *********************************************************************
+ * Names of registers used in this module
+ ********************************************************************* */
+
+#define RELOCOFFSET s8 /* $30 (fp) */
+#define TEXTOFFSET t9 /* $25 (t9) */
+#define MEMTOP t8 /* $24 (t8) */
+#define TEXTBASE s7 /* $23 (s7) */
+#undef BOOT_OFFSET
+#define BOOT_OFFSET s6 /* $22 (s6) */
+
+ .sdata
+
+#include "initdata.h" /* declare variables we use here */
+
+#if CFG_MULTI_CPUS
+ .globl cfe_spinlock
+cfe_spinlock: .word 0
+#endif
+
+ .extern _fdata
+ .extern _edata
+ .extern _etext
+
+/* *********************************************************************
+ * uninitialized data
+ ********************************************************************* */
+
+ .bss
+
+ .comm __junk,4
+
+/* *********************************************************************
+ * Exception Vectors
+ ********************************************************************* */
+
+ .text
+
+ .set noreorder
+
+/*
+ * Declare the actual vectors. This expands to code that
+ * must be at the very beginning of the text segment.
+ */
+
+DECLARE_VECTOR(0x0000,vec_reset,cpu_reset)
+
+ .set reorder
+
+/* *********************************************************************
+ * Some offsets depend on our current configuration
+ ********************************************************************* */
+
+#define RUNTIME_RELOC_START 0
+#define RUNTIME_RELOC_STOP 0
+
+/* *********************************************************************
+ * Segment Table.
+ *
+ * Addresses of data segments and of certain routines we're going
+ * to call from KSEG1. These are here mostly for the embedded
+ * PIC case, since we can't count on the 'la' instruction to
+ * do the expected thing (the assembler expands it into a macro
+ * for doing GP-relative stuff, and the code is NOT GP-relative.
+ * So, we (relocatably) get the offset of this table and then
+ * index within it.
+ *
+ * Pointer values in this segment will be relative to KSEG0 for
+ * cached versions of CFE, so we need to OR in K1BASE in the
+ * case of calling to a uncached address.
+ *
+ * The LOADREL macro handles most of the nastiness here.
+ ********************************************************************* */
+
+#include "segtable.h"
+#include "cfe.h"
+
+ .org 0x570
+ .byte 'c','f','e','-','v',CFE_VER_MAJOR,CFE_VER_MINOR,CFE_VER_BUILD,BCM63XX_MAJOR,BCM63XX_MINOR # CFE version info for applications
+ .org 0x580 # move past exception vectors
+
+ /*
+ * BCM963XX NVRAM Data Storage
+ */
+
+ .globl nvram_data_storage
+nvram_data_storage:
+ .word NVRAM_DATA_ID
+ .space 0x400
+
+ .globl segment_table
+segment_table:
+ _LONG_ _etext # [ 0] End of text (R_SEG_ETEXT)
+ _LONG_ _fdata # [ 1] Beginning of data (R_SEG_FDATA)
+ _LONG_ _edata # [ 2] End of data (R_SEG_EDATA)
+ _LONG_ _end # [ 3] End of BSS (R_SEG_END)
+ _LONG_ _ftext # [ 4] Beginning of text (R_SEG_FTEXT)
+ _LONG_ _fbss # [ 5] Beginning of BSS (R_SEG_FBSS)
+ _LONG_ _gp # [ 6] Global Pointer (R_SEG_GP)
+ _LONG_ 0 # [ 7] Beginning of reloc entries
+ _LONG_ 0 # [ 8] End of reloc entries
+ _LONG_ 0 # [ 9] R_SEG_APIENTRY
+
+/* *********************************************************************
+ * Init Table.
+ *
+ * This is like segment_table except it contains pointers to
+ * routines used during initialization. It serves both as a
+ * table for doing PIC stuff and also to separate out
+ * machine-specific init routines.
+ *
+ * The CALLINIT_xxx macros are used to call routines in this table.
+ ********************************************************************* */
+
+
+ .globl init_table
+init_table:
+ _LONG_ board_earlyinit # [ 0] R_INIT_EARLYINIT
+ _LONG_ board_setleds # [ 1] R_INIT_SETLEDS
+ _LONG_ board_draminfo # [ 2] R_INIT_DRAMINFO
+ _LONG_ CPUCFG_CPUINIT # [ 3] R_INIT_CPUINIT
+ _LONG_ CPUCFG_ALTCPU_START1 # [ 4] R_INIT_ALTCPU_START1
+ _LONG_ CPUCFG_ALTCPU_START2 # [ 5] R_INIT_ALTCPU_START2
+ _LONG_ CPUCFG_ALTCPU_RESET # [ 6] R_INIT_ALTCPU_RESET
+ _LONG_ CPUCFG_CPURESTART # [ 7] R_INIT_CPURESTART
+ _LONG_ CPUCFG_DRAMINIT # [ 8] R_INIT_DRAMINIT
+ _LONG_ CPUCFG_CACHEOPS # [ 9] R_INIT_CACHEOPS
+ _LONG_ CPUCFG_TLBHANDLER # [ 10] R_INIT_TLBHANDLER
+ _LONG_ cfe_main # [ 11] R_INIT_CMDSTART
+ _LONG_ cfe_command_restart # [ 12] R_INIT_CMDRESTART
+ _LONG_ cfe_doxreq # [ 13] R_INIT_DOXREQ
+ _LONG_ CPUCFG_TP1_SWITCH # [ 14] R_INIT_TP1_SWITCH
+ _LONG_ cfe_size_ram # [ 15] R_INIT_SIZERAM
+
+/* *********************************************************************
+ * CPU Startup Code
+ ********************************************************************* */
+
+cpu_reset:
+
+ /*
+ * Start with GP as zero. Nobody should touch
+ * this or set it to any other value until we're ready
+ * to use it. This is used to tell when we should start
+ * using relocated references in the init table,
+ * so beware! (see CALLINIT_RELOC in mipsmacros.h)
+ */
+
+ move gp,zero # start with no GP.
+
+ .set noreorder
+ bal 1f
+ nop
+1: nop
+ .set reorder
+ li BOOT_OFFSET, 0x1fff0000
+ and BOOT_OFFSET, ra
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Do low-level board initialization. This is our first
+ * chance to customize the startup sequence.
+ */
+ move a0, BOOT_OFFSET
+
+ CALLINIT_KSEG1(init_table,R_INIT_EARLYINIT)
+
+ SETLEDS1('H','E','L','O')
+
+ CALLINIT_KSEG1(init_table,R_INIT_CPUINIT)
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Now, switch from KSEG1 to KSEG0
+ */
+
+#if CFG_RUNFROMKSEG0
+ bal cpu_kseg0_switch
+#endif
+
+#------------------------------------------------------------------------------
+ /*
+ * Now running on cpu0 in K0SEG.
+ */
+
+#if CFG_CMT
+ /*
+ * Check if the thread switch is required. If we are already
+ * running on thread 1 this function will do nothing and just return
+ * If we are running on thread 0 this function will take thread 1
+ * out of reset and put thread 0 to sleep waiting for singnal from
+ * thread 1.
+ */
+ CALLINIT_KSEG0(init_table,R_INIT_TP1_SWITCH)
+#endif
+
+#if CFG_INIT_DRAM
+ SETLEDS('D','R','A','M')
+
+ CALLINIT_KSEG0(init_table,R_INIT_DRAMINFO)
+
+ move a0,v0 # pass these params
+ CALLINIT_KSEG0(init_table,R_INIT_DRAMINIT)
+ CALLINIT_KSEG0(init_table,R_INIT_SIZERAM)
+ move k0,v0 # Save in k0 for now
+#else
+ li k0,(CFG_DRAM_SIZE * 1024)
+#endif
+
+#------------------------------------------------------------------------------
+
+#if CFG_BOOTRAM
+ b have_ram # No RAM is ok if using emulator RAM
+#endif
+
+ bne k0,zero,have_ram
+
+ SETLEDS('R','A','M','X') # die here if no ram
+
+die1: b die1
+
+have_ram:
+
+ /*
+ * If this is the 64-bit version, turn on the KX bit
+ * to allow 64-bit accesses.
+ */
+
+#ifdef __long64
+ mfc0 t0,C0_SR
+ or t0,t0,M_SR_KX
+ mtc0 t0,C0_SR
+#endif
+
+#------------------------------------------------------------------------------
+ /*
+ * K0 contains the RAM size (and therefore the top of RAM
+ * offset). Start there, and subtract the amount of memory
+ * we expect to use. If we have more than 256MB of
+ * physical memory, work backwards from the 256MB
+ * boundary.
+ */
+
+__CalcMemTop: li MEMTOP,256 # 256MB boundary
+ bgt k0,MEMTOP,1f # use 256MB if k0 is greater
+ move MEMTOP,k0 # otherwise keep top
+1: sll MEMTOP,20 # make into byte amount
+
+ li RELOCOFFSET,0 # not relocating, no offset
+ li TEXTOFFSET,0
+
+ /*
+ * DRAM is now running, and we're alive in cacheable memory
+ * on cpu0 in K0SEG. Set up GP.
+ */
+
+ LOADREL(a0,segment_table)
+ LR gp,R_SEG_GP(a0)
+ add gp,RELOCOFFSET
+
+#------------------------------------------------------------------------------
+ /*
+ * Zero BSS
+ */
+
+ SETLEDS('Z','B','S','S')
+
+ LOADREL(a0,segment_table)
+__ZeroBss:
+
+ LR v0,R_SEG_FBSS(a0)
+ LR v1,R_SEG_END(a0)
+ ADD v0,RELOCOFFSET # Relocate to actual data segment
+ ADD v1,RELOCOFFSET
+
+1: SR zero,0(v0) # Zero one cacheline at a time
+ SR zero,(REGSIZE*1)(v0)
+ SR zero,(REGSIZE*2)(v0)
+ SR zero,(REGSIZE*3)(v0)
+ add v0,REGSIZE*4
+ blt v0,v1,1b
+
+#------------------------------------------------------------------------------
+ /*
+ * Copy code
+ */
+
+ SETLEDS('C','O','D','E')
+
+ LOADREL(a0,segment_table)
+__CopyCode:
+
+ LR t1,R_SEG_FTEXT(a0) # destination address
+ move TEXTBASE,t1
+
+ LR t2,R_SEG_FTEXT(a0) # Source address
+ FIXUP (t2);
+ LR t3,R_SEG_ETEXT(a0)
+ FIXUP (t3);
+
+1: LR t4,0(t2) # read one cache line
+ LR t5,(REGSIZE*1)(t2)
+ LR t6,(REGSIZE*2)(t2)
+ LR t7,(REGSIZE*3)(t2)
+ SR t4,0(t1) # write one cache line
+ SR t5,(REGSIZE*1)(t1)
+ SR t6,(REGSIZE*2)(t1)
+ SR t7,(REGSIZE*3)(t1)
+ add t1,REGSIZE*4
+ add t2,REGSIZE*4
+ bltu t2,t3,1b
+
+#------------------------------------------------------------------------------
+ /*
+ * Copy initialized data
+ */
+
+#if (CFG_BOOTRAM == 0)
+
+ SETLEDS('D','A','T','A')
+
+ LOADREL(a0,segment_table)
+
+__CopyData:
+ LR t1,R_SEG_FDATA(a0)
+ FIXUP (t1);
+ li t0,15
+ add t1,t0
+ not t0
+ and t1,t0 # t1 = _etext rounded up to 16-byte boundary
+
+ LR t2,R_SEG_FDATA(a0)
+ LR t3,R_SEG_EDATA(a0)
+ ADD t2,RELOCOFFSET # Relocate to actual data segment
+ ADD t3,RELOCOFFSET
+
+1: LR t4,0(t1) # read one cache line
+ LR t5,(REGSIZE*1)(t1)
+ LR t6,(REGSIZE*2)(t1)
+ LR t7,(REGSIZE*3)(t1)
+ SR t4,0(t2) # write one cache line
+ SR t5,(REGSIZE*1)(t2)
+ SR t6,(REGSIZE*2)(t2)
+ SR t7,(REGSIZE*3)(t2)
+ add t1,(REGSIZE*4)
+ add t2,(REGSIZE*4)
+ bltu t2,t3,1b
+
+#endif
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Flush the cache, then switch to relocated code
+ * We need to flush the cache since we just moved the code and
+ * it may still live in our L1 DCache. We also need to
+ * flush L2, since there are some rare times we run
+ * uncached from DRAM, like when we start/stop a CPU.
+ *
+ * In the case of running completely uncached, don't flush the
+ * cache. It should not have any dirty lines in it, but you
+ * never know...
+ */
+
+__GoRelo:
+
+#if CFG_RUNFROMKSEG0
+ SETLEDS('L','1','2','F')
+
+ li a0,CFE_CACHE_FLUSH_D | CFE_CACHE_FLUSH_L2
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+ li a0,CFE_CACHE_INVAL_I
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+#endif /* CFG_RUNFROMKSEG0 */
+
+ la t0,gorelo # Now jump to an address code was compiled for
+ j t0 # and go there
+gorelo: nop
+ li BOOT_OFFSET, 0 # no longer running at offset
+
+ /*
+ * Remember total amount of memory. This is *still* in k0
+ * after all this time. Hopefully.
+ */
+
+__MemVars:
+ SR k0,mem_totalsize
+ SR RELOCOFFSET,mem_datareloc
+
+ move v0,zero
+
+ LOADREL(a0,segment_table) # trashed by l2 cache flush
+ LR v0,R_SEG_FDATA(a0)
+ ADD v0,RELOCOFFSET
+ LR v1,R_SEG_END(a0)
+ ADD v1,RELOCOFFSET
+
+ SR v0,mem_bottomofmem
+ SR v1,mem_heapstart
+
+ add v1,(CFG_HEAP_SIZE*1024) # Otherwise
+ add v1,STACK_SIZE
+ SR v1,mem_topofmem
+
+ SR TEXTOFFSET,mem_textreloc
+
+ /* At this point it's safe to use the CALLINIT_RELOC macro */
+
+ LR t1,R_SEG_FTEXT(a0)
+ FIXUP (t1);
+ LR t0,R_SEG_ETEXT(a0)
+ FIXUP (t0);
+ sub t0,t0,t1
+ SR t0,mem_textsize
+ add t1,TEXTOFFSET
+ SR t1,mem_textbase
+
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Stash away some config register stuff
+ */
+
+ mfc0 v0,C0_PRID
+ SR v0,cpu_prid
+
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Set up the "C" stack and jump to the main routine.
+ */
+
+ SETLEDS('M','A','I','N')
+
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+ li a0,0 # call as "cfe_main(0,0)"
+ li a1,0
+
+ CALLINIT_RELOC(init_table,R_INIT_CMDSTART) # should not return
+
+/* *********************************************************************
+ * CFE_LAUNCH
+ *
+ * Start the user program. The program is passed a handle
+ * that must be passed back when calling the firmware.
+ *
+ * Parameters passed to the called program are as follows:
+ *
+ * a0 - CFE handle
+ * a1 - entry vector
+ * a2 - reserved, will be 0
+ * a3 - entrypoint signature.
+ *
+ * Input parameters:
+ * a0 - entry vector
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+LEAF(cfe_launch)
+
+ sub sp,8
+ SR a0,0(sp)
+
+ /*
+ * This function runs in RAM so BOOT_OFFSET is 0. It is called from
+ * C which could have modified the BOOT_OFFSET register, s6.
+ */
+ li BOOT_OFFSET, 0
+
+
+ /*
+ * Mask all interrupts.
+ */
+ mfc0 v0,C0_SR # Get current interrupt flag
+ li v1,M_SR_IE # master interrupt control
+ not v1 # disable interrupts
+ and v0,v1 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+
+ /*
+ * Flush the D-Cache, since the program we loaded is "data".
+ * 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.
+ */
+
+ li a0,CFE_CACHE_FLUSH_D|CFE_CACHE_INVAL_I
+ CALLINIT_RELOC(init_table,R_INIT_CACHEOPS)
+
+
+ /*
+ * Set things up for launching the program. Pass the
+ * handle in A0 - apps need to remember that and pass it
+ * back.
+ */
+
+ j RunProgram
+
+END(cfe_launch)
+
+ /*
+ * This is a nice place to set a breakpoint.
+ */
+LEAF(RunProgram)
+ LR t0,0(sp) # entry point
+
+ j t0 # go for it.
+END(RunProgram)
+
+/* *********************************************************************
+ * CPU_KSEG0_SWITCH
+ *
+ * Hack the return address so we will come back in KSEG0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cpu_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(cpu_kseg0_switch)
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/init_ram.S b/cfe/cfe/arch/mips/common/src/init_ram.S
new file mode 100755
index 0000000..2531700
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/init_ram.S
@@ -0,0 +1,889 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * CPU init module File: init_ram.S
+ *
+ * This module contains the vectors and lowest-level CPU startup
+ * functions for CFE.
+ *
+ * This is very similar to "init_mips.S" but is used when
+ * you want to locate CFE in DRAM, loading it like an
+ * application program.
+ *
+ * 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 "exception.h"
+
+#include "bsp_config.h"
+#include "cpu_config.h"
+
+#include "cfe_devfuncs.h"
+
+/* *********************************************************************
+ * Check some stuff
+ ********************************************************************* */
+
+#if CFG_RELOC
+#error "RAM version is not compatible with relocation."
+#endif
+#if !(CFG_RUNFROMKSEG0)
+#error "RAM version should be run cached"
+#endif
+
+#if CFG_MULTI_CPUS
+#error "Multiple CPUs not compatible with RAM version"
+#endif
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#include "mipsmacros.h"
+
+
+/* *********************************************************************
+ * SETLEDS(a,b,c,d)
+ *
+ * Sets the on-board LED display (if present).
+ *
+ * Input parameters:
+ * a,b,c,d - four ASCII characters (literal constants)
+ *
+ * Return value:
+ * a0,k1,ra trashed
+ ********************************************************************* */
+
+
+#define SETLEDS(a,b,c,d) \
+ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
+ jal board_setleds ;
+
+
+/* *********************************************************************
+ * Other constants
+ ********************************************************************* */
+
+/*
+ * This is the size of the stack, rounded to KByte boundaries.
+ */
+
+#ifndef CFG_STACK_SIZE
+#error "CFG_STACK_SIZE not defined"
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+/*
+ * 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
+
+
+/*
+ * To make life easier reading this code, define "KSEGBASE"
+ * to either K0BASE or K1BASE depending on whether we're running
+ * uncached.
+ */
+
+#define KSEGBASE K0BASE /* RAM version always cached */
+
+
+/* *********************************************************************
+ * Names of registers used in this module
+ ********************************************************************* */
+
+ .sdata
+
+#include "initdata.h" /* declare variables we use here */
+
+#if CFG_MULTI_CPUS
+ .globl cfe_spinlock
+cfe_spinlock: .word 0
+#endif
+
+ .extern _fdata
+ .extern _edata
+ .extern _etext
+
+/* *********************************************************************
+ * uninitialized data
+ ********************************************************************* */
+
+ .bss
+
+ .comm __junk,4
+
+ .text
+
+ .set noreorder
+
+
+/* *********************************************************************
+ * CFE Entry Point (used by OS boot loaders and such)
+ ********************************************************************* */
+
+ .set noreorder
+
+ .globl vec_reset
+
+vec_reset: b cpu_reset
+ nop
+
+
+vec_apientry: b cpu_apientry
+ nop
+ .word CFE_EPTSEAL
+ .word CFE_EPTSEAL
+
+ .set reorder
+
+
+/* *********************************************************************
+ * Segment Table.
+ *
+ * Addresses of data segments and of certain routines we're going
+ * to call from KSEG1. These are here mostly for the embedded
+ * PIC case, since we can't count on the 'la' instruction to
+ * do the expected thing (the assembler expands it into a macro
+ * for doing GP-relative stuff, and the code is NOT GP-relative.
+ * So, we (relocatably) get the offset of this table and then
+ * index within it.
+ *
+ * Pointer values in this segment will be relative to KSEG0 for
+ * cached versions of CFE, so we need to OR in K1BASE in the
+ * case of calling to a uncached address.
+ *
+ * The LOADREL macro handles most of the nastiness here.
+ ********************************************************************* */
+
+
+#include "segtable.h"
+
+ .globl segment_table
+segment_table:
+ _LONG_ _etext # [ 0] End of text (R_SEG_ETEXT)
+ _LONG_ _fdata # [ 1] Beginning of data (R_SEG_FDATA)
+ _LONG_ _edata # [ 2] End of data (R_SEG_EDATA)
+ _LONG_ _end # [ 3] End of BSS (R_SEG_END)
+ _LONG_ _ftext # [ 4] Beginning of text (R_SEG_FTEXT)
+ _LONG_ _fbss # [ 5] Beginning of BSS (R_SEG_FBSS)
+ _LONG_ _gp # [ 6] Global Pointer (R_SEG_GP)
+ _LONG_ 0 # [ 7] Beginning of reloc entries
+ _LONG_ 0 # [ 8] End of reloc entries
+ _LONG_ cpu_apientry # [ 9] R_SEG_APIENTRY
+
+
+/* *********************************************************************
+ * Init Table.
+ *
+ * This is like segment_table except it contains pointers to
+ * routines used during initialization. It serves both as a
+ * table for doing PIC stuff and also to separate out
+ * machine-specific init routines.
+ *
+ * The CALLINIT_xxx macros are used to call routines in this table.
+ ********************************************************************* */
+
+
+ .globl init_table
+init_table:
+ _LONG_ board_earlyinit # [ 0] R_INIT_EARLYINIT
+ _LONG_ board_setleds # [ 1] R_INIT_SETLEDS
+ _LONG_ board_draminfo # [ 2] R_INIT_DRAMINFO
+ _LONG_ CPUCFG_CPUINIT # [ 3] R_INIT_CPUINIT
+ _LONG_ CPUCFG_ALTCPU_START1 # [ 4] R_INIT_ALTCPU_START1
+ _LONG_ CPUCFG_ALTCPU_START2 # [ 5] R_INIT_ALTCPU_START2
+ _LONG_ CPUCFG_ALTCPU_RESET # [ 6] R_INIT_ALTCPU_RESET
+ _LONG_ CPUCFG_CPURESTART # [ 7] R_INIT_CPURESTART
+ _LONG_ CPUCFG_DRAMINIT # [ 8] R_INIT_DRAMINIT
+ _LONG_ CPUCFG_CACHEOPS # [ 9] R_INIT_CACHEOPS
+ _LONG_ CPUCFG_TLBHANDLER # [ 10] R_INIT_TLBHANDLER
+ _LONG_ cfe_main # [ 11] R_INIT_CMDSTART
+ _LONG_ cfe_command_restart # [ 12] R_INIT_CMDRESTART
+ _LONG_ cfe_doxreq # [ 13] R_INIT_DOXREQ
+ _LONG_ CPUCFG_TP1_SWITCH # [ 14] R_INIT_TP1_SWITCH
+ _LONG_ bcmcore_null # [ 15] R_INIT_SIZERAM
+
+/* *********************************************************************
+ * CPU Startup Code
+ ********************************************************************* */
+
+
+cpu_reset:
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Do low-level board initialization. This is our first
+ * chance to customize the startup sequence.
+ */
+
+ CALLINIT_KSEG0(init_table,R_INIT_EARLYINIT)
+
+ SETLEDS('H','E','L','O')
+
+#------------------------------------------------------------------------------
+
+ /*
+ * DRAM is now running, and we're alive in cacheable memory
+ * on cpu0 in K0SEG. Set up GP.
+ */
+
+ LOADREL(a0,segment_table)
+ LR gp,R_SEG_GP(a0)
+
+#------------------------------------------------------------------------------
+ /*
+ * Zero BSS
+ */
+
+ SETLEDS('Z','B','S','S')
+
+ LOADREL(a0,segment_table)
+__ZeroBss:
+
+ LR v0,R_SEG_FBSS(a0)
+ LR v1,R_SEG_END(a0)
+
+1: SR zero,0(v0) # Zero one cacheline at a time
+ SR zero,(REGSIZE*1)(v0)
+ SR zero,(REGSIZE*2)(v0)
+ SR zero,(REGSIZE*3)(v0)
+ add v0,REGSIZE*4
+ blt v0,v1,1b
+
+
+#------------------------------------------------------------------------------
+
+ li k0,256 # memory size in megabytes
+
+
+#ifdef __long64
+ mfc0 t0,C0_SR
+ or t0,t0,M_SR_KX
+ mtc0 t0,C0_SR
+#endif
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Remember total amount of memory. This is *still* in k0
+ * after all this time. Hopefully.
+ */
+
+__MemVars:
+ SR k0,mem_totalsize
+ SR zero,mem_datareloc
+
+ move v0,zero
+
+ LOADREL(a0,segment_table) # trashed by l2 cache flush
+ LR v0,R_SEG_FTEXT(a0) # bottom = beginning of text
+ LR v1,R_SEG_END(a0)
+
+ SR v0,mem_bottomofmem
+ SR v1,mem_heapstart
+
+ add v1,(CFG_HEAP_SIZE*1024) # Otherwise
+ add v1,STACK_SIZE
+ SR v1,mem_topofmem
+
+ SR zero,mem_textreloc
+
+
+ LR t1,R_SEG_FTEXT(a0)
+ LR t0,R_SEG_ETEXT(a0)
+ sub t0,t0,t1
+ SR t0,mem_textsize
+ SR t1,mem_textbase
+
+
+#------------------------------------------------------------------------------
+
+#if CFG_MULTI_CPUS
+ /*
+ * Let secondary CPU(s) run their idle loops. Set the
+ * mailbox register to our relocation factor so we can read
+ * it out of the mailbox register and relocate GP properly.
+ */
+
+ move a0,zero
+ CALLINIT_KSEG0(init_table,R_INIT_ALTCPU_START2)
+#endif
+
+ /*
+ * Stash away some config register stuff
+ */
+
+ mfc0 v0,C0_PRID
+ SR v0,cpu_prid
+
+
+#------------------------------------------------------------------------------
+
+ /*
+ * Set up the "C" stack and jump to the main routine.
+ */
+
+ SETLEDS('M','A','I','N')
+
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+ li a0,0 # call as "cfe_main(0,0)"
+ li a1,0
+
+ CALLINIT_KSEG0(init_table,R_INIT_CMDSTART) # should not return
+
+
+ /*
+ * Terminate the simulator.
+ */
+
+crash_sim: li $2,1
+ li $4,0
+ syscall 0xCA
+ b cpu_reset
+
+
+
+/* *********************************************************************
+ * CFE_WARMSTART
+ *
+ * Restart the command interpreter
+ *
+ * Input parameters:
+ * A0 - command status
+ * nothing (GP has already been set up for us)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cfe_warmstart)
+
+ SR a0,0(sp) # store on old stack
+ LOADREL(v0,init_table)
+ LR v0,R_INIT_CPURESTART(v0)
+ jal v0 # had better not trash GP or K1
+ LR a0,0(sp)
+
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+
+ /*
+ * If someone called the API to do a warm start, clear the
+ * spin lock, since the call will never return.
+ */
+
+#if CFG_MULTI_CPUS
+ SPIN_UNLOCK(cfe_spinlock,t0)
+#endif
+
+ CALLINIT_KSEG0(init_table,R_INIT_CMDRESTART) # should not return
+
+END(cfe_warmstart)
+
+/* *********************************************************************
+ * CFE_FLUSHCACHE
+ *
+ * Perform certain cache operations
+ *
+ * Input parameters:
+ * a0 - flags (CFE_CACHE_xxx flags, or zero for a default)
+ * a1,a2 - start/end of range for "range invalidate" operations
+ * (not used otherwise)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_cfe_flushcache)
+
+ sub sp,32
+ SR ra,0(sp)
+ SR a0,8(sp)
+ SR s0,16(sp)
+ SR v1,24(sp)
+
+
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+
+ LR v1,24(sp)
+ LR s0,16(sp)
+ LR a0,8(sp)
+ LR ra,0(sp)
+ add sp,32
+ j ra
+
+END(_cfe_flushcache)
+
+
+/* *********************************************************************
+ * CFE_LAUNCH
+ *
+ * Start the user program. The program is passed a handle
+ * that must be passed back when calling the firmware.
+ *
+ * Parameters passed to the called program are as follows:
+ *
+ * a0 - CFE handle
+ * a1 - entry vector
+ * a2 - reserved, will be 0
+ * a3 - entrypoint signature.
+ *
+ * Input parameters:
+ * a0 - entry vector
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+LEAF(cfe_launch)
+
+ sub sp,8
+ SR a0,0(sp)
+
+ /*
+ * Mask all interrupts.
+ */
+ mfc0 v0,C0_SR # Get current interrupt flag
+ li v1,M_SR_IE # master interrupt control
+ not v1 # disable interrupts
+ and v0,v1 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+ /*
+ * Flush the D-Cache, since the program we loaded is "data".
+ * 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.
+ */
+
+ li a0,CFE_CACHE_FLUSH_D|CFE_CACHE_INVAL_I
+ CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS)
+
+ /*
+ * Set things up for launching the program. Pass the
+ * handle in A0 - apps need to remember that and pass it
+ * back.
+ */
+
+ j RunProgram
+
+END(cfe_launch)
+
+ /*
+ * This is a nice place to set a breakpoint.
+ */
+LEAF(RunProgram)
+
+ LOADREL(a2,segment_table)
+ LR a2,R_SEG_APIENTRY(a2) # A2 = code entry
+ move t0,a0 #
+ move a1,zero # A1 = 0
+ move a0,gp # A0 = handle
+ li a3,CFE_EPTSEAL # A3 = entrypoint signature
+ LR t0,0(sp) # entry point
+ j t0 # go for it.
+END(RunProgram)
+
+
+
+
+/* *********************************************************************
+ * CFE_LEDS
+ *
+ * Set the on-board LEDs.
+ *
+ * Input parameters:
+ * a0 - LEDs
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cfe_leds)
+
+ j board_setleds # jump to BSP routine
+
+END(cfe_leds)
+
+/* *********************************************************************
+ * TLB Fill Exeption Handler
+ ********************************************************************* */
+
+cpu_tlbfill:
+ move k0,ra # Save, we're about to trash
+ LOADREL(k1,init_table) # Load offset of init table
+ LR k1,R_INIT_TLBHANDLER(k1) # Get entry from table
+ move ra,k0 # restore trashed ra
+ j k1 # Dispatch to handler
+
+/* *********************************************************************
+ * XTLB Fill Exception Handler
+ ********************************************************************* */
+
+cpu_xtlbfill:
+ j _exc_entry
+
+/* *********************************************************************
+ * Cache Error Exception Handler
+ ********************************************************************* */
+
+cpu_cacheerr:
+ j _exc_entry
+
+
+/* *********************************************************************
+ * General Exception Handler
+ ********************************************************************* */
+
+cpu_exception:
+ j _exc_entry
+
+
+/* *********************************************************************
+ * General Interrupt Handler
+ ********************************************************************* */
+
+cpu_interrupt:
+ j _exc_entry
+
+
+/* *********************************************************************
+ * EJTAG Debug Exception Handler
+ ********************************************************************* */
+
+cpu_ejtag:
+ j cpu_reset
+
+/* *********************************************************************
+ * cpu_apientry(handle,iocb)
+ *
+ * API entry point for external apps.
+ *
+ * Input parameters:
+ * a0 - firmware handle (used to determine the location of
+ * our relocated data)
+ * a1 - pointer to IOCB to execute
+ *
+ * Return value:
+ * v0 - return code, 0 if ok
+ ********************************************************************* */
+
+#define _regidx(x) ((x)*8)
+
+#define CAE_SRSAVE _regidx(0)
+#define CAE_GPSAVE _regidx(1)
+#define CAE_RASAVE _regidx(2)
+#define CAE_S0SAVE _regidx(3)
+#define CAE_S1SAVE _regidx(4)
+#define CAE_S2SAVE _regidx(5)
+#define CAE_S3SAVE _regidx(6)
+#define CAE_S4SAVE _regidx(7)
+#define CAE_S5SAVE _regidx(8)
+#define CAE_S6SAVE _regidx(9)
+#define CAE_S7SAVE _regidx(10)
+
+#define CAE_STKSIZE _regidx(11)
+
+LEAF(cpu_apientry)
+
+ sub sp,CAE_STKSIZE # Make room for our stuff
+
+ mfc0 v0,C0_SR # Get current interrupt flag
+ SR v0,CAE_SRSAVE(sp) # save on stack
+ li t0,M_SR_IE # master interrupt control
+ not t0 # disable interrupts
+ and v0,t0 # SR now has IE=0
+ mtc0 v0,C0_SR # put back into CP0
+
+ SR gp,CAE_GPSAVE(sp) # save GP
+ SR ra,CAE_RASAVE(sp) # and old RA
+
+ SR s0,CAE_S0SAVE(sp)
+ SR s1,CAE_S1SAVE(sp)
+ SR s2,CAE_S2SAVE(sp)
+ SR s3,CAE_S3SAVE(sp)
+ SR s4,CAE_S4SAVE(sp)
+ SR s5,CAE_S5SAVE(sp)
+ SR s6,CAE_S6SAVE(sp)
+ SR s7,CAE_S7SAVE(sp)
+
+ move gp,a0 # set up new GP
+ move a0,a1 # A0 points at IOCB
+
+
+#if CFG_MULTI_CPUS
+ SPIN_LOCK(cfe_spinlock,t0,t1)
+#endif
+
+ CALLINIT_KSEG0(init_table,R_INIT_DOXREQ) # should not return
+
+#if CFG_MULTI_CPUS
+ SPIN_UNLOCK(cfe_spinlock,t0)
+#endif
+
+ #
+ # Restore the saved registers.
+ #
+
+ LR s7,CAE_S7SAVE(sp)
+ LR s6,CAE_S6SAVE(sp)
+ LR s5,CAE_S5SAVE(sp)
+ LR s4,CAE_S4SAVE(sp)
+ LR s3,CAE_S3SAVE(sp)
+ LR s2,CAE_S2SAVE(sp)
+ LR s1,CAE_S1SAVE(sp)
+ LR s0,CAE_S0SAVE(sp)
+
+ LR ra,CAE_RASAVE(sp) # unwind the stack
+ LR gp,CAE_GPSAVE(sp)
+
+ LR t0,CAE_SRSAVE(sp) # old interrupt mask
+
+ add sp,CAE_STKSIZE # restore old stack pointer
+
+ mtc0 t0,C0_SR # restore interrupts
+ j ra
+ nop
+
+END(cpu_apientry)
+
+
+/* *********************************************************************
+ * CPU_KSEG0_SWITCH
+ *
+ * Hack the return address so we will come back in KSEG0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(cpu_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(cpu_kseg0_switch)
+
+
+
+
+/* *********************************************************************
+ * _GETSTATUS()
+ *
+ * Read the STATUS register into v0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - Status register
+ ********************************************************************* */
+
+LEAF(_getstatus)
+
+ mfc0 v0,C0_SR
+ j ra
+END(_getstatus)
+
+
+/* *********************************************************************
+ * _SETSTATUS()
+ *
+ * Set the STATUS register to the value in a0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - Status register
+ ********************************************************************* */
+
+LEAF(_setstatus)
+
+ mtc0 a0,C0_SR
+ j ra
+END(_setstatus)
+
+/* *********************************************************************
+ * _GETCAUSE()
+ *
+ * Read the CAUSE register into v0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - Cause register
+ ********************************************************************* */
+
+LEAF(_getcause)
+
+ mfc0 v0,C0_CAUSE
+ j ra
+END(_getcause)
+
+
+/* *********************************************************************
+ * _GETTICKS()
+ *
+ * Read the COUNT register into v0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * v0 - count register
+ ********************************************************************* */
+
+LEAF(_getticks)
+
+ mfc0 v0,C0_COUNT
+ j ra
+END(_getticks)
+
+
+/* *********************************************************************
+ * _SETALARM(ticks)
+ *
+ * Set the C0_Compare register from a0
+ *
+ * Input parameters:
+ * a0 - compare register
+ *
+ * Return value:
+ * none
+ ********************************************************************* */
+
+LEAF(_setalarm)
+
+ mtc0 a0,C0_COMPARE
+ j ra
+END(_setalarm)
+
+
+/* *********************************************************************
+ * _SETCONTEXT()
+ *
+ * Set the CONTEXT register.
+ *
+ * Input parameters:
+ * a0 - context
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_setcontext)
+
+ mtc0 a0,C0_CTEXT
+ j ra
+END(_setcontext)
+
+/* *********************************************************************
+ * _GETSEGTBL()
+ *
+ * Return the address of the segment table. We use this
+ * to display the startup messages.
+ *
+ * You can't just address the table from C because it lives
+ * in the text segment.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * address of table
+ ********************************************************************* */
+
+
+LEAF(_getsegtbl)
+ move t0,ra
+ LOADREL(v0,segment_table)
+ move ra,t0
+ j ra
+END(_getsegtbl)
+
+
+/* *********************************************************************
+ * _wbflush()
+ *
+ * Flush the write buffer. This is probably not necessary
+ * on SiByte CPUs, but we have it for completeness.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(_wbflush)
+
+ sync /* drain the buffers */
+ la t0,__junk /* do an uncached read to force it out */
+ or t0,K1BASE
+ lw zero,0(t0)
+ j ra
+
+END(_wbflush)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+
diff --git a/cfe/cfe/arch/mips/common/src/lib_hssubr.S b/cfe/cfe/arch/mips/common/src/lib_hssubr.S
new file mode 100644
index 0000000..07085e3
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/lib_hssubr.S
@@ -0,0 +1,194 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Hyperspace Subroutines File: lib_hssubr.S
+ *
+ * Little stub routines to allow access to KXSEG from 32-bit progs.
+ *
+ * Author: Mitch Lichtenberg (mitch@sibyte.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 "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD */
+
+
+/* *********************************************************************
+ * hs_read8 - read 8-bit bytes
+ ********************************************************************* */
+
+
+LEAF(hs_read8)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ lbu v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read8)
+
+/* *********************************************************************
+ * hs_read16 - read 16-bit shorts
+ ********************************************************************* */
+
+LEAF(hs_read16)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ lhu v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read16)
+
+/* *********************************************************************
+ * hs_read32 - read 32-bit ints
+ ********************************************************************* */
+
+LEAF(hs_read32)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ lw v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read32)
+
+/* *********************************************************************
+ * hs_read64 - read 64-bit longs
+ ********************************************************************* */
+
+LEAF(hs_read64)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ ld v0,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_read64)
+
+/* *********************************************************************
+ * hs_write8 - write 8-bit bytes
+ ********************************************************************* */
+
+LEAF(hs_write8)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sb a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write8)
+
+/* *********************************************************************
+ * hs_write16 - write 16-bit shorts
+ ********************************************************************* */
+
+LEAF(hs_write16)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sh a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write16)
+
+/* *********************************************************************
+ * hs_write32 - write 32-bit longs
+ ********************************************************************* */
+
+LEAF(hs_write32)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sw a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write32)
+
+/* *********************************************************************
+ * hs_write64 - write 64-bit longs
+ ********************************************************************* */
+
+LEAF(hs_write64)
+ mfc0 t2,C0_SR
+ or t1,t2,M_SR_KX
+ mtc0 t1,C0_SR
+ HAZARD
+
+ sd a1,(a0)
+
+ mtc0 t2,C0_SR
+ HAZARD
+ j ra
+END(hs_write64)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
diff --git a/cfe/cfe/arch/mips/common/src/lib_physio.S b/cfe/cfe/arch/mips/common/src/lib_physio.S
new file mode 100644
index 0000000..7f57fea
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/lib_physio.S
@@ -0,0 +1,173 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical memory peek/poke routines File: lib_physio.S
+ *
+ * Little stub routines to allow access to arbitrary physical
+ * addresses. In most cases this should not be needed, as
+ * many physical addresses are within kseg1, but this handles
+ * the cases that are not automagically, so we don't need
+ * to mess up the code with icky macros and such.
+ *
+ * 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 "mipsmacros.h"
+#include "cpu_config.h" /* for definition of HAZARD */
+
+
+/* *********************************************************************
+ * PHYSOP(inst,a)
+ *
+ * Macro to construct code for doing the physical I/O
+ * We try to avoid messing with KX or doing 64-bit stuff
+ * unless necessary.
+ *
+ * Input parameters:
+ * INST - instruction name to run
+ * A - register containing arg or return value
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+
+#ifdef _MIPSREGS32_
+#define PHYSOP(INST,A) \
+ or a0,a0,K1BASE ; \
+ INST A,0(a0) ; \
+ j ra ;
+#else
+#define PHYSOP(INST,A) \
+ lui t0,0x2000 ; \
+ bgeu a0,t0,1f ; \
+ or a0,a0,K1BASE ; \
+ INST A,0(a0) ; \
+ j ra ; \
+1: lui t0,0x9000 ; \
+ dsll t0,t0,32 ; \
+ or a0,a0,t0 ; \
+ mfc0 t1,C0_SR ; \
+ and t0,t1,M_SR_KX ; \
+ beq t0,zero,1f ; \
+ INST A,0(a0) ; \
+ j ra ; \
+1: or t0,t1,M_SR_KX ; \
+ mtc0 t0,C0_SR ; \
+ HAZARD ; \
+ INST A,0(a0) ; \
+ mtc0 t1,C0_SR ; \
+ HAZARD ; \
+ j ra ;
+#endif
+
+
+/* *********************************************************************
+ * phys_read8 - read 8-bit bytes
+ ********************************************************************* */
+
+
+LEAF(phys_read8)
+PHYSOP(lbu,v0)
+END(phys_read8)
+
+/* *********************************************************************
+ * phys_read16 - read 16-bit shorts
+ ********************************************************************* */
+
+LEAF(phys_read16)
+PHYSOP(lh,v0)
+END(phys_read16)
+
+/* *********************************************************************
+ * phys_read32 - read 32-bit ints
+ ********************************************************************* */
+
+LEAF(phys_read32)
+PHYSOP(lw,v0)
+END(phys_read32)
+
+/* *********************************************************************
+ * phys_read64 - read 64-bit longs
+ ********************************************************************* */
+
+LEAF(phys_read64)
+PHYSOP(ld,v0)
+END(phys_read64)
+
+/* *********************************************************************
+ * phys_write8 - write 8-bit bytes
+ ********************************************************************* */
+
+LEAF(phys_write8)
+PHYSOP(sb,a1)
+END(phys_write8)
+
+/* *********************************************************************
+ * phys_write16 - write 16-bit shorts
+ ********************************************************************* */
+
+LEAF(phys_write16)
+PHYSOP(sh,a1)
+END(phys_write16)
+
+/* *********************************************************************
+ * phys_write32 - write 32-bit longs
+ ********************************************************************* */
+
+LEAF(phys_write32)
+PHYSOP(sw,a1)
+END(phys_write32)
+
+/* *********************************************************************
+ * phys_write64 - write 64-bit longs
+ ********************************************************************* */
+
+LEAF(phys_write64)
+PHYSOP(sd,a1)
+END(phys_write64)
+
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
diff --git a/cfe/cfe/arch/mips/common/src/lib_setjmp.S b/cfe/cfe/arch/mips/common/src/lib_setjmp.S
new file mode 100644
index 0000000..b8c82b3
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/lib_setjmp.S
@@ -0,0 +1,94 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Simple setjmp/longjmp File: lib_setjmp.S
+ *
+ * A very simple SETJMP and LONGJMP
+ *
+ * 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_setjmp.h"
+
+#ifdef _MIPSREGS32_
+#define SREG sw
+#define LREG lw
+#else
+#define SREG sd
+#define LREG ld
+#endif
+
+LEAF(lib_setjmp)
+
+ SREG s0,JMPB_S0(a0)
+ SREG s1,JMPB_S1(a0)
+ SREG s2,JMPB_S2(a0)
+ SREG s3,JMPB_S3(a0)
+ SREG s4,JMPB_S4(a0)
+ SREG s5,JMPB_S5(a0)
+ SREG s6,JMPB_S6(a0)
+ SREG s7,JMPB_S7(a0)
+ SREG fp,JMPB_FP(a0)
+ SREG sp,JMPB_SP(a0)
+ SREG ra,JMPB_RA(a0)
+ move v0,zero
+ j ra
+
+END(lib_setjmp)
+
+LEAF(lib_longjmp)
+ LREG s0,JMPB_S0(a0)
+ LREG s1,JMPB_S1(a0)
+ LREG s2,JMPB_S2(a0)
+ LREG s3,JMPB_S3(a0)
+ LREG s4,JMPB_S4(a0)
+ LREG s5,JMPB_S5(a0)
+ LREG s6,JMPB_S6(a0)
+ LREG s7,JMPB_S7(a0)
+ LREG fp,JMPB_FP(a0)
+ LREG sp,JMPB_SP(a0)
+ LREG ra,JMPB_RA(a0)
+ move v0,a1
+ jr ra
+END(lib_longjmp)
+
diff --git a/cfe/cfe/arch/mips/common/src/mips_arena.c b/cfe/cfe/arch/mips/common/src/mips_arena.c
new file mode 100644
index 0000000..d96fee6
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/mips_arena.c
@@ -0,0 +1,186 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Physical Memory (arena) manager File: sb1250_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 "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_
+
+#include "cpu_config.h"
+
+#include "addrspace.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+
+#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;
+uint64_t *cfe_pagetable = NULL;
+
+extern void CPUCFG_PAGETBLINIT(uint64_t *ptaddr,unsigned int ptstart);
+
+void cfe_bootarea_init(void);
+extern void _setcontext(int64_t);
+
+
+/* *********************************************************************
+ * CFE_BOOTAREA_INIT()
+ *
+ * Initialize the page table and map our boot program area.
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void cfe_bootarea_init(void)
+{
+ unsigned char *pte;
+ int64_t pte_int;
+ unsigned int addr = 16*MEG;
+ unsigned int topmem;
+ unsigned int topcfe;
+ unsigned int botcfe;
+ unsigned int beforecfe;
+ unsigned int aftercfe;
+
+ /*
+ * Calculate the location where the boot area will
+ * live. It lives either above or below the
+ * firmware, depending on where there's more space.
+ */
+
+ /*
+ * The firmware will always be loaded in the first
+ * 256M. Calculate the top of that region. The bottom
+ * of that region is always the beginning of our
+ * data segment.
+ */
+ if (mem_totalsize > (uint64_t)256) {
+ topmem = 256*MEG;
+ }
+ else {
+ topmem = (unsigned int) (mem_totalsize << 20);
+ }
+ botcfe = (unsigned int) K1_TO_PHYS(mem_bottomofmem);
+ topcfe = (unsigned int) K1_TO_PHYS(mem_topofmem);
+
+ beforecfe = botcfe;
+ aftercfe = topmem-topcfe;
+
+ if (beforecfe > aftercfe) {
+ botcfe -= (PAGESIZE-1);
+ botcfe &= ~(PAGESIZE-1); /* round down to page boundary */
+ addr = botcfe - CFE_BOOTAREA_SIZE; /* this is the address */
+ }
+ else {
+ topcfe += (PAGESIZE-1); /* round *up* to a page address */
+ topcfe &= ~(PAGESIZE-1);
+ addr = topcfe;
+ }
+
+ mem_bootarea_start = addr;
+ mem_bootarea_size = CFE_BOOTAREA_SIZE;
+
+ /*
+ * Allocate the page table
+ */
+
+ pte = KMALLOC(1024,1024);
+
+#ifdef __long64
+ pte_int = (int64_t) pte;
+#else
+ pte_int = (int64_t) ((int) pte);
+#endif
+
+ /*
+ * Set the CP0 CONTEXT register to point at the page table
+ */
+
+ pte_int <<= 13;
+ cfe_pagetable = (uint64_t *) pte;
+
+ _setcontext(pte_int);
+
+
+ /*
+ * Initialize page table entries
+ */
+
+ CPUCFG_PAGETBLINIT(cfe_pagetable,addr);
+
+
+}
+
diff --git a/cfe/cfe/arch/mips/common/src/tools.mk b/cfe/cfe/arch/mips/common/src/tools.mk
new file mode 100755
index 0000000..d195de9
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/tools.mk
@@ -0,0 +1,83 @@
+#
+# Basic compiler options and preprocessor flags
+#
+
+CFLAGS += -g -c -ffreestanding
+CFLAGS += -O1 -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
+
+#
+# Tools locations
+#
+
+ifndef TOOLS
+TOOLS=/opt/toolchains/uclibc-crosstools-gcc-4.4.2-1/usr/bin/mips-linux-
+endif
+
+GCC ?= $(TOOLS)gcc
+GLD ?= $(TOOLS)ld
+AR ?= $(TOOLS)ar
+OBJDUMP ?= $(TOOLS)objdump
+OBJCOPY ?= $(TOOLS)objcopy
+RANLIB ?= $(TOOLS)ranlib
+
+#
+# Check for 64-bit mode
+#
+
+ifeq ($(strip ${CFG_MLONG64}),1)
+ CFLAGS += -mlong64 -D__long64
+endif
+
+#
+# Figure out which linker script to use
+#
+
+ifeq ($(strip ${CFG_RAMAPP}),1)
+ CFLAGS += -DCFG_RAMAPP=1
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_ramapp.lds
+ CFLAGS += -DCFG_RUNFROMKSEG0=1
+else
+ ifeq ($(strip ${CFG_RELOC}),0)
+ ifeq ($(strip ${CFG_BOOTRAM}),1)
+ CFLAGS += -DCFG_BOOTRAM=1
+ ROMRAM = ram
+ else
+ CFLAGS += -DCFG_BOOTRAM=0
+ ROMRAM = rom
+ endif
+ ifeq ($(strip ${CFG_UNCACHED}),1)
+ CFLAGS += -DCFG_RUNFROMKSEG0=0
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_${ROMRAM}_uncached.lds
+ else
+ CFLAGS += -DCFG_RUNFROMKSEG0=1
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_${ROMRAM}_cached.lds
+ endif
+ else
+ CFLAGS += -membedded-pic -mlong-calls -DCFG_EMBEDDED_PIC=1
+ ifeq ($(strip ${CFG_UNCACHED}),1)
+ CFLAGS += -DCFG_RUNFROMKSEG0=0
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_rom_reloc_uncached.lds --embedded-relocs
+ else
+ CFLAGS += -DCFG_RUNFROMKSEG0=1
+ ifeq ($(strip ${CFG_TEXTAT1MB}),1)
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_rom_reloc_cached_biendian.lds --embedded-relocs
+ else
+ LDFLAGS = -g --script ${ARCH_SRC}/cfe_rom_reloc_cached.lds --embedded-relocs
+ endif
+ endif
+ endif
+endif
+#
+# Determine target endianness
+#
+
+ifeq ($(strip ${CFG_LITTLE}),1)
+ ENDIAN = -EL
+ CFLAGS += -EL
+ LDFLAGS += -EL
+else
+ ENDIAN = -EB
+ CFLAGS += -EB
+ LDFLAGS += -EB
+endif
+
diff --git a/cfe/cfe/arch/mips/common/src/ui_memtest.c b/cfe/cfe/arch/mips/common/src/ui_memtest.c
new file mode 100644
index 0000000..5388fd8
--- /dev/null
+++ b/cfe/cfe/arch/mips/common/src/ui_memtest.c
@@ -0,0 +1,282 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Test commands File: ui_memtest.c
+ *
+ * A simple memory test
+ *
+ * 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 "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_console.h"
+#include "cfe_devfuncs.h"
+
+#include "cfe_error.h"
+
+#include "ui_command.h"
+#include "cfe.h"
+
+#include "bsp_config.h"
+
+#include "cfe_mem.h"
+
+
+#ifdef __long64
+static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[]);
+#endif
+
+#ifndef _SB_MAKE64
+#define _SB_MAKE64(x) ((uint64_t)(x))
+#endif
+#ifndef _SB_MAKEMASK
+#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n))
+#endif
+#ifndef _SB_MAKEMASK1
+#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
+#endif
+
+
+int ui_init_memtestcmds(void);
+
+int ui_init_memtestcmds(void)
+{
+#ifdef __long64
+ cmd_addcmd("memorytest",
+ ui_cmd_memorytest,
+ NULL,
+ "Tests all available memory",
+ "",
+ "-loop;Loop forever or until keypress|"
+ "-stoponerror;Stop if error occurs while looping|"
+ "-cca=*;Use specified cacheability attribute|"
+ "-arena=*;Test only specified arena index");
+#endif
+ return 0;
+}
+
+
+#ifdef __long64
+/* extensive memory tests */
+
+static void inline uacwrite(volatile long *srcadr,long *dstadr)
+{
+__asm __volatile ("ld $8, 0(%0) ; "
+ "ld $9, 8(%0) ; "
+ "ld $10, 16(%0) ; "
+ "ld $11, 24(%0) ; "
+ "sync ; "
+ "sd $8, 0(%1) ; "
+ "sd $9, 8(%1) ; "
+ "sd $10, 16(%1) ; "
+ "sd $11, 24(%1) ; "
+ "sync" :: "r"(srcadr),"r"(dstadr) : "$8","$9","$10","$11");
+}
+
+
+#define TEST_DATA_LEN 4
+#define CACHE_LINE_LEN 32
+
+static int ui_cmd_memorytest(ui_cmdline_t *cmd,int argc,char *argv[])
+{
+
+ static volatile long test_data[TEST_DATA_LEN] = {
+ 0xaaaaaaaaaaaaaaaa, 0x5555555555555555, 0xcccccccccccccccc, 0x3333333333333333, /* one cache line */
+ };
+ int arena, exitLoop;
+ int error;
+ int arena_type;
+ uint64_t arena_start, arena_size;
+ long phys_addr, offset, mem_base, cache_mem_base, i;
+ long *dst_adr, *cache_dst_adr;
+ long cda,tda;
+ int forever;
+ int passcnt;
+ int stoponerr = 0;
+ int cca = K_CALG_UNCACHED_ACCEL;
+ int arenanum = -1;
+ char *x;
+
+ arena = 0;
+ exitLoop = 0;
+ offset = 0;
+ mem_base = 0;
+ passcnt = 0;
+ error = 0;
+
+ forever = cmd_sw_isset(cmd,"-loop");
+ stoponerr = cmd_sw_isset(cmd,"-stoponerror");
+ if (cmd_sw_value(cmd,"-cca",&x)) cca = atoi(x);
+ if (cmd_sw_value(cmd,"-arena",&x)) arenanum = atoi(x);
+
+ printf("Available memory arenas:\n");
+ while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) {
+ phys_addr = (long) arena_start; /* actual physical address */
+ mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */
+ xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size);
+ arena++;
+ }
+
+ printf("\nTesting memory.\n");
+ do {
+
+ passcnt++;
+ if (forever) {
+ if (console_status()) break;
+ printf("***** Iteration %d *****\n",passcnt);
+ }
+
+ arena = 0;
+ exitLoop = 0;
+ error = 0;
+
+ while (cfe_arena_enum(arena, &arena_type, &arena_start, &arena_size, FALSE) == 0) {
+
+ if ((arenanum >= 0) && (arena != arenanum)) {
+ arena++;
+ continue;
+ }
+
+ test_data[0] = 0xAAAAAAAAAAAAAAAA;
+ test_data[1] = 0x5555555555555555;
+ test_data[2] = 0xCCCCCCCCCCCCCCCC;
+ test_data[3] = 0x3333333333333333;
+
+ phys_addr = (long) arena_start; /* actual physical address */
+ mem_base = PHYS_TO_XKPHYS(cca, phys_addr); /* virtual address */
+ cache_mem_base = PHYS_TO_K0(phys_addr);
+
+ xprintf("\n");
+ xprintf("Testing: phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr, mem_base, arena_size);
+
+ xprintf("Writing: a/5/c/3\n");
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ uacwrite(test_data, dst_adr);
+ }
+
+ xprintf("Reading: a/5/c/3\n");
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ cache_dst_adr = (long*)(mem_base+offset);
+ for (i = 0; i < TEST_DATA_LEN; i++) {
+ cda = cache_dst_adr[i];
+ tda = test_data[i];
+ if (cda != tda) {
+ xprintf("mem[%016llX] %016llX != %016llX\n",
+ mem_base+offset+(i*8), cda, tda);
+ exitLoop = 1;
+ }
+ }
+ if (exitLoop) break;
+ }
+
+
+ if (exitLoop) {
+ exitLoop = 0;
+ error++;
+ arena++;
+ continue;
+ }
+
+ xprintf("Writing: address|5555/inv/aaaa|address\n");
+ exitLoop = 0;
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ test_data[0] = ((long)dst_adr<<32)|0x55555555;
+ test_data[1] = ~test_data[0];
+ test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff);
+ test_data[3] = ~test_data[2];
+ uacwrite(test_data, dst_adr);
+ }
+
+ xprintf("Reading: address|5555/inv/aaaa|address\n");
+
+ for (offset = 0; (offset < arena_size); offset += CACHE_LINE_LEN) {
+ dst_adr = (long*)(mem_base+offset);
+ test_data[0] = ((long)dst_adr<<32)|0x55555555;
+ test_data[1] = ~test_data[0];
+ test_data[2] = 0xaaaaaaaa00000000|((long)dst_adr & 0xffffffff);
+ test_data[3] = ~test_data[2];
+ cache_dst_adr = (long*)(mem_base+offset);
+ for (i = 0; i < TEST_DATA_LEN; i++) {
+ cda = cache_dst_adr[i];
+ tda = test_data[i];
+ if (cda != tda) {
+ xprintf("mem[%016llX] %016llX != %016llX\n",
+ mem_base+offset+(i*8),cda,tda);
+ exitLoop = 1;
+ }
+ }
+ if (exitLoop) break;
+ }
+
+ if (exitLoop) {
+ error++;
+ exitLoop = 0;
+ if (stoponerr) forever = 0;
+ }
+
+ arena++;
+ }
+ } while (forever);
+
+ if (error) printf("Failing address: %016llX\n",mem_base+offset);
+
+ return error ? -1 : 0;
+}
+
+#endif
+
+
+
+