[newlib-cygwin/main] mips: Implement MIPS HAL and UHI
Jeff Johnston
jjohnstn@sourceware.org
Sat Jul 5 01:26:05 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=467a2bdf17ad376dafada9f1734784f4611fa6fd
commit 467a2bdf17ad376dafada9f1734784f4611fa6fd
Author: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
Date: Wed Jun 11 10:11:33 2025 +0200
mips: Implement MIPS HAL and UHI
Implement abstract interface for MIPS, including unified hosting
interface (UHI).
Signed-off-by: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
Diff:
---
libgloss/config/mips.mt | 60 +-
libgloss/configure | 19 +-
libgloss/kill.c | 1 +
libgloss/mips/Makefile.in | 180 ++-
libgloss/mips/acinclude.m4 | 19 +-
libgloss/mips/boot/corecheck_predef.S | 227 ++++
libgloss/mips/boot/init_caches.S | 178 +++
libgloss/mips/boot/init_caches_predef.S | 183 +++
libgloss/mips/boot/init_cm3l2.S | 145 +++
libgloss/mips/boot/init_cm3l2_predef.S | 123 ++
libgloss/mips/boot/init_cp0.S | 105 ++
libgloss/mips/boot/init_cp0_predef.S | 131 +++
libgloss/mips/boot/init_l23caches.S | 141 +++
libgloss/mips/boot/init_l23caches_predef.S | 161 +++
libgloss/mips/boot/init_tlb.S | 348 ++++++
libgloss/mips/boot/init_tlb_predef.S | 149 +++
libgloss/mips/boot/predef.h | 153 +++
libgloss/mips/boot/reset.S | 222 ++++
libgloss/mips/boot/reset_predef.S | 243 ++++
libgloss/mips/bootcode.ld | 14 +
libgloss/mips/crt0.S | 316 ------
libgloss/mips/fstat.c | 32 +
libgloss/mips/hal/__exit.c | 48 +
libgloss/mips/hal/abiflags.S | 110 ++
libgloss/mips/hal/cache.h | 82 ++
libgloss/mips/hal/crt0.S | 312 ++++++
libgloss/mips/hal/get_ram_range.c | 65 ++
libgloss/mips/hal/libcm3.a | 34 +
libgloss/mips/hal/link.c | 39 +
libgloss/mips/hal/minicrt.S | 31 +
libgloss/mips/hal/mips64_tlb.c | 219 ++++
libgloss/mips/hal/mips_clean_cache.c | 113 ++
libgloss/mips/hal/mips_cm3_l2size.c | 88 ++
libgloss/mips/hal/mips_dsp.S | 127 +++
libgloss/mips/hal/mips_excpt_boot.S | 378 +++++++
libgloss/mips/hal/mips_excpt_entry.S | 210 ++++
libgloss/mips/hal/mips_excpt_handler.c | 309 ++++++
libgloss/mips/hal/mips_excpt_isr_fallback.S | 50 +
libgloss/mips/hal/mips_excpt_isr_fragment.S | 71 ++
libgloss/mips/hal/mips_excpt_register.S | 145 +++
libgloss/mips/hal/mips_excpt_timer.S | 101 ++
libgloss/mips/hal/mips_flush_cache.c | 106 ++
libgloss/mips/hal/mips_fp.S | 182 +++
libgloss/mips/hal/mips_intctrl.c | 148 +++
libgloss/mips/hal/mips_l2size.c | 94 ++
libgloss/mips/hal/mips_lock_cache.c | 81 ++
libgloss/mips/hal/mips_msa.S | 181 +++
libgloss/mips/hal/mips_size_cache.c | 106 ++
libgloss/mips/hal/mips_sync_cache.c | 62 ++
libgloss/mips/hal/mips_tlb.c | 477 ++++++++
libgloss/mips/hal/mips_xpa.S | 75 ++
libgloss/mips/hal/syscalls.c | 52 +
libgloss/mips/idtmon.S | 3 +-
libgloss/mips/include/mips/asm.h | 354 ++++++
libgloss/mips/include/mips/cm3.h | 75 ++
libgloss/mips/include/mips/cpu.h | 354 ++++++
libgloss/mips/include/mips/ctx.S | 147 +++
libgloss/mips/include/mips/dsp.h | 58 +
libgloss/mips/include/mips/endian.h | 91 ++
libgloss/mips/include/mips/fgregdef.h | 126 +++
libgloss/mips/include/mips/fpa.h | 31 +
libgloss/mips/include/mips/hal.h | 454 ++++++++
libgloss/mips/include/mips/intctrl.h | 69 ++
libgloss/mips/include/mips/m32c0.h | 1605 +++++++++++++++++++++++++++
libgloss/mips/include/mips/m32c1.h | 274 +++++
libgloss/mips/include/mips/m32tlb.h | 101 ++
libgloss/mips/include/mips/m64c0.h | 266 +++++
libgloss/mips/include/mips/m64tlb.h | 104 ++
libgloss/mips/include/mips/mips32.h | 175 +++
libgloss/mips/include/mips/mips64.h | 114 ++
libgloss/mips/include/mips/mt.h | 519 +++++++++
libgloss/mips/include/mips/notlb.h | 113 ++
libgloss/mips/include/mips/prid.h | 128 +++
libgloss/mips/include/mips/regdef.h | 131 +++
libgloss/mips/include/mips/uhi_syscalls.h | 68 ++
libgloss/mips/include/mips/version.h | 4 +
libgloss/mips/malta32-yamon.ld | 316 ++++++
libgloss/mips/mti32.ld | 1 -
libgloss/mips/mti64.ld | 1 -
libgloss/mips/mti64_n32.ld | 1 -
libgloss/mips/regs.S | 5 +-
libgloss/mips/syscalls.c | 48 -
libgloss/mips/uhi/uhi_assert.c | 73 ++
libgloss/mips/uhi/uhi_break.c | 62 ++
libgloss/mips/uhi/uhi_close.c | 71 ++
libgloss/mips/uhi/uhi_exception.c | 63 ++
libgloss/mips/uhi/uhi_exit.c | 87 ++
libgloss/mips/uhi/uhi_fstat.c | 159 +++
libgloss/mips/uhi/uhi_get_ram_range.c | 62 ++
libgloss/mips/uhi/uhi_getargs.S | 106 ++
libgloss/mips/uhi/uhi_indirect.c | 56 +
libgloss/mips/uhi/uhi_link.c | 80 ++
libgloss/mips/uhi/uhi_lseek.c | 76 ++
libgloss/mips/uhi/uhi_open.c | 75 ++
libgloss/mips/uhi/uhi_plog.c | 79 ++
libgloss/mips/uhi/uhi_pread.c | 78 ++
libgloss/mips/uhi/uhi_pwrite.c | 78 ++
libgloss/mips/uhi/uhi_read.c | 75 ++
libgloss/mips/uhi/uhi_stat.c | 58 +
libgloss/mips/uhi/uhi_stat.h | 51 +
libgloss/mips/uhi/uhi_unlink.c | 77 ++
libgloss/mips/uhi/uhi_write.c | 75 ++
libgloss/mips/uhi/yamon_close.c | 81 ++
libgloss/mips/uhi/yamon_exception.c | 52 +
libgloss/mips/uhi/yamon_exit.c | 60 +
libgloss/mips/uhi/yamon_fstat.c | 183 +++
libgloss/mips/uhi/yamon_read.c | 101 ++
libgloss/mips/uhi/yamon_syscalls.h | 33 +
libgloss/mips/uhi/yamon_write.c | 98 ++
libgloss/mips/uhi32.ld | 322 ++++++
libgloss/mips/uhi64_64.ld | 322 ++++++
libgloss/mips/uhi64_n32.ld | 322 ++++++
newlib/configure.host | 1 +
newlib/libc/include/machine/ieeefp.h | 6 +
newlib/libc/include/sys/config.h | 2 +-
newlib/libc/include/sys/stat.h | 16 +-
newlib/libc/machine/mips/machine/regdef.h | 38 +
newlib/libc/machine/mips/setjmp.S | 6 +-
newlib/libc/machine/mips/strcmp.S | 190 ++--
newlib/libc/machine/mips/strlen.c | 20 +-
120 files changed, 15841 insertions(+), 535 deletions(-)
diff --git a/libgloss/config/mips.mt b/libgloss/config/mips.mt
index 6ae84b44f..7be62dc5f 100644
--- a/libgloss/config/mips.mt
+++ b/libgloss/config/mips.mt
@@ -4,28 +4,62 @@
# are mentioned here, they are not used for all targets.
#
close.o: ${srcdir}/../close.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
fstat.o: ${srcdir}/../fstat.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
getpid.o: ${srcdir}/../getpid.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
isatty.o: ${srcdir}/../isatty.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
kill.o: ${srcdir}/../kill.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
lseek.o: ${srcdir}/../lseek.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
open.o: ${srcdir}/../open.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
print.o: ${srcdir}/../print.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
putnum.o: ${srcdir}/../putnum.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
read.o: ${srcdir}/../read.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
stat.o: ${srcdir}/../stat.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
unlink.o: ${srcdir}/../unlink.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
write.o: ${srcdir}/../write.c
- $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
+get_ram_range.o: ${srcdir}/hal/get_ram_range.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
+link.o: $(srcdir)/hal/link.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $?
+
+# These are the UHI implementations of semi-hosting functions
+
+uhi_getargs.o: $(srcdir)/uhi/uhi_getargs.S
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $<
+uhi_%.o: $(srcdir)/uhi/uhi_%.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $<
+
+# These are the YAMON specific versions of semi-hosting which fall
+# back to UHI for operations not supported natively on YAMON
+yamon_%.o: $(srcdir)/uhi/yamon_%.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $<
+
+# Exception and interrupt handling support
+mips_excpt_handler.o: $(srcdir)/hal/mips_excpt_handler.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) -DVERBOSE_EXCEPTIONS=1 $(INCLUDES) -c $(CFLAGS) $<
+mips_excpt_handler_quiet.o: $(srcdir)/hal/mips_excpt_handler.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $< -o $@
+%.o: $(srcdir)/hal/%.S
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $< -o $@
+%.o: $(srcdir)/hal/%.c
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $< -o $@
+mips_excpt_isr_000.o:
+ $(CC) $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(INCLUDES) $(CFLAGS) -c -DDEF=__isr_vec_000 -DREF=__isr_vec_000 -DISR=_mips_isr_000 -DZERO ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@
+mips_excpt_isr_%.o:
+ $(CC) $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(INCLUDES) $(CFLAGS) -c -DDEF=__isr_vec_$* -DREF=__isr_vec_$(shell printf '%03d' `expr $* - 1`) -DISR=_mips_isr_$* ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@
+
+# Boot code
+%.o: $(srcdir)/boot/%.S
+ $(CC) $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) -c $(CFLAGS) $<
diff --git a/libgloss/configure b/libgloss/configure
index a0cc8b50f..3eb4c2740 100755
--- a/libgloss/configure
+++ b/libgloss/configure
@@ -5461,18 +5461,16 @@ case "${target}" in
MIPS_SCRIPT_LIST="dve idt jmr3904app jmr3904dram jmr3904dram-java jmr3904app-java sde32 sde64 mti32 mti64 mti64_n32 mti64_64"
MIPS_BSP_LIST="libdve.a libidt.a libjmr3904.a"
;;
- mipsisa32-*-* | mipsisa32el-*-* | \
- mipsisa32r2-*-* | mipsisa32r2el-*-* | \
- mipsisa64*-*-*)
- MIPS_CRT0="crt0_cfe.o crt0_cygmon.o crt0.o"
- MIPS_SCRIPT_LIST="idt32 idt64 cfe"
- MIPS_BSP_LIST="libcygmon.a libidt.a libcfe.a"
- ;;
mips*-lsi*-*)
MIPS_PART_SPECIFIC_OBJ="entry.o"
MIPS_SCRIPT_LIST="lsi"
MIPS_BSP_LIST=liblsi.a
;;
+ mips*-mti*-* | mips*-img*-*)
+ MIPS_CRT0="crt0.o"
+ MIPS_SCRIPT_LIST="idt nullmon mti32 mti64_n32 mti64_64 uhi32 uhi64_64 uhi64_n32 malta32-yamon bootcode"
+ MIPS_BSP_LIST="libidt.a libnullmon.a libuhi.a libyamon.a libhal.a libcm3_impl.a"
+ ;;
mips64vr5*-*-*)
MIPS_PART_SPECIFIC_OBJ="vr5xxx.o cma101.o"
MIPS_PART_SPECIFIC_DEFINES=-DR5000
@@ -5484,6 +5482,13 @@ case "${target}" in
MIPS_SCRIPT_LIST="ddb ddb-kseg0 nullmon"
MIPS_BSP_LIST="libpmon.a libnullmon.a"
;;
+ mipsisa32-*-* | mipsisa32el-*-* | \
+ mipsisa32r2-*-* | mipsisa32r2el-*-* | \
+ mipsisa64*-*-*)
+ MIPS_CRT0="crt0_cfe.o crt0_cygmon.o crt0.o"
+ MIPS_SCRIPT_LIST="idt32 idt64 cfe"
+ MIPS_BSP_LIST="libcygmon.a libidt.a libcfe.a"
+ ;;
mips*)
MIPS_CRT0="crt0_cfe.o crt0.o"
MIPS_PART_SPECIFIC_OBJ="vr4300.o cma101.o"
diff --git a/libgloss/kill.c b/libgloss/kill.c
index 4b9b73636..fd52bd667 100644
--- a/libgloss/kill.c
+++ b/libgloss/kill.c
@@ -13,6 +13,7 @@
* they apply.
*/
#include "glue.h"
+void _exit(int);
extern void _exit (int) __attribute__((__noreturn__));
diff --git a/libgloss/mips/Makefile.in b/libgloss/mips/Makefile.in
index 4213a1d1f..56c58574d 100644
--- a/libgloss/mips/Makefile.in
+++ b/libgloss/mips/Makefile.in
@@ -67,7 +67,8 @@ OBJCOPY = `if [ -f ${objroot}/../binutils/objcopy ] ; \
CRT0 = @MIPS_CRT0@
PCRT0 = pcrt0.o
GENOBJS = syscalls.o fstat.o getpid.o isatty.o kill.o \
- lseek.o print.o putnum.o stat.o unlink.o
+ lseek.o print.o putnum.o stat.o unlink.o __exit.o link.o \
+ get_ram_range.o
GENOBJS2 = open.o close.o read.o write.o
IDTOBJS = idtmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
PMONOBJS = pmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
@@ -77,11 +78,125 @@ JMR3904OBJS = jmr3904-io.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS} ${GENOBJS2}
CFEOBJS = cfe.o cfe_api.o cfe_mem.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS} ${GENOBJS2}
CYGMONOBJS = open.o close.o cygmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
+
+ISROBJS = mips_excpt_isr_fallback.o
+ISROBJS += mips_excpt_isr_000.o mips_excpt_isr_001.o mips_excpt_isr_002.o
+ISROBJS += mips_excpt_isr_003.o mips_excpt_isr_004.o mips_excpt_isr_005.o
+ISROBJS += mips_excpt_isr_006.o mips_excpt_isr_007.o mips_excpt_isr_008.o
+ISROBJS += mips_excpt_isr_009.o mips_excpt_isr_010.o mips_excpt_isr_011.o
+ISROBJS += mips_excpt_isr_012.o mips_excpt_isr_013.o mips_excpt_isr_014.o
+ISROBJS += mips_excpt_isr_015.o mips_excpt_isr_016.o mips_excpt_isr_017.o
+ISROBJS += mips_excpt_isr_018.o mips_excpt_isr_019.o mips_excpt_isr_020.o
+ISROBJS += mips_excpt_isr_021.o mips_excpt_isr_022.o mips_excpt_isr_023.o
+ISROBJS += mips_excpt_isr_024.o mips_excpt_isr_025.o mips_excpt_isr_026.o
+ISROBJS += mips_excpt_isr_027.o mips_excpt_isr_028.o mips_excpt_isr_029.o
+ISROBJS += mips_excpt_isr_030.o mips_excpt_isr_031.o mips_excpt_isr_032.o
+ISROBJS += mips_excpt_isr_033.o mips_excpt_isr_034.o mips_excpt_isr_035.o
+ISROBJS += mips_excpt_isr_036.o mips_excpt_isr_037.o mips_excpt_isr_038.o
+ISROBJS += mips_excpt_isr_039.o mips_excpt_isr_040.o mips_excpt_isr_041.o
+ISROBJS += mips_excpt_isr_042.o mips_excpt_isr_043.o mips_excpt_isr_044.o
+ISROBJS += mips_excpt_isr_045.o mips_excpt_isr_046.o mips_excpt_isr_047.o
+ISROBJS += mips_excpt_isr_048.o mips_excpt_isr_049.o mips_excpt_isr_050.o
+ISROBJS += mips_excpt_isr_051.o mips_excpt_isr_052.o mips_excpt_isr_053.o
+ISROBJS += mips_excpt_isr_054.o mips_excpt_isr_055.o mips_excpt_isr_056.o
+ISROBJS += mips_excpt_isr_057.o mips_excpt_isr_058.o mips_excpt_isr_059.o
+ISROBJS += mips_excpt_isr_060.o mips_excpt_isr_061.o mips_excpt_isr_062.o
+ISROBJS += mips_excpt_isr_063.o mips_excpt_isr_064.o mips_excpt_isr_065.o
+ISROBJS += mips_excpt_isr_066.o mips_excpt_isr_067.o mips_excpt_isr_068.o
+ISROBJS += mips_excpt_isr_069.o mips_excpt_isr_070.o mips_excpt_isr_071.o
+ISROBJS += mips_excpt_isr_072.o mips_excpt_isr_073.o mips_excpt_isr_074.o
+ISROBJS += mips_excpt_isr_075.o mips_excpt_isr_076.o mips_excpt_isr_077.o
+ISROBJS += mips_excpt_isr_078.o mips_excpt_isr_079.o mips_excpt_isr_080.o
+ISROBJS += mips_excpt_isr_081.o mips_excpt_isr_082.o mips_excpt_isr_083.o
+ISROBJS += mips_excpt_isr_084.o mips_excpt_isr_085.o mips_excpt_isr_086.o
+ISROBJS += mips_excpt_isr_087.o mips_excpt_isr_088.o mips_excpt_isr_089.o
+ISROBJS += mips_excpt_isr_090.o mips_excpt_isr_091.o mips_excpt_isr_092.o
+ISROBJS += mips_excpt_isr_093.o mips_excpt_isr_094.o mips_excpt_isr_095.o
+ISROBJS += mips_excpt_isr_096.o mips_excpt_isr_097.o mips_excpt_isr_098.o
+ISROBJS += mips_excpt_isr_099.o mips_excpt_isr_100.o mips_excpt_isr_101.o
+ISROBJS += mips_excpt_isr_102.o mips_excpt_isr_103.o mips_excpt_isr_104.o
+ISROBJS += mips_excpt_isr_105.o mips_excpt_isr_106.o mips_excpt_isr_107.o
+ISROBJS += mips_excpt_isr_108.o mips_excpt_isr_109.o mips_excpt_isr_110.o
+ISROBJS += mips_excpt_isr_111.o mips_excpt_isr_112.o mips_excpt_isr_113.o
+ISROBJS += mips_excpt_isr_114.o mips_excpt_isr_115.o mips_excpt_isr_116.o
+ISROBJS += mips_excpt_isr_117.o mips_excpt_isr_118.o mips_excpt_isr_119.o
+ISROBJS += mips_excpt_isr_120.o mips_excpt_isr_121.o mips_excpt_isr_122.o
+ISROBJS += mips_excpt_isr_123.o mips_excpt_isr_124.o mips_excpt_isr_125.o
+ISROBJS += mips_excpt_isr_126.o mips_excpt_isr_127.o mips_excpt_isr_128.o
+ISROBJS += mips_excpt_isr_129.o mips_excpt_isr_130.o mips_excpt_isr_131.o
+ISROBJS += mips_excpt_isr_132.o mips_excpt_isr_133.o mips_excpt_isr_134.o
+ISROBJS += mips_excpt_isr_135.o mips_excpt_isr_136.o mips_excpt_isr_137.o
+ISROBJS += mips_excpt_isr_138.o mips_excpt_isr_139.o mips_excpt_isr_140.o
+ISROBJS += mips_excpt_isr_141.o mips_excpt_isr_142.o mips_excpt_isr_143.o
+ISROBJS += mips_excpt_isr_144.o mips_excpt_isr_145.o mips_excpt_isr_146.o
+ISROBJS += mips_excpt_isr_147.o mips_excpt_isr_148.o mips_excpt_isr_149.o
+ISROBJS += mips_excpt_isr_150.o mips_excpt_isr_151.o mips_excpt_isr_152.o
+ISROBJS += mips_excpt_isr_153.o mips_excpt_isr_154.o mips_excpt_isr_155.o
+ISROBJS += mips_excpt_isr_156.o mips_excpt_isr_157.o mips_excpt_isr_158.o
+ISROBJS += mips_excpt_isr_159.o mips_excpt_isr_160.o mips_excpt_isr_161.o
+ISROBJS += mips_excpt_isr_162.o mips_excpt_isr_163.o mips_excpt_isr_164.o
+ISROBJS += mips_excpt_isr_165.o mips_excpt_isr_166.o mips_excpt_isr_167.o
+ISROBJS += mips_excpt_isr_168.o mips_excpt_isr_169.o mips_excpt_isr_170.o
+ISROBJS += mips_excpt_isr_171.o mips_excpt_isr_172.o mips_excpt_isr_173.o
+ISROBJS += mips_excpt_isr_174.o mips_excpt_isr_175.o mips_excpt_isr_176.o
+ISROBJS += mips_excpt_isr_177.o mips_excpt_isr_178.o mips_excpt_isr_179.o
+ISROBJS += mips_excpt_isr_180.o mips_excpt_isr_181.o mips_excpt_isr_182.o
+ISROBJS += mips_excpt_isr_183.o mips_excpt_isr_184.o mips_excpt_isr_185.o
+ISROBJS += mips_excpt_isr_186.o mips_excpt_isr_187.o mips_excpt_isr_188.o
+ISROBJS += mips_excpt_isr_189.o mips_excpt_isr_190.o mips_excpt_isr_191.o
+ISROBJS += mips_excpt_isr_192.o mips_excpt_isr_193.o mips_excpt_isr_194.o
+ISROBJS += mips_excpt_isr_195.o mips_excpt_isr_196.o mips_excpt_isr_197.o
+ISROBJS += mips_excpt_isr_198.o mips_excpt_isr_199.o mips_excpt_isr_200.o
+ISROBJS += mips_excpt_isr_201.o mips_excpt_isr_202.o mips_excpt_isr_203.o
+ISROBJS += mips_excpt_isr_204.o mips_excpt_isr_205.o mips_excpt_isr_206.o
+ISROBJS += mips_excpt_isr_207.o mips_excpt_isr_208.o mips_excpt_isr_209.o
+ISROBJS += mips_excpt_isr_210.o mips_excpt_isr_211.o mips_excpt_isr_212.o
+ISROBJS += mips_excpt_isr_213.o mips_excpt_isr_214.o mips_excpt_isr_215.o
+ISROBJS += mips_excpt_isr_216.o mips_excpt_isr_217.o mips_excpt_isr_218.o
+ISROBJS += mips_excpt_isr_219.o mips_excpt_isr_220.o mips_excpt_isr_221.o
+ISROBJS += mips_excpt_isr_222.o mips_excpt_isr_223.o mips_excpt_isr_224.o
+ISROBJS += mips_excpt_isr_225.o mips_excpt_isr_226.o mips_excpt_isr_227.o
+ISROBJS += mips_excpt_isr_228.o mips_excpt_isr_229.o mips_excpt_isr_230.o
+ISROBJS += mips_excpt_isr_231.o mips_excpt_isr_232.o mips_excpt_isr_233.o
+ISROBJS += mips_excpt_isr_234.o mips_excpt_isr_235.o mips_excpt_isr_236.o
+ISROBJS += mips_excpt_isr_237.o mips_excpt_isr_238.o mips_excpt_isr_239.o
+ISROBJS += mips_excpt_isr_240.o mips_excpt_isr_241.o mips_excpt_isr_242.o
+ISROBJS += mips_excpt_isr_243.o mips_excpt_isr_244.o mips_excpt_isr_245.o
+ISROBJS += mips_excpt_isr_246.o mips_excpt_isr_247.o mips_excpt_isr_248.o
+ISROBJS += mips_excpt_isr_249.o mips_excpt_isr_250.o mips_excpt_isr_251.o
+ISROBJS += mips_excpt_isr_252.o mips_excpt_isr_253.o mips_excpt_isr_254.o
+ISROBJS += mips_excpt_isr_255.o
+
+UHIOBJS = uhi_assert.o uhi_close.o uhi_exit.o uhi_fstat.o \
+ uhi_lseek.o uhi_open.o uhi_plog.o \
+ uhi_pread.o uhi_pwrite.o uhi_read.o uhi_link.o uhi_stat.o \
+ uhi_unlink.o uhi_write.o uhi_getargs.o uhi_exception.o \
+ uhi_get_ram_range.o uhi_indirect.o uhi_break.o \
+ syscalls.o getpid.o isatty.o kill.o
+
+YAMONOBJS = yamon_read.o yamon_write.o yamon_exit.o yamon_close.o \
+ yamon_fstat.o yamon_exception.o
+
+HALOBJ = mips_clean_cache.o mips_flush_cache.o mips_l2size.o \
+ mips_lock_cache.o mips_size_cache.o mips_sync_cache.o \
+ mips_fp.o \
+ mips_excpt_entry.o mips_excpt_handler.o mips_excpt_handler_quiet.o \
+ mips_excpt_register.o mips_excpt_boot.o \
+ mips_intctrl.o $(ISROBJS)
+
+HALOBJ += mips_tlb.o
+
+HALOBJ += mips64_tlb.o mips_xpa.o mips_msa.o
+
+BOOTOBJ = reset.o init_cp0.o init_caches.o init_tlb.o init_l23caches.o
+
+CM3OBJ_IMPL = mips_cm3_l2size.o init_cm3l2.o
+
+CM3AR = libcm3.a
+
# Nullmon cannot support read and write, but the test cases pull them in via libs
NULLMONOBJS = nullmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
-CFLAGS = -g
-
GCC_LDFLAGS = `if [ -d ${objroot}/../gcc ] ; \
then echo -L${objroot}/../gcc ; fi`
@@ -93,6 +208,14 @@ PART_SPECIFIC_DEFINES = @MIPS_PART_SPECIFIC_DEFINES@
# Host specific makefile fragment comes in here.
@host_makefile_frag@
+HALCFLAGS += -g \
+ -fdebug-prefix-map=$(srcdir)=$(DESTDIR)$(exec_prefix)/share/mips \
+ -fdebug-prefix-map=$(srcdir)/include=$(DESTDIR)$(exec_prefix)/$(target_alias)/include \
+ -Wa,--debug-prefix-map=$(srcdir)=$(DESTDIR)$(exec_prefix)/share/mips \
+ -Wa,--debug-prefix-map=$(srcdir)/include=$(DESTDIR)$(exec_prefix)/$(target_alias)/include \
+ -Werror
+
+HALCFLAGS += -I $(srcdir)/include
#
# build a test program for each target board. Just trying to get
# it to link is a good test, so we ignore all the errors for now.
@@ -140,6 +263,22 @@ libcfe.a: $(CFEOBJS)
${AR} ${ARFLAGS} $@ $(CFEOBJS)
${RANLIB} $@
+libuhi.a: $(UHIOBJS)
+ ${AR} ${ARFLAGS} $@ $(UHIOBJS)
+ ${RANLIB} $@
+
+libyamon.a: $(YAMONOBJS)
+ ${AR} ${ARFLAGS} $@ $(YAMONOBJS)
+ ${RANLIB} $@
+
+libhal.a: $(HALOBJ) $(BOOTOBJ)
+ ${AR} ${ARFLAGS} $@ $^
+ ${RANLIB} $@
+
+libcm3_impl.a: $(CM3OBJ_IMPL)
+ ${AR} ${ARFLAGS} $@ $^
+ ${RANLIB} $@
+
# nullmon.a , This is what you want if you want crt0 but NO mon services
# Supports GDB sim testing, board bringups, ICE operation.
libnullmon.a: $(NULLMONOBJS)
@@ -191,10 +330,10 @@ cfe-test.dis: cfe-test.x
$(OBJDUMP) -d cfe-test.x > $@
cfe-test: cfe-test.srec cfe-test.dis
-doc:
+doc:
clean mostlyclean:
- rm -f a.out core *.i *~ *.o *-test *.srec *.dis *.map *.x
+ rm -f a.out core *.i *~ *.a *.o *-test *.srec *.dis *.map *.x
distclean maintainer-clean realclean: clean
rm -f Makefile config.status a.out
@@ -205,6 +344,7 @@ install:
@for file in $(CRT0) $(PCRT0) $(BSP); do \
$(INSTALL_DATA) $${file} $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$${file}; \
done
+ $(INSTALL_DATA) ${srcdir}/hal/libcm3.a $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/libcm3.a
@for script in ${SCRIPTS}; do\
$(INSTALL_DATA) ${srcdir}/$${script}.ld $(DESTDIR)$(tooldir)/lib${MULTISUBDIR}/$${script}.ld; \
done
@@ -216,39 +356,43 @@ clean-info:
test.o: ${srcdir}/test.c
# these are for the BSPs
-crt0.o: ${srcdir}/crt0.S
-pcrt0.o: ${srcdir}/crt0.S
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) -DGCRT0 ${srcdir}/crt0.S -o ${PCRT0}
+crt0.o: ${srcdir}/hal/crt0.S
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(CFLAGS) $(INCLUDES) $^ -o $@
+pcrt0.o: ${srcdir}/hal/crt0.S
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(CFLAGS) $(INCLUDES) -DGCRT0 $^ -o ${PCRT0}
crt0_cfe.o: ${srcdir}/crt0_cfe.S
crt0_cygmon.o: ${srcdir}/crt0_cygmon.S
idtmon.o: ${srcdir}/idtmon.S
pmon.o: ${srcdir}/pmon.S
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $(PART_SPECIFIC_DEFINES) ${srcdir}/pmon.S -o pmon.o
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(CFLAGS) $(PART_SPECIFIC_DEFINES) $^ -o $@
vr4300.o: ${srcdir}/vr4300.S
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/vr4300.S
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $^ -o $@
vr5xxx.o: ${srcdir}/vr5xxx.S
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/vr5xxx.S
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $^ -o $@
lsipmon.o: $(srcdir)/lsipmon.S $(srcdir)/pmon.S
+__exit.o: ${srcdir}/hal/__exit.c
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(INCLUDES) $(CFLAGS) $^ -o $@
jmr3904-io.o: ${srcdir}/jmr3904-io.c
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/jmr3904-io.c -o $@
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $^ -o $@
cfe.o: ${srcdir}/cfe.c ${srcdir}/cfe_api.h
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/cfe.c -o $@
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $< -o $@
cfe_api.o: ${srcdir}/cfe_api.c ${srcdir}/cfe_api.h ${srcdir}/cfe_api_int.h
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/cfe_api.c -o $@
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $< -o $@
cfe_mem.o: ${srcdir}/cfe_mem.c ${srcdir}/cfe_api.h
- $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) ${srcdir}/cfe_mem.c -o $@
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(CFLAGS) $< -o $@
# cma101 can not be compiled mips16, if a mips16 version is needed then
# it will have to be built, then this rule can be scrapped, allowing
# the implicit rule to run.
cma101.o: ${srcdir}/cma101.c
- $(CC) -c $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) $(CFLAGS) -mno-mips16 ${srcdir}/cma101.c
+ $(CC) -c $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) $(CFLAGS) -mno-mips16 $^
# cygmon can not be compiled as mips16 since it uses the syscall instruction
cygmon.o: ${srcdir}/cygmon.c
- $(CC) -c $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) $(CFLAGS) -mno-mips16 ${srcdir}/cygmon.c
+ $(CC) -c $(CFLAGS_FOR_TARGET) -O2 $(HALCFLAGS) $(INCLUDES) $(CFLAGS) -mno-mips16 $^
-syscalls.o: ${srcdir}/syscalls.c
+syscalls.o: ${srcdir}/hal/syscalls.c
+ $(CC) -c $(CFLAGS_FOR_TARGET) $(HALCFLAGS) $(INCLUDES) $(CFLAGS) $< -o $@
# target specific makefile fragment comes in here.
@target_makefile_frag@
diff --git a/libgloss/mips/acinclude.m4 b/libgloss/mips/acinclude.m4
index 6061d8dd1..cda8d77e2 100644
--- a/libgloss/mips/acinclude.m4
+++ b/libgloss/mips/acinclude.m4
@@ -9,18 +9,16 @@ case "${target}" in
MIPS_SCRIPT_LIST="dve idt jmr3904app jmr3904dram jmr3904dram-java jmr3904app-java sde32 sde64 mti32 mti64 mti64_n32 mti64_64"
MIPS_BSP_LIST="libdve.a libidt.a libjmr3904.a"
;;
- mipsisa32-*-* | mipsisa32el-*-* | \
- mipsisa32r2-*-* | mipsisa32r2el-*-* | \
- mipsisa64*-*-*)
- MIPS_CRT0="crt0_cfe.o crt0_cygmon.o crt0.o"
- MIPS_SCRIPT_LIST="idt32 idt64 cfe"
- MIPS_BSP_LIST="libcygmon.a libidt.a libcfe.a"
- ;;
mips*-lsi*-*)
MIPS_PART_SPECIFIC_OBJ="entry.o"
MIPS_SCRIPT_LIST="lsi"
MIPS_BSP_LIST=liblsi.a
;;
+ mips*-mti*-* | mips*-img*-*)
+ MIPS_CRT0="crt0.o"
+ MIPS_SCRIPT_LIST="idt nullmon mti32 mti64_n32 mti64_64 uhi32 uhi64_64 uhi64_n32 malta32-yamon bootcode"
+ MIPS_BSP_LIST="libidt.a libnullmon.a libuhi.a libyamon.a libhal.a libcm3_impl.a"
+ ;;
mips64vr5*-*-*)
MIPS_PART_SPECIFIC_OBJ="vr5xxx.o cma101.o"
MIPS_PART_SPECIFIC_DEFINES=-DR5000
@@ -32,6 +30,13 @@ case "${target}" in
MIPS_SCRIPT_LIST="ddb ddb-kseg0 nullmon"
MIPS_BSP_LIST="libpmon.a libnullmon.a"
;;
+ mipsisa32-*-* | mipsisa32el-*-* | \
+ mipsisa32r2-*-* | mipsisa32r2el-*-* | \
+ mipsisa64*-*-*)
+ MIPS_CRT0="crt0_cfe.o crt0_cygmon.o crt0.o"
+ MIPS_SCRIPT_LIST="idt32 idt64 cfe"
+ MIPS_BSP_LIST="libcygmon.a libidt.a libcfe.a"
+ ;;
mips*)
MIPS_CRT0="crt0_cfe.o crt0.o"
MIPS_PART_SPECIFIC_OBJ="vr4300.o cma101.o"
diff --git a/libgloss/mips/boot/corecheck_predef.S b/libgloss/mips/boot/corecheck_predef.S
new file mode 100644
index 000000000..62f1b2cc3
--- /dev/null
+++ b/libgloss/mips/boot/corecheck_predef.S
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2015-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _RESETCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/cm3.h>
+#include "predef.h"
+
+MIPS_NOMIPS16
+
+/* Config 0 has some RO fields. */
+#if defined (C0_CONFIG0_VALUE)
+#define C0_CONFIG0_RO (CFG0_M | CFG0_AT_MASK | CFG0_AR_MASK | \
+ CFG0_MT_MASK | CFG0_VI)
+#define C0_CONFIG0_EXP (C0_CONFIG0_RO & C0_CONFIG0_VALUE)
+#endif
+
+/* Config 1 has no RW fields. */
+#if defined(C0_CONFIG1_VALUE)
+#define C0_CONFIG1_RO (0xffffffff)
+#define C0_CONFIG1_EXP (C0_CONFIG1_RO & C0_CONFIG1_VALUE)
+#endif
+
+/* Config 2 has 2 RW fields. */
+#if defined(C0_CONFIG2_VALUE)
+#define C0_CONFIG2_RO ~(CFG2_TU_MASK | CFG2_SU_MASK)
+#define C0_CONFIG2_EXP (C0_CONFIG2_RO & C0_CONFIG2_VALUE)
+#endif
+
+/* Config 3 has only 1 R/W bit (microMIPS on exception) */
+#if defined(C0_CONFIG3_VALUE)
+#define C0_CONFIG3_RO (~CFG3_IOE)
+#define C0_CONFIG3_EXP (C0_CONFIG3_RO & C0_CONFIG3_VALUE)
+#endif
+
+
+/* Config 4 has only 1 field R/W (FTLB page size) */
+#if defined(C0_CONFIG4_VALUE)
+#define C0_CONFIG4_RO (~CFG4_FTLBPS_MASK)
+#define C0_CONFIG4_EXP (C0_CONFIG4_RO & C0_CONFIG4_VALUE)
+#endif
+
+/* Config 5 has only a few fields and some of them are RO. */
+#if defined(C0_CONFIG5_VALUE)
+#define C0_CONFIG5_RO (CFG5_MVH | CFG5_LLB | CFG5_MRP | CFG5_NF)
+#define C0_CONFIG5_EXP (C0_CONFIG5_RO & C0_CONFIG5_VALUE)
+#endif
+
+#if defined(C0_CMGCRBASE_VALUE)
+#define C0_CMGCRBASE_ADDR ((C0_CMGCRBASE_VALUE << 4) | (0xb << 28))
+#define C0_CMGCRBASE_RO (0xffffffff)
+#define C0_CMGCRBASE_EXP C0_CMGCRBASE_VALUE
+#endif
+
+/* GCR L2 config has REG_EXISTS and L2 config as readonly nozero fields. */
+#if defined(GCR_L2_CONFIG)
+#define GCR_L2_CONFIG_RO ((1<<31) | ((1<<16) - 1))
+#define GCR_L2_CONFIG_EXP GCR_L2_CONFIG_VALUE
+#endif
+
+LEAF(__core_check)
+ /*
+ * Compare the expected value to the RO fields
+ * of the config register
+ */
+#if defined(C0_CONFIG0_VALUE)
+ li t0, C0_CONFIG0_EXP
+ li t1, C0_CONFIG0_RO
+ mfc0 t3, C0_CONFIG
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+
+#if defined(C0_CONFIG1_VALUE)
+ li t0, C0_CONFIG1_EXP
+ li t1, C0_CONFIG1_RO
+ mfc0 t3, C0_CONFIG1
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+
+#if defined(C0_CONFIG2_VALUE)
+ li t0, C0_CONFIG2_EXP
+ li t1, C0_CONFIG2_RO
+ mfc0 t3, C0_CONFIG2
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+
+#if defined(C0_CONFIG3_VALUE)
+ li t0, C0_CONFIG3_EXP
+ li t1, C0_CONFIG3_RO
+ mfc0 t3, C0_CONFIG3
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+
+#if defined(C0_CONFIG4_VALUE)
+ li t0, C0_CONFIG4_EXP
+ li t1, C0_CONFIG4_RO
+ mfc0 t3, C0_CONFIG4
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+
+#if defined(C0_CONFIG5_VALUE)
+ li t0, C0_CONFIG5_EXP
+ li t1, C0_CONFIG5_RO
+ mfc0 t3, C0_CONFIG5
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+
+#if defined(C0_CMGCRBASE_VALUE)
+ li t0, C0_CMGCRBASE_EXP
+ li t1, C0_CMGCRBASE_RO
+ mfc0 t3, C0_CMGCRBASE
+ and t2, t1, t3
+ bne t2, t0, 1f
+#if defined(GCR_L2_CONFIG_VALUE)
+ li t0, GCR_L2_CONFIG_EXP
+ li t1, GCR_L2_CONFIG_RO
+ li t2, C0_CMGCRBASE_ADDR
+ lw t3, GCR_L2_CONFIG(t2)
+ and t2, t1, t3
+ bne t2, t0, 1f
+#endif
+#endif
+
+#if defined(C0_WATCHHI_VALUE)
+ mfc0 t0, C0_WATCHHI, 0
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+#if defined(C0_WATCHHI1_VALUE)
+ mfc0 t0, C0_WATCHHI, 1
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI1_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+#if defined(C0_WATCHHI2_VALUE)
+ mfc0 t0, C0_WATCHHI, 2
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI2_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+#if defined(C0_WATCHHI3_VALUE)
+ mfc0 t0, C0_WATCHHI, 3
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI3_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+#if defined(C0_WATCHHI4_VALUE)
+ mfc0 t0, C0_WATCHHI, 4
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI4_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+#if defined(C0_WATCHHI5_VALUE)
+ mfc0 t0, C0_WATCHHI, 5
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI5_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+#if defined(C0_WATCHHI6_VALUE)
+ mfc0 t0, C0_WATCHHI, 6
+ ext t0, t0, WATCHHI_M_SHIFT, 1
+
+ li t1, ((C0_WATCHHI6_VALUE & WATCHHI_M) >> WATCHHI_M_SHIFT)
+ bne t0, t1, 1f
+#endif
+
+ b 2f
+1:
+ /* Incorrect config supplied, report a boot failure through UHI */
+ li t9, 23
+ /* Reason - Predef config incorrect */
+ li a0, 2
+ /* Trigger the UHI operation */
+ sdbbp 1
+ /* In case a debugger corrects this failure */
+
+2:
+ jr ra
+
+END(__core_check)
diff --git a/libgloss/mips/boot/init_caches.S b/libgloss/mips/boot/init_caches.S
new file mode 100644
index 000000000..fb5ef11ab
--- /dev/null
+++ b/libgloss/mips/boot/init_caches.S
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+MIPS_NOMIPS16
+
+#define LINE_SIZE vt0
+#define SET_SIZE vt1
+#define ASSOC a0
+#define TOTAL_BYTES a1
+#define CURR_ADDR1 a2
+#define CURR_ADDR2 a3
+#define END_ADDR t0
+#define CONFIG t1
+#define CONFIG1 t2
+#define TEMP t3
+
+ .set noat
+
+/*
+ * init_icache invalidates all instruction cache entries
+ */
+
+LEAF(__init_icache)
+ mfc0 CONFIG1, C0_CONFIG1
+
+ ext LINE_SIZE, CONFIG1, CFG1_IL_SHIFT, 3
+
+ /* Skip ahead if No I$ */
+ li TEMP, 2
+ beqz LINE_SIZE, $Ldone_icache
+ sllv LINE_SIZE, TEMP, LINE_SIZE /* Now have true I$ line size in bytes */
+
+ ext SET_SIZE, CONFIG1, CFG1_IS_SHIFT, 3
+ addiu SET_SIZE, SET_SIZE, 1 /* Rotate to account for 7 == 32 sets */
+ andi SET_SIZE, SET_SIZE, 7 /* Mask down to 3-bit */
+ li TEMP, 32
+ sllv SET_SIZE, TEMP, SET_SIZE /* I$ Sets per way */
+
+ // Config1IA == I$ Assoc - 1
+ ext ASSOC, CONFIG1, CFG1_IA_SHIFT, 3
+ addiu ASSOC, ASSOC, 1
+
+ mul SET_SIZE, SET_SIZE, ASSOC /* Total number of sets */
+ mul TOTAL_BYTES, SET_SIZE, LINE_SIZE /* Total number of bytes */
+
+ li CURR_ADDR2, 0x80000000 /* Get a KSeg0 address for cacheops */
+ subu CURR_ADDR2, CURR_ADDR2, LINE_SIZE /* Pre-bias the addresses as the loop */
+ subu CURR_ADDR1, CURR_ADDR2, LINE_SIZE /* increments them first */
+
+ addu END_ADDR, CURR_ADDR1, TOTAL_BYTES /* END_ADDR is last line to invalidate */
+ sll LINE_SIZE, LINE_SIZE, 1 /* Double line size as we process two */
+ /* per loop */
+
+ /* Clear TagLo/TagHi registers */
+ mtc0 zero, C0_TAGLO
+ mtc0 zero, C0_TAGHI
+
+$Lnext_icache_tag:
+ /*
+ * Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+ addu CURR_ADDR1, LINE_SIZE
+ addu CURR_ADDR2, LINE_SIZE
+ cache Index_Store_Tag_I, 0(CURR_ADDR1)
+ cache Index_Store_Tag_I, 0(CURR_ADDR2)
+ bne CURR_ADDR1, END_ADDR, $Lnext_icache_tag
+
+$Ldone_icache:
+ jr ra
+END(__init_icache)
+
+/*
+ * init_dcache invalidates all data cache entries
+ */
+
+LEAF(__init_dcache)
+ mfc0 CONFIG1, C0_CONFIG1
+ ext LINE_SIZE, CONFIG1, CFG1_DL_SHIFT, 3
+
+ /* Skip ahead if No D$ */
+ li TEMP, 2
+ beqz LINE_SIZE, $Ldone_dcache
+
+ sllv LINE_SIZE, TEMP, LINE_SIZE /* Now have true D$ line size in bytes */
+
+ ext SET_SIZE, CONFIG1, CFG1_DS_SHIFT, 3
+ addiu SET_SIZE, SET_SIZE, 1 /* Rotate to account for 7 == 32 sets */
+ andi SET_SIZE, SET_SIZE, 7 /* Mask down to 3-bit */
+ li TEMP, 32
+ sllv SET_SIZE, TEMP, SET_SIZE /* D$ Sets per way */
+
+ /* Config1.DA == D$ Assoc - 1 */
+ ext ASSOC, CONFIG1, CFG1_DA_SHIFT, 3
+ addiu ASSOC, 1
+
+ mul SET_SIZE, SET_SIZE, ASSOC /* Get total number of sets */
+ mul TOTAL_BYTES, SET_SIZE, LINE_SIZE /* Total number of bytes */
+
+ li CURR_ADDR2, 0x80000000 /* Get a KSeg0 address for cacheops */
+ subu CURR_ADDR2, CURR_ADDR2, LINE_SIZE /* Pre-bias the addresses as the loop */
+ subu CURR_ADDR1, CURR_ADDR2, LINE_SIZE /* increments them first */
+
+ addu END_ADDR, CURR_ADDR1, TOTAL_BYTES /* END_ADDR is last line to invalidate */
+ sll LINE_SIZE, LINE_SIZE, 1 /* Double line size as we process two */
+ /* per loop*/
+
+ /* Clear TagLo/TagHi registers */
+ mtc0 zero, C0_TAGLO
+ mtc0 zero, C0_TAGHI
+ mtc0 zero, C0_TAGLO, 2
+ mtc0 zero, C0_TAGHI, 2
+
+$Lnext_dcache_tag:
+ /*
+ * Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+ addu CURR_ADDR1, LINE_SIZE
+ addu CURR_ADDR2, LINE_SIZE
+ cache Index_Store_Tag_D, 0(CURR_ADDR1)
+ cache Index_Store_Tag_D, 0(CURR_ADDR2)
+ bne CURR_ADDR1, END_ADDR, $Lnext_dcache_tag
+
+$Ldone_dcache:
+ jr ra
+
+END(__init_dcache)
+
+/*
+ * __change_k0_cca essentially turns the cache on
+ */
+
+LEAF(__change_k0_cca)
+ /*
+ * NOTE! This code must be executed in KSEG1 (not KSEG0 uncached)
+ * Set CCA for kseg0 to cacheable
+ */
+ mfc0 CONFIG, C0_CONFIG
+ li TEMP, CFG_C_NONCOHERENT
+
+$Lset_kseg0_cca:
+ ins CONFIG, TEMP, 0, 3
+ mtc0 CONFIG, C0_CONFIG
+ MIPS_JRHB (ra)
+
+END(__change_k0_cca)
diff --git a/libgloss/mips/boot/init_caches_predef.S b/libgloss/mips/boot/init_caches_predef.S
new file mode 100644
index 000000000..27e82b096
--- /dev/null
+++ b/libgloss/mips/boot/init_caches_predef.S
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include "predef.h"
+
+MIPS_NOMIPS16
+
+/*
+ * Depending on the range of the displacement field of the CACHE instruction
+ * we can do multiple cacheops per iteration. With a cache present there
+ * is a guarantee of 32 lines minimum so a power of 2 less than or equal
+ * to 32 means there is no remainder after the loop.
+ * The maximum number of lines per iteration is the range of the CACHE
+ * displacement divided by the line_size. We cap this at 8 as a sensible
+ * bound.
+ */
+
+#if __mips_isa_rev < 6
+/* MicroMIPS Release 3 has a 12-bit displacement for CACHE */
+# define ILINES_PER_ITER 8
+# define DLINES_PER_ITER 8
+#else
+/* MIPS Release 6 has a 9-bit signed displacement for CACHE */
+#if ILINE_SIZE == 128
+# define ILINES_PER_ITER 4 /* Requires both positive and negative disp */
+#else
+# define ILINES_PER_ITER 8
+#endif
+#if DLINE_SIZE == 128
+# define DLINES_PER_ITER 4 /* Requires both positive and negative disp */
+#else
+# define DLINES_PER_ITER 8
+#endif
+#endif
+
+/*
+ * Start off pointing to one block below where we want to invalidate the cache
+ * as the pointer is moved on at the start of the loop. Also offset the start
+ * address for each set of cache lines so that the positive and negative
+ * displacements from the CACHE ops can be used.
+ */
+
+#define ICACHE_START (0x80000000 - (ILINE_SIZE * ILINES_PER_ITER / 2))
+#define ICACHE_END (0x80000000 + ITOTAL_BYTES - (ILINE_SIZE * ILINES_PER_ITER / 2))
+#define DCACHE_START (0x80000000 - (DLINE_SIZE * DLINES_PER_ITER / 2))
+#define DCACHE_END (0x80000000 + DTOTAL_BYTES - (DLINE_SIZE * DLINES_PER_ITER / 2))
+
+#define CURRENT_ADDR a0
+#define END_ADDR a1
+#define CONFIG a2
+#define TEMP a3
+
+ .set noat
+
+/*
+ * init_icache invalidates all instruction cache entries
+ */
+#if defined(ILINE_ENC) && ILINE_ENC != 0
+LEAF(__init_icache)
+ /* Use KSEG0 base address */
+ li CURRENT_ADDR, ICACHE_START
+ /* Get the address of the last batch of lines */
+ li END_ADDR, ICACHE_END
+
+ /* Clear TagLo/TagHi registers */
+ mtc0 zero, C0_TAGLO
+ mtc0 zero, C0_TAGHI
+
+ /*
+ * Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+$Lnext_icache_tag:
+ addu CURRENT_ADDR, (ILINE_SIZE * ILINES_PER_ITER)
+ cache Index_Store_Tag_I, (ILINE_SIZE*-2)(CURRENT_ADDR)
+ cache Index_Store_Tag_I, (ILINE_SIZE*-1)(CURRENT_ADDR)
+ cache Index_Store_Tag_I, (ILINE_SIZE*0)(CURRENT_ADDR)
+ cache Index_Store_Tag_I, (ILINE_SIZE*1)(CURRENT_ADDR)
+#if ILINES_PER_ITER == 8
+ cache Index_Store_Tag_I, (ILINE_SIZE*-4)(CURRENT_ADDR)
+ cache Index_Store_Tag_I, (ILINE_SIZE*-3)(CURRENT_ADDR)
+ cache Index_Store_Tag_I, (ILINE_SIZE*2)(CURRENT_ADDR)
+ cache Index_Store_Tag_I, (ILINE_SIZE*3)(CURRENT_ADDR)
+#endif
+ bne CURRENT_ADDR, END_ADDR, $Lnext_icache_tag
+
+$Ldone_icache:
+ jr ra
+END(__init_icache)
+
+#endif // ILINE_ENC != 0
+
+/*
+ * init_dcache invalidates all data cache entries
+ */
+
+#if defined(DLINE_ENC) && DLINE_ENC != 0
+LEAF(__init_dcache)
+ /* Use KSEG0 base address */
+ li CURRENT_ADDR, DCACHE_START
+ /* Get the address of the last batch of lines */
+ li END_ADDR, DCACHE_END
+
+ /* Clear TagLo/TagHi registers */
+ mtc0 zero, C0_TAGLO
+ mtc0 zero, C0_TAGHI
+ mtc0 zero, C0_TAGLO, 2
+ mtc0 zero, C0_TAGHI, 2
+
+ /*
+ * Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+$Lnext_dcache_tag:
+ addu CURRENT_ADDR, (DLINE_SIZE * DLINES_PER_ITER)
+ cache Index_Store_Tag_D, (DLINE_SIZE*-2)(CURRENT_ADDR)
+ cache Index_Store_Tag_D, (DLINE_SIZE*-1)(CURRENT_ADDR)
+ cache Index_Store_Tag_D, (DLINE_SIZE*0)(CURRENT_ADDR)
+ cache Index_Store_Tag_D, (DLINE_SIZE*1)(CURRENT_ADDR)
+#if DLINES_PER_ITER == 8
+ cache Index_Store_Tag_D, (DLINE_SIZE*-4)(CURRENT_ADDR)
+ cache Index_Store_Tag_D, (DLINE_SIZE*-3)(CURRENT_ADDR)
+ cache Index_Store_Tag_D, (DLINE_SIZE*2)(CURRENT_ADDR)
+ cache Index_Store_Tag_D, (DLINE_SIZE*3)(CURRENT_ADDR)
+#endif
+ bne CURRENT_ADDR, END_ADDR, $Lnext_dcache_tag
+
+$Ldone_dcache:
+ jr ra
+
+END(__init_dcache)
+#endif // DLINE_ENC != 0
+
+/*
+ * __change_k0_cca essentially turns the cache on
+ */
+
+#if ILINE_ENC != 0 || DLINE_ENC != 0
+LEAF(__change_k0_cca)
+ /*
+ * NOTE! This code must be executed in KSEG1 (not KSEG0 uncached)
+ * Set CCA for kseg0 to cacheable
+ */
+ mfc0 CONFIG, C0_CONFIG
+ li TEMP, CFG_C_NONCOHERENT
+
+$Lset_kseg0_cca:
+ ins CONFIG, TEMP, 0, 3
+ mtc0 CONFIG, C0_CONFIG
+ MIPS_JRHB (ra)
+
+END(__change_k0_cca)
+#endif // ILINE_ENC != 0 || DLINE_ENC != 0
diff --git a/libgloss/mips/boot/init_cm3l2.S b/libgloss/mips/boot/init_cm3l2.S
new file mode 100644
index 000000000..2efbbe61e
--- /dev/null
+++ b/libgloss/mips/boot/init_cm3l2.S
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/cm3.h>
+
+MIPS_NOMIPS16
+
+#define CM3_BASE t8
+LEAF(__init_l23cache)
+ /* Check for memory mapped L2 cache config */
+ mfc0 t0, C0_CONFIG3
+ ext t1, t0, CFG3_M_SHIFT, 1
+ beqz t1, err
+
+ mfc0 t0, C0_CONFIG4
+ ext t1, t0, CFG4_M_SHIFT, 1
+ beqz t1, err
+
+ mfc0 t0, C0_CONFIG5
+ ext t1, t0, CFG5_L2C_SHIFT, 1
+ bnez t1, disable_cache
+err:
+ /*
+ * CM3 L2 code supplied but we have a Config2 L2 setup
+ * Report a Boot failure through UHI
+ */
+ li t9, 23
+ /* Reason - L2 cache config */
+ li a0, 1
+ /* Trigger the UHI operation */
+ sdbbp 1
+ /* In case a debugger corrects this failure */
+ jr ra
+
+disable_cache:
+ /* Read CMGCRBase to find CMGCR_BASE_ADDR */
+ PTR_MFC0 t1,C0_CMGCRBASE
+ sll t1, t1, CMGCR_BASE_ADDR_LSHIFT
+ li CM3_BASE, 0xb0000000 /* Make it virtual */
+ or CM3_BASE, CM3_BASE, t1
+
+ /* Disable L2 cache by setting it to bypass mode */
+ PTR_L t0, GCR_L2_CONFIG(CM3_BASE)
+ li a2, 1
+ ins t0, a2, GCR_L2_BYPASS_SHIFT, GCR_L2_BYPASS_BITS
+ PTR_S t0, GCR_L2_CONFIG(CM3_BASE)
+ret:
+ jr ra
+END(__init_l23cache)
+
+LEAF(__init_l23cache_cached)
+ /* Read CMGCRBase to find CMGCR_BASE_ADDR */
+ PTR_MFC0 t3,C0_CMGCRBASE
+ sll t3, t3, CMGCR_BASE_ADDR_LSHIFT
+ li CM3_BASE, 0xb0000000 /* Make it virtual */
+ or CM3_BASE, CM3_BASE, t3
+
+ /* Read GCR_L2_CONFIG */
+ PTR_L t2, GCR_L2_CONFIG(CM3_BASE)
+ ext t3, t2, GCR_L2_SL_SHIFT, GCR_L2_SL_BITS
+ beqz t3, done_cm3l2cache # No L2 cache
+
+ /* Unusual case, hardware cache initialization support & init finished. */
+ PTR_L t1, GCR_L2_RAM_CONFIG(CM3_BASE)
+ ext t0, t1, GCR_L2_RAM_HCIS_SHIFT, (GCR_L2_RAM_HCID_BITS +\
+ GCR_L2_RAM_HCIS_BITS)
+ li t1, 3
+ beq t0, t1, done_cm3l2cache
+
+ li a2, 2
+ sllv a1, a2, t3 /* Now have L2 line size */
+
+ ext a0, t2, GCR_L2_SS_SHIFT, GCR_L2_SS_BITS
+ li a2, 64
+ sllv a0, a2, a0 /* Now have L2 sets/way */
+
+ ext t3, t2, GCR_L2_SA_SHIFT, GCR_L2_SA_BITS
+ addiu t3, t3, 1 /* Set associativity */
+ mul a0, t3, a0 /* Get total number of sets */
+
+ sw zero, GCR_TAG_ADDR(CM3_BASE)
+ sw zero, (GCR_TAG_ADDR+4)(CM3_BASE)
+ sw zero, GCR_TAG_STATE(CM3_BASE)
+ sw zero, (GCR_TAG_STATE+4)(CM3_BASE)
+ sw zero, GCR_TAG_DATA(CM3_BASE)
+ sw zero, (GCR_TAG_DATA+4)(CM3_BASE)
+ sw zero, GCR_TAG_ECC(CM3_BASE)
+ sw zero, (GCR_TAG_ECC+4)(CM3_BASE)
+ sync
+
+ /* Reg exists, L2 cache does TAG/DATA ECC. */
+ li t0, 0x8000FFFF
+ and t2, t2, t0
+ /* LRU is updated on store tag operation */
+ li t0, (1<<GCR_L2_LRU_WE_SHIFT)
+ or t2, t2, t0
+ sw t2, GCR_L2_CONFIG(CM3_BASE)
+ sync
+
+ li a2, 0x80000000
+
+next_cm3l2cache_tag:
+ cache Index_Store_Tag_S, 0(a2)
+ addiu a0, a0, -1
+ addu a2, a2, a1
+ bnez a0, next_cm3l2cache_tag
+
+done_cm3l2cache:
+ move a2, zero
+ PTR_L t0, GCR_L2_CONFIG(CM3_BASE)
+ ins t0, a2, GCR_L2_BYPASS_SHIFT, GCR_L2_BYPASS_BITS
+ PTR_S t0, GCR_L2_CONFIG(CM3_BASE)
+
+ jr ra
+END(__init_l23cache_cached)
diff --git a/libgloss/mips/boot/init_cm3l2_predef.S b/libgloss/mips/boot/init_cm3l2_predef.S
new file mode 100644
index 000000000..c8e1d5e3e
--- /dev/null
+++ b/libgloss/mips/boot/init_cm3l2_predef.S
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2015-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/cm3.h>
+#include "predef.h"
+
+MIPS_NOMIPS16
+
+#define CM3_BASE a3
+
+# ifndef C0_CMGCRBASE_VALUE
+# error "Static CM3 cache initialization decisions require C0_CMGCRBASE_VALUE"
+# else
+# define C0_CMGCRBASE_ADDR ((C0_CMGCRBASE_VALUE << 4) | (0xb << 28))
+# ifndef GCR_L2_CONFIG_VALUE
+# error "Static CM3 cache initialization decisions require GCR_L2_CONFIG_VALUE"
+# endif
+# endif
+
+#undef SLINE_ENC
+#undef SSET_ENC
+#undef SASSOC_ENC
+#undef SLINE_SIZE
+#undef SSET_SIZE
+#undef SASSOC
+
+#define SLINE_ENC ((GCR_L2_CONFIG_VALUE & GCR_L2_SL_MASK) >> GCRL2_CFG_SL_SHIFT)
+#define SSET_ENC ((GCR_L2_CONFIG_VALUE & GCR_L2_SS_MASK) >> GCRL2_CFG_SS_SHIFT)
+#define SASSOC_ENC ((GCR_L2_CONFIG_VALUE & GCR_L2_SA_MASK) >> GCRL2_CFG_SA_SHIFT)
+#define SLINE_SIZE (2 << SLINE_ENC)
+#define SSET_SIZE (64 << SSET_ENC)
+#define SASSOC (SASSOC_ENC + 1)
+
+
+LEAF(__init_l23cache)
+ li CM3_BASE, C0_CMGCRBASE_ADDR
+ /* Disable L2 cache */
+ PTR_L t0, GCR_L2_CONFIG(CM3_BASE)
+ li a2, 1
+ ins t0, a2, GCR_L2_BYPASS_SHIFT, GCR_L2_BYPASS_BITS
+ PTR_S t0, GCR_L2_CONFIG(CM3_BASE)
+
+ jr ra
+END(__init_l23cache)
+
+LEAF(__init_l23cache_cached)
+ li CM3_BASE, C0_CMGCRBASE_ADDR
+
+#if SLINE_ENC != 0
+ /* Unusual case, hardware cache initialization support & init finished. */
+ PTR_L t1, GCR_L2_RAM_CONFIG(CM3_BASE)
+ ext t0, t1, GCR_L2_RAM_HCIS_SHIFT, (GCR_L2_RAM_HCID_BITS +\
+ GCR_L2_RAM_HCIS_BITS)
+ li t1, 3
+ beq t0, t1, done_cm3l2cache
+
+ /* Compute L2 cache size */
+ li a1, SLINE_SIZE
+ li a0, SSET_SIZE * SASSOC
+
+ sw zero, GCR_TAG_ADDR(CM3_BASE)
+ sw zero, (GCR_TAG_ADDR+4)(CM3_BASE)
+ sw zero, GCR_TAG_STATE(CM3_BASE)
+ sw zero, (GCR_TAG_STATE+4)(CM3_BASE)
+ sw zero, GCR_TAG_DATA(CM3_BASE)
+ sw zero, (GCR_TAG_DATA+4)(CM3_BASE)
+ sw zero, GCR_TAG_ECC(CM3_BASE)
+ sw zero, (GCR_TAG_ECC+4)(CM3_BASE)
+
+ /* Reg exists, L2 cache does TAG/DATA ECC. */
+ li t1, (GCR_L2_CONFIG_VALUE & 0x8000FFFF)
+ /* LRU is updated on store tag operation */
+ li t0, (1<<GCR_L2_LRU_WE_SHIFT)
+ or t1, t1, t0
+ sw t1, GCR_L2_CONFIG(CM3_BASE)
+ sync
+
+ lui a2, 0x8000
+next_cm3l2cache_tag:
+ cache Index_Store_Tag_S, 0(a2)
+ addiu a0, a0, -1
+ addu a2, a2, a1
+ bnez a0, next_cm3l2cache_tag
+#endif /* SLINE_ENC != 0 */
+
+done_cm3l2cache:
+ move a2, zero
+ PTR_L t0, GCR_L2_CONFIG(CM3_BASE)
+ ins t0, a2, GCR_L2_BYPASS_SHIFT, GCR_L2_BYPASS_BITS
+ PTR_S t0, GCR_L2_CONFIG(CM3_BASE)
+
+ jr ra
+END(__init_l23cache_cached)
diff --git a/libgloss/mips/boot/init_cp0.S b/libgloss/mips/boot/init_cp0.S
new file mode 100644
index 000000000..15ac1c804
--- /dev/null
+++ b/libgloss/mips/boot/init_cp0.S
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+MIPS_NOMIPS16
+
+ .set noat
+
+LEAF(__init_cp0)
+
+ /* Initialize Status */
+ li t1, SR_ERL | SR_BEV
+ mtc0 t1, C0_STATUS
+
+ /* Initialize Watch registers if implemented */
+ mfc0 t0, C0_CONFIG1
+ ext t1, t0, CFG1_WR_SHIFT, 1
+ beqz t1, $Ldone_wr
+ li t1, WATCHHI_I | WATCHHI_R | WATCHHI_W
+
+ /* Clear Watch Status bits and disable watch exceptions */
+ mtc0 t1, C0_WATCHHI
+ mfc0 t0, C0_WATCHHI
+ mtc0 zero, C0_WATCHLO
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 1
+ mfc0 t0, C0_WATCHHI, 1
+ mtc0 zero, C0_WATCHLO, 1
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 2
+ mfc0 t0, C0_WATCHHI, 2
+ mtc0 zero, C0_WATCHLO, 2
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 3
+ mfc0 t0, C0_WATCHHI, 3
+ mtc0 zero, C0_WATCHLO, 3
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 4
+ mfc0 t0, C0_WATCHHI, 4
+ mtc0 zero, C0_WATCHLO, 4
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 5
+ mfc0 t0, C0_WATCHHI, 5
+ mtc0 zero, C0_WATCHLO, 5
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 6
+ mfc0 t0, C0_WATCHHI, 6
+ mtc0 zero, C0_WATCHLO, 6
+ bgez t0, $Ldone_wr
+
+ mtc0 t1, C0_WATCHHI, 7
+ mfc0 t0, C0_WATCHHI, 7
+ mtc0 zero, C0_WATCHLO, 7
+
+$Ldone_wr:
+ /*
+ * Clear WP bit to avoid watch exception upon user code entry, IV,
+ * and software interrupts.
+ */
+ mtc0 zero, C0_CAUSE
+
+ /*
+ * Clear timer interrupt. (Count was cleared at the reset vector to
+ * allow timing boot.)
+ */
+ mtc0 zero, C0_COMPARE
+
+ jr ra
+END(__init_cp0)
diff --git a/libgloss/mips/boot/init_cp0_predef.S b/libgloss/mips/boot/init_cp0_predef.S
new file mode 100644
index 000000000..abc1888fe
--- /dev/null
+++ b/libgloss/mips/boot/init_cp0_predef.S
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include "predef.h"
+
+MIPS_NOMIPS16
+
+ .set noat
+
+LEAF(__init_cp0)
+
+ /* Initialize Status */
+ li t1, SR_BEV | SR_ERL
+ mtc0 t1, C0_STATUS
+
+#if (C0_CONFIG1_VALUE & CFG1_WR) != 0
+ li t1, WATCHHI_I | WATCHHI_R | WATCHHI_W
+
+ /* Clear Watch Status bits and disable watch exceptions */
+ mtc0 t1, C0_WATCHHI
+ mtc0 zero, C0_WATCHLO
+
+# ifndef C0_WATCHHI_VALUE
+# error "C0_WATCHHI_VALUE is required"
+# endif
+
+# if (C0_WATCHHI_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 1
+ mtc0 zero, C0_WATCHLO, 1
+
+# ifndef C0_WATCHHI1_VALUE
+# error "C0_WATCHHI1_VALUE is required"
+# endif
+
+# if (C0_WATCHHI1_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 2
+ mtc0 zero, C0_WATCHLO, 2
+
+# ifndef C0_WATCHHI2_VALUE
+# error "C0_WATCHHI2_VALUE is required"
+# endif
+
+# if (C0_WATCHHI2_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 3
+ mtc0 zero, C0_WATCHLO, 3
+
+# ifndef C0_WATCHHI3_VALUE
+# error "C0_WATCHHI3_VALUE is required"
+# endif
+
+# if (C0_WATCHHI3_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 4
+ mtc0 zero, C0_WATCHLO, 4
+
+# ifndef C0_WATCHHI4_VALUE
+# error "C0_WATCHHI4_VALUE is required"
+# endif
+
+# if (C0_WATCHHI4_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 5
+ mtc0 zero, C0_WATCHLO, 5
+
+# ifndef C0_WATCHHI5_VALUE
+# error "C0_WATCHHI5_VALUE is required"
+# endif
+
+# if (C0_WATCHHI5_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 6
+ mtc0 zero, C0_WATCHLO, 6
+
+# ifndef C0_WATCHHI6_VALUE
+# error "C0_WATCHHI6_VALUE is required"
+# endif
+
+# if (C0_WATCHHI6_VALUE & WATCHHI_M) != 0
+ mtc0 t1, C0_WATCHHI, 7
+ mtc0 zero, C0_WATCHLO, 7
+
+# endif
+# endif
+# endif
+# endif
+# endif
+# endif
+# endif
+#endif
+
+ /*
+ * Clear WP bit to avoid watch exception upon user code entry, IV, and
+ * software interrupts.
+ */
+ mtc0 zero, C0_CAUSE
+
+ /*
+ * Clear timer interrupt. (Count was cleared at the reset vector to
+ * allow timing boot.)
+ */
+ mtc0 zero, C0_COMPARE
+
+ jr ra
+END(__init_cp0)
diff --git a/libgloss/mips/boot/init_l23caches.S b/libgloss/mips/boot/init_l23caches.S
new file mode 100644
index 000000000..3b3ffed52
--- /dev/null
+++ b/libgloss/mips/boot/init_l23caches.S
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+MIPS_NOMIPS16
+ .set noat
+
+LEAF(__init_l23cache)
+ /* L2 Cache initialization routine */
+ /* Check for memory mapped L2 cache config */
+ mfc0 a3, C0_CONFIG3
+ ext a3, a3, CFG3_M_SHIFT, 1
+ beqz a3, l23_init
+ mfc0 a3, C0_CONFIG4
+ ext a3, a3, CFG4_M_SHIFT, 1
+ beqz a3, l23_init
+ mfc0 a3, C0_CONFIG5
+ ext a3, a3, CFG5_L2C_SHIFT, 1
+ beqz a3, l23_init
+
+ /*
+ * No CM3 code supplied but we have a memory mapped L2 configuration
+ * Report a Boot failure through UHI
+ */
+ li t9, 23
+ /* Reason - L2 cache config */
+ li a0, 1
+ /* Trigger the UHI operation */
+ sdbbp 1
+ /* In case a debugger corrects this failure */
+ b done_l3cache
+
+l23_init:
+ /* Check L2 cache size */
+ mfc0 t0, C0_CONFIG2
+
+ /* Isolate L2$ Line Size */
+ ext t1, t0, CFG2_SL_SHIFT, CFG2_SL_BITS
+
+ /* Skip ahead if No L2$ */
+ beqz t1, done_l2cache
+
+ li a2, 2
+ sllv a1, a2, t1 /* Decode L2$ line size in bytes */
+
+ /* Isolate L2$ Sets per Way */
+ ext a0, t0, CFG2_SS_SHIFT, CFG2_SS_BITS
+ li a2, 64
+ sllv a0, a2, a0 /* L2$ Sets per way */
+
+ /* Isolate L2$ Associativity */
+ ext t1, t0, CFG2_SA_SHIFT, CFG2_SA_BITS
+ addiu t1, t1, 1
+
+ mul a0, a0, t1 /* Get total number of sets */
+
+l2cache_init:
+ li a2, 0x80000000 /* Get a KSeg0 address for cacheops */
+
+ /* Clear L23TagLo/L23TagHi registers */
+ mtc0 zero, C0_TAGLO, 4
+
+ /*
+ * L2$ Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+next_L2cache_tag:
+ cache Index_Store_Tag_S, 0(a2)
+ addiu a0, a0, -1
+ addu a2, a2, a1
+ bnez a0, next_L2cache_tag
+
+done_l2cache:
+ /* Isolate L3$ Line Size */
+ ext t1, t0, CFG2_TL_SHIFT, CFG2_TL_BITS
+
+ /* Skip ahead if No L3$ */
+ beqz t1, done_l3cache
+
+ li a2, 2
+ sllv a1, a2, t1 /* Decode L3$ line size in bytes */
+
+ /* Isolate L3$ Sets per Way */
+ ext a0, t0, CFG2_TS_SHIFT, CFG2_TS_BITS
+ li a2, 64
+ sllv a0, a2, a0 /* Decode L3 Sets per way */
+
+ /* Isolate L3$ Associativity */
+ ext t1, t0, CFG2_TA_SHIFT, CFG2_TA_BITS
+ addiu t1, t1, 1 /* Decode L3 associativity (number of sets) */
+ mul a0, a0, t1 /* Compute total number of sets */
+
+l3cache_init:
+ li a2, 0x80000000 /* Get a KSeg0 address for cacheops */
+
+ /* Clear L23Tag register */
+ mtc0 zero, C0_TAGLO, 4
+
+ /*
+ * L3$ Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+next_L3cache_tag:
+ cache Index_Store_Tag_T, 0(a2)
+ addiu a0, a0, -1
+ addu a2, a2, a1
+ bnez a0, next_L3cache_tag
+
+done_l3cache:
+ jr ra
+END(__init_l23cache)
diff --git a/libgloss/mips/boot/init_l23caches_predef.S b/libgloss/mips/boot/init_l23caches_predef.S
new file mode 100644
index 000000000..d21c69ff2
--- /dev/null
+++ b/libgloss/mips/boot/init_l23caches_predef.S
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include "predef.h"
+
+MIPS_NOMIPS16
+
+/*
+ * Depending on the range of the displacement field of the CACHE instruction
+ * we can do multiple cacheops per iteration. With a cache present there
+ * is a guarantee of 32 lines minimum so a power of 2 less than or equal
+ * to 32 means there is no remainder after the loop.
+ * The maximum number of lines per iteration is the range of the CACHE
+ * displacement divided by the line_size. We cap this at 8 as a sensible
+ * bound.
+ */
+
+#if __mips_isa_rev < 6
+/* MicroMIPS Release 3 has a 12-bit displacement for CACHE */
+# define SLINES_PER_ITER 8
+# define TLINES_PER_ITER 8
+#else
+/* MIPS Release 6 has a 9-bit signed displacement for CACHE */
+#if SLINE_SIZE == 128
+# define SLINES_PER_ITER 4 /* Requires both positive and negative disp */
+#else
+# define SLINES_PER_ITER 8
+#endif
+#if TLINE_SIZE == 128
+# define TLINES_PER_ITER 4 /* Requires both positive and negative disp */
+#else
+# define TLINES_PER_ITER 8
+#endif
+#endif
+
+#ifdef MEM_MAPPED_L2C
+# error MEM_MAPPED_L2C used with Config L2 code
+#endif
+
+/*
+ * Start off pointing to one block below where we want to invalidate the cache
+ * as the pointer is moved on at the start of the loop. Also offset the start
+ * address for each set of cache lines so that the positive and negative
+ * displacements from the CACHE ops can be used.
+ */
+
+#define SCACHE_START (0x80000000 - (SLINE_SIZE * SLINES_PER_ITER / 2))
+#define SCACHE_END (0x80000000 + STOTAL_BYTES - (SLINE_SIZE * SLINES_PER_ITER / 2))
+#define TCACHE_START (0x80000000 - (TLINE_SIZE * TLINES_PER_ITER / 2))
+#define TCACHE_END (0x80000000 + TTOTAL_BYTES - (TLINE_SIZE * TLINES_PER_ITER / 2))
+
+#define CURRENT_ADDR a0
+#define END_ADDR a1
+#define CONFIG a2
+#define TEMP a3
+
+ .set noat
+
+/*
+ * __init_l23cache invalidates all secondary/tertiary data cache entries
+ */
+
+#if defined(SLINE_ENC) && SLINE_ENC != 0
+LEAF(__init_l23cache)
+ /* Use KSEG0 base address */
+ li CURRENT_ADDR, SCACHE_START
+ /* Get the address of the last batch of lines */
+ li END_ADDR, SCACHE_END
+
+ /* Clear TagLo/TagHi registers */
+ mtc0 zero, C0_TAGLO, 4
+
+ /*
+ * Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+$Lnext_scache_tag:
+ addu CURRENT_ADDR, (SLINE_SIZE * SLINES_PER_ITER)
+ cache Index_Store_Tag_S, (SLINE_SIZE*-2)(CURRENT_ADDR)
+ cache Index_Store_Tag_S, (SLINE_SIZE*-1)(CURRENT_ADDR)
+ cache Index_Store_Tag_S, (SLINE_SIZE*0)(CURRENT_ADDR)
+ cache Index_Store_Tag_S, (SLINE_SIZE*1)(CURRENT_ADDR)
+#if SLINES_PER_ITER == 8
+ cache Index_Store_Tag_S, (SLINE_SIZE*-4)(CURRENT_ADDR)
+ cache Index_Store_Tag_S, (SLINE_SIZE*-3)(CURRENT_ADDR)
+ cache Index_Store_Tag_S, (SLINE_SIZE*2)(CURRENT_ADDR)
+ cache Index_Store_Tag_S, (SLINE_SIZE*3)(CURRENT_ADDR)
+#endif
+ bne CURRENT_ADDR, END_ADDR, $Lnext_scache_tag
+
+$Ldone_scache:
+
+#if defined(TLINE_ENC) && TLINE_ENC != 0
+
+ /* Use KSEG0 base address */
+ li CURRENT_ADDR, TCACHE_START
+ /* Get the address of the last batch of lines */
+ li END_ADDR, TCACHE_END
+
+ /* Clear TagLo/TagHi registers */
+ mtc0 zero, C0_TAGLO, 4
+
+ /*
+ * Index Store Tag Cache Op will invalidate the tag entry, clear
+ * the lock bit, and clear the LRF bit
+ */
+$Lnext_tcache_tag:
+ addu CURRENT_ADDR, (TLINE_SIZE * TLINES_PER_ITER)
+ cache Index_Store_Tag_T, (TLINE_SIZE*-2)(CURRENT_ADDR)
+ cache Index_Store_Tag_T, (TLINE_SIZE*-1)(CURRENT_ADDR)
+ cache Index_Store_Tag_T, (TLINE_SIZE*0)(CURRENT_ADDR)
+ cache Index_Store_Tag_T, (TLINE_SIZE*1)(CURRENT_ADDR)
+#if TLINES_PER_ITER == 8
+ cache Index_Store_Tag_T, (TLINE_SIZE*-4)(CURRENT_ADDR)
+ cache Index_Store_Tag_T, (TLINE_SIZE*-3)(CURRENT_ADDR)
+ cache Index_Store_Tag_T, (TLINE_SIZE*2)(CURRENT_ADDR)
+ cache Index_Store_Tag_T, (TLINE_SIZE*3)(CURRENT_ADDR)
+#endif
+ bne CURRENT_ADDR, END_ADDR, $Lnext_tcache_tag
+
+$Ldone_tcache:
+
+#endif // TLINE_ENC != 0
+ jr ra
+END(__init_l23cache)
+
+LEAF(__init_l23cache_cached)
+ jr ra
+END(__init_l23cache_cached)
+
+#endif // SLINE_ENC != 0
diff --git a/libgloss/mips/boot/init_tlb.S b/libgloss/mips/boot/init_tlb.S
new file mode 100644
index 000000000..20cf0b8dc
--- /dev/null
+++ b/libgloss/mips/boot/init_tlb.S
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2015-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+MIPS_NOMIPS16
+
+/*
+ * int, int __tlb_size();
+ *
+ * Return number of entries in TLB.
+ * Entries in va0, number of sets in va1.
+ * Must not use registers t8 or a3
+ *
+ */
+SLEAF(__tlb_size)
+ /* first see if we've got a TLB */
+ mfc0 t0, C0_CONFIG
+ mfc0 t1, C0_CONFIG1
+ move va0, zero
+
+ ext t0, t0, CFG0_MT_SHIFT, CFG0_MT_BITS
+ /* No MMU test, 0 entries */
+ beqz t0, 1f
+
+ /* Fixed Address Translation, 0 entries */
+ li t2, (CFG0_MT_FIXED >> CFG0_MT_SHIFT)
+ beq t0, t2, 1f
+
+ /* Block Address Translator, 0 entries */
+ li t2, (CFG0_MT_BAT >> CFG0_MT_SHIFT)
+ beq t0, t2, 1f
+
+ /* (D)TLB or not? */
+ andi t2, t0, (CFG0_MT_TLB | CFG0_MT_DUAL) >> CFG0_MT_SHIFT
+ beqz t2, 1f
+
+ /*
+ * As per PRA, field holds No. of entries -1
+ * Standard TLBs and Dual TLBs have extension fields.
+ */
+ ext va0, t1, CFG1_MMUS_SHIFT, CFG1_MMUS_BITS
+ addiu va0, va0, 1
+
+ mfc0 t1, C0_CONFIG3
+ ext t1, t1, CFG3_M_SHIFT, 1
+ beqz t1, 1f
+
+ mfc0 t1, C0_CONFIG4
+#if __mips_isa_rev < 6
+ ext t3, t1, CFG4_MMUED_SHIFT, CFG4_MMUED_BITS
+
+ li t2, (CFG4_MMUED_FTLBVEXT >> CFG4_MMUED_SHIFT)
+ beq t3, t2, 2f /* FTLB + VTLBExt */
+
+ li t2, (CFG4_MMUED_SIZEEXT >> CFG4_MMUED_SHIFT)
+ beq t3, t2, 3f /* SizeExt for VTLBEXT */
+
+ li t2, (CFG4_MMUED_FTLB >> CFG4_MMUED_SHIFT)
+ beq t3, t2, 4f /* FTLB Size */
+
+ /* No extension */
+ jr ra
+
+3:
+ ext t3, t1, CFG4_MMUSE_SHIFT, CFG4_MMUSE_BITS
+ sll t2, t3, CFG1_MMUS_BITS
+ addu va0, va0, t2
+ jr ra
+#endif /* __mips_isa_rev < 6 */
+2:
+ ext t2, t1, CFG4_VTLBSEXT_SHIFT, CFG4_VTLBSEXT_BITS
+ sll t2, t2, CFG1_MMUS_BITS
+ addu va0, va0, t2
+4:
+ /* Skip FTLB size calc if Config MT != 4 */
+ li t3, (CFG0_MT_DUAL >> CFG0_MT_SHIFT)
+ bne t3, t0, 1f
+
+ /* Ways */
+ li t2, 2
+ ext t3, t1, CFG4_FTLBW_SHIFT, CFG4_FTLBW_BITS
+ addu t2, t2, t3
+
+ /* Sets per way */
+ ext t3, t1, CFG4_FTLBS_SHIFT, CFG4_FTLBS_BITS
+ li va1, 1
+ sllv va1, va1, t3
+
+ /* Total sets */
+ sllv t2, t2, t3
+ addu va0, va0, t2
+
+1: jr ra
+SEND(__tlb_size)
+
+/*
+ * void __tlbinvalall()
+ *
+ * Invalidate the TLB.
+ * Must not use register a3
+ */
+SLEAF(__tlbinvalall)
+
+ mfc0 t0, C0_CONFIG
+ and t2, t0, CFG0_MT_MASK
+ beqz t2, $Lexit /* Config[MT] test, return if no TLB */
+
+ li t1, CFG0_MT_BAT
+ beq t1, t2, $Lexit /* return as there is a BAT */
+
+ li t1, CFG0_MT_FIXED /* return as there is a FMT */
+ beq t1, t2, $Lexit
+
+ PTR_MTC0 zero, C0_ENTRYLO0
+ PTR_MTC0 zero, C0_ENTRYLO1
+ PTR_MTC0 zero, C0_PAGEMASK
+
+ /* Fetch size & number of sets in va0, va1 */
+ move t8, ra
+ jal __tlb_size
+ move ra, t8
+
+ /* If Config4 does not exist then use old method for invalidation */
+ mfc0 t1, C0_CONFIG3
+ ext t1, t1, CFG3_M_SHIFT, 1
+ beqz t1, $Llegacy_init
+
+ /* If Config4[IE] = 0, use old method for invalidation */
+ mfc0 t9, C0_CONFIG4
+ ext t2, t9, CFG4_IE_SHIFT, CFG4_IE_BITS
+ beqz t2, $Llegacy_init
+
+ /* If Config4[IE] = 1, EHINV loop */
+ li t1, (CFG4_IE_EHINV >> CFG4_IE_SHIFT)
+ beq t1, t2, $Lehinv_init
+
+ /*
+ * If Config4[IE] = 2, tlbinvf loop. Handles Config[MT] being either
+ * 1 or 4.
+ */
+ li t1, (CFG4_IE_INV >> CFG4_IE_SHIFT)
+ beq t1, t2, $Ltlbinvf_init
+
+ /* TLB walk done by hardware, Config4[IE] = 3 */
+ mtc0 zero, C0_INDEX
+ ehb
+ .set push
+ .set eva
+ tlbinvf
+ .set pop
+ b $Lexit
+
+$Ltlbinvf_init:
+ /*
+ * TLB walk done by software, Config4[IE] = 2, Config[MT] = 4 or 1
+ *
+ * one TLBINVF is executed with an index in VTLB range to
+ * invalidate all VTLB entries.
+ *
+ * For Dual TLBs additionally, one TLBINVF is executed per FTLB set.
+ */
+
+ /* Flush the VTLB */
+ mtc0 zero, C0_INDEX
+ ehb
+ .set push
+ .set eva
+ tlbinvf
+ .set pop
+
+ /*
+ * For JTLB MMUs (Config[MT] = 1) only 1 tlbinvf is required
+ * early out in that case.
+ */
+ mfc0 t0, C0_CONFIG
+ ext t3, t0, CFG0_MT_SHIFT, CFG0_MT_BITS
+ li t1, (CFG0_MT_TLB >> CFG0_MT_SHIFT)
+ beq t1, t3, $Lexit
+
+ /*
+ * va0 contains number of TLB entries
+ * va1 contains number of sets per way
+ */
+ lui t9, %hi(__tlb_stride_length) /* Fetch the tlb stride for */
+ addiu t9, %lo(__tlb_stride_length) /* stepping through FTLB sets */
+ mul va1, va1, t9
+ subu t2, va0, va1 /* End pointer */
+
+1: subu va0, va0, t9
+ mtc0 va0, C0_INDEX
+ ehb /* mtc0, hazard on tlbinvf */
+ .set push
+ .set eva
+ tlbinvf
+ .set pop
+ bne va0, t2, 1b
+
+ b $Lexit
+
+$Lehinv_init:
+ /*
+ * Config4[IE] = 1. EHINV supported, but not tlbinvf.
+ *
+ * Invalidate the TLB for R3 onwards by loading EHINV and writing to all
+ * tlb entries.
+ */
+ move t0, zero
+ li t1, C0_ENTRYHI_EHINV_MASK
+ mtc0 t1, C0_ENTRYHI
+1:
+ mtc0 t0, C0_INDEX
+ ehb /* mtc0, hazard on tlbwi */
+
+ tlbwi
+ addiu t0, t0, 1
+ bne va0, t0, 1b
+
+ b $Lexit
+
+$Llegacy_init:
+ /*
+ * Invalidate the TLB for R1 onwards by loading
+ * 0x(FFFFFFFF)KSEG0_BASE into EntryHi and writing it into index 0
+ * incrementing by a pagesize, writing into index 1, etc.
+ */
+
+ /*
+ * If large physical addressing is enabled, load 0xFFFFFFFF
+ * into the top half of EntryHi.
+ */
+ move t0, zero /* t0 == 0 if XPA disabled */
+ mfc0 t9, C0_CONFIG3 /* or not present */
+ and t9, t1, CFG3_LPA
+ beqz t9, $Lno_xpa
+
+ mfc0 t9, C0_PAGEGRAIN
+ ext t9, t1, PAGEGRAIN_ELPA_SHIFT, PAGEGRAIN_ELPA_BITS
+ bnez t9, $Lno_xpa
+
+ li t0, -1 /* t0 == 0xFFFFFFFF if XPA is used */
+$Lno_xpa:
+ li t1, (KSEG0_BASE - 2<<13)
+
+ move t2, zero
+1: addiu t1, t1, (2<<13)
+ PTR_MTC0 t1, C0_ENTRYHI
+
+ beqz t0, $Lskip_entryhi
+ .set push
+ .set xpa
+ mthc0 t0, C0_ENTRYHI /* Store 0xFFFFFFFF to upper half of EntryHI */
+ .set pop
+
+$Lskip_entryhi:
+ ehb /* mtc0, hazard on tlbp */
+
+ tlbp /* Probe for a match */
+ ehb /* tlbp, Hazard on mfc0 */
+
+ mfc0 t8, C0_INDEX
+ bgez t8, 1b /* Skip this address if it exists */
+
+ mtc0 t2, C0_INDEX
+ ehb /* mtc0, hazard on tlbwi */
+
+ tlbwi
+ addiu t2, t2, 1
+ bne va0, t2, 1b
+
+$Lexit:
+ PTR_MTC0 zero, C0_ENTRYHI /* Unset EntryHI, upper half is cleared */
+ /* autmatically as mtc0 writes zeroes */
+ MIPS_JRHB (ra)
+SEND(__tlbinvalall)
+
+LEAF(__init_tlb)
+
+ mfc0 t0, C0_CONFIG
+ and t2, t0, CFG0_MT_MASK
+ beqz t2, 1f /* return if no tlb present */
+
+ li t1, CFG0_MT_BAT
+ beq t1, t2, 1f /* return as there is a BAT */
+
+ li t1, CFG0_MT_FIXED /* return as there is a FMT */
+ beq t1, t2, 1f
+
+ lui t1, %hi(__enable_xpa) /* Test for XPA usage */
+ ori t1, %lo(__enable_xpa)
+ beqz t1, 2f
+
+ mfc0 t0, C0_CONFIG3
+ and t0, t0, CFG3_LPA
+ bnez t0, 3f
+
+ /*
+ * Raise an error because XPA was requested but LPA support is not
+ * available.
+ */
+ /* Incorrect config supplied, report a boot failure through UHI */
+ li t9, 23
+ /* Reason - Predef/requested config incorrect */
+ li a0, 2
+ /* Trigger the UHI operation */
+ sdbbp 1
+
+3: li t1, 1
+ mfc0 t0, C0_PAGEGRAIN
+ ins t0, t1, PAGEGRAIN_ELPA_SHIFT, PAGEGRAIN_ELPA_BITS
+ mtc0 t0, C0_PAGEGRAIN
+2:
+ move a3, ra
+ jal __tlbinvalall
+ move ra, a3
+
+ mtc0 zero, C0_PAGEMASK
+1: jr ra
+END(__init_tlb)
diff --git a/libgloss/mips/boot/init_tlb_predef.S b/libgloss/mips/boot/init_tlb_predef.S
new file mode 100644
index 000000000..e092d0a0f
--- /dev/null
+++ b/libgloss/mips/boot/init_tlb_predef.S
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _BOOTCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include "predef.h"
+
+MIPS_NOMIPS16
+
+LEAF(__init_tlb)
+#if HAVE_LPA && ENABLE_XPA
+ mfc0 t0, C0_PAGEGRAIN
+ li t1, 1
+ ins t0, t1, PAGEGRAIN_ELPA_SHIFT, PAGEGRAIN_ELPA_BITS
+ mtc0 t0, C0_PAGEGRAIN
+#endif
+ # Top halves of registers are cleared impicitly with mtc0
+ PTR_MTC0 zero, C0_PAGEMASK
+ PTR_MTC0 zero, C0_ENTRYLO0
+ PTR_MTC0 zero, C0_ENTRYLO1
+
+#if HAVE_HW_TLB_WALK
+ /* TLB walk done by hardware, Config4[IE] = 3 or Config[MT] = 1 */
+ mtc0 zero, C0_INDEX
+ ehb
+ .set push
+ .set eva
+ tlbinvf
+ .set pop
+#endif
+
+#if HAVE_SW_TLB_WALK
+ /*
+ * TLB walk done by software, Config4[IE] = 2, Config[MT] = 4
+ *
+ * one TLBINVF is executed with an index in VTLB range to
+ * invalidate all VTLB entries.
+ *
+ * One TLBINVF is executed per FTLB entry.
+ *
+ */
+ li t2, MMU_SIZE /* Start pointer/finger */
+ li t8, FTLB_SETS
+ li t9, %hi(__tlb_stride_length)
+ addiu t9, %lo(__tlb_stride_length)
+ mul t8, t8, t9
+ subu t1, t2, t8 /* End pointer */
+
+ mtc0 zero, C0_INDEX
+ ehb
+ .set push
+ .set eva
+ tlbinvf
+ .set pop
+
+1: subu t2, t2, t9
+ mtc0 t2, C0_INDEX
+ ehb
+ .set push
+ .set eva
+ tlbinvf
+ .set pop
+ bne t1, t2, 1b
+#endif
+
+#if HAVE_EHINV_WALK
+ li v0, MMU_SIZE
+ move v1, zero
+ li t0, C0_ENTRYHI_EHINV_MASK
+ PTR_MTC0 t0, C0_ENTRYHI
+1:
+ mtc0 v1, C0_INDEX
+ ehb
+
+ tlbwi
+ addiu v1, v1, 1
+ bne v0, v1, 1b
+#endif
+
+#if HAVE_NO_INV
+ /*
+ * Clean invalidate TLB for R1 onwards by loading
+ * 0x(FFFFFFFF)KSEG0_BASE into EntryHi and writing it into index MAX
+ * incrementing EntryHi by a pagesize, writing into index MAX-1, etc.
+ */
+ li v0, MMU_SIZE
+
+ /*
+ * If large physical addressing is enabled, load 0xFFFFFFFF
+ * into the top half of EntryHi.
+ */
+#if HAVE_LPA && ENABLE_LPA
+ li t0, -1
+#endif
+ li t1, (KSEG0_BASE - 2<<13)
+
+ move v1, zero
+1: addiu t1, t1, (2<<13)
+ PTR_MTC0 t1, C0_ENTRYHI
+#if HAVE_LPA && ENABLE_LPA
+ mthc0 t0, C0_ENTRYHI
+#endif
+ ehb /* mt(h)c0, hazard on tlbp */
+
+ tlbp /* Probe for a match */
+ ehb /* tlbp, hazard on MFC0 */
+
+ mfc0 t8, C0_INDEX
+ bgez t8, 1b /* Skip this address if it exists */
+
+ mtc0 v0, C0_INDEX
+ ehb /* mtc0, hazard on tlbwi */
+
+ tlbwi
+ addiu v1, v1, 1
+ bne v0, v1, 1b
+#endif
+
+ PTR_MTC0 zero, C0_ENTRYHI /* Unset EntryHI, top half */
+ MIPS_JRHB (ra)
+END(__init_tlb)
diff --git a/libgloss/mips/boot/predef.h b/libgloss/mips/boot/predef.h
new file mode 100644
index 000000000..eeaa79ed9
--- /dev/null
+++ b/libgloss/mips/boot/predef.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef C0_CONFIG0_VALUE
+#error "Static TLB initialisation decisions require C0_CONFIG0_VALUE"
+#endif
+
+#ifndef C0_CONFIG1_VALUE
+#error "Static TLB/cache initialisation decisions require C0_CONFIG1_VALUE"
+#endif
+
+#define ILINE_ENC ((C0_CONFIG1_VALUE & CFG1_IL_MASK) >> CFG1_IL_SHIFT)
+#define ILINE_SIZE (2 << ILINE_ENC)
+#define ISET_ENC ((C0_CONFIG1_VALUE & CFG1_IS_MASK) >> CFG1_IS_SHIFT)
+#define ISET_SIZE (32 << ((ISET_ENC + 1) & 0x7))
+#define IASSOC_ENC ((C0_CONFIG1_VALUE & CFG1_IA_MASK) >> CFG1_IA_SHIFT)
+#define IASSOC (IASSOC_ENC + 1)
+#define ITOTAL_BYTES (ILINE_SIZE * ISET_SIZE * IASSOC)
+#define DLINE_ENC ((C0_CONFIG1_VALUE & CFG1_DL_MASK) >> CFG1_DL_SHIFT)
+#define DLINE_SIZE (2 << DLINE_ENC)
+#define DSET_ENC ((C0_CONFIG1_VALUE & CFG1_DS_MASK) >> CFG1_DS_SHIFT)
+#define DSET_SIZE (32 << ((DSET_ENC + 1) & 0x7))
+#define DASSOC_ENC ((C0_CONFIG1_VALUE & CFG1_DA_MASK) >> CFG1_DA_SHIFT)
+#define DASSOC (DASSOC_ENC + 1)
+#define DTOTAL_BYTES (DLINE_SIZE * DSET_SIZE * DASSOC)
+
+#ifndef C0_CONFIG2_VALUE
+# error "Static cache initialisation decisions require C0_CONFIG2_VALUE"
+#endif
+
+#ifndef C0_CONFIG3_VALUE
+# error "Static TLB initialisation decisions require C0_CONFIG3_VALUE"
+#endif
+
+#if (C0_CONFIG3_VALUE & CFG4_M) != 0
+# ifndef C0_CONFIG4_VALUE
+# error "Static TLB/cache initialisation decisions require C0_CONFIG4_VALUE"
+# endif
+# if (C0_CONFIG4_VALUE & CFG4_M) != 0
+# ifndef C0_CONFIG5_VALUE
+# error "Static cache initialisation decisions require C0_CONFIG5_VALUE"
+# endif
+# if (C0_CONFIG5_VALUE & CFG5_L2C) != 0
+# define MEM_MAPPED_L2C 1
+# endif
+# endif
+#endif
+
+#define SLINE_ENC ((C0_CONFIG2_VALUE & CFG2_SL_MASK) >> CFG2_SL_SHIFT)
+#define SSET_ENC ((C0_CONFIG2_VALUE & CFG2_SS_MASK) >> CFG2_SS_SHIFT)
+#define SASSOC_ENC ((C0_CONFIG2_VALUE & CFG2_SA_MASK) >> CFG2_SA_SHIFT)
+
+#define SLINE_SIZE (2 << SLINE_ENC)
+#define SSET_SIZE (64 << SSET_ENC)
+#define SASSOC (SASSOC_ENC + 1)
+#define STOTAL_BYTES (SLINE_SIZE * SSET_SIZE * SASSOC)
+
+#define TLINE_ENC ((C0_CONFIG2_VALUE & CFG2_TL_MASK) >> CFG2_TL_SHIFT)
+#define TLINE_SIZE (2 << TLINE_ENC)
+#define TSET_ENC ((C0_CONFIG2_VALUE & CFG2_TS_MASK) >> CFG2_TS_SHIFT)
+#define TSET_SIZE (64 << TSET_ENC)
+#define TASSOC_ENC ((C0_CONFIG2_VALUE & CFG2_TA_MASK) >> CFG2_TA_SHIFT)
+#define TASSOC (TASSOC_ENC + 1)
+#define TTOTAL_BYTES (TLINE_SIZE * TSET_SIZE * TASSOC)
+
+/* TLB Macros */
+
+// TLB Type
+#define TLB_STANDARD ((C0_CONFIG0_VALUE & CFG0_MT_MASK) == CFG0_MT_TLB)
+#define TLB_DUAL ((C0_CONFIG0_VALUE & CFG0_MT_MASK) == CFG0_MT_DUAL)
+#define HAVE_TLB (TLB_STANDARD || TLB_DUAL)
+
+// Size definitions.
+// FTLBs may be present.
+#ifdef C0_CONFIG4_VALUE
+# define FTLB_SET_ENC (C0_CONFIG4_VALUE & CFG4_FTLBS_MASK) >> (CFG4_FTLBS_SHIFT)
+# define FTLB_WAY_ENC ((C0_CONFIG4_VALUE & CFG4_FTLBW_MASK) >> CFG4_FTLBW_SHIFT)
+# if TLB_DUAL
+# define FTLB_SETS (1 << FTLB_SET_ENC)
+# define FTLB_SIZE (2 + FTLB_WAY_ENC) * FTLB_SETS
+# else
+# define FTLB_SETS 1
+# define FTLB_SIZE 0
+# endif
+
+// VTLB May be present
+# define VTLB_SIZE_ENC ((C0_CONFIG4_VALUE & CFG4_VTLBSEXT_MASK) \
+ >> CFG4_VTLBSEXT_SHIFT)
+# define VTLB_SIZE (VTLB_SIZE_ENC << CFG1_MMUS_BITS)
+#endif
+
+// Size
+#define TLB_SIZE ((C0_CONFIG1_VALUE & CFG1_MMUS_MASK) >> CFG1_MMUS_SHIFT)
+
+// ISA < 6 relys on CFG4 MMU Extension definition
+#if __mips_isa_rev < 6
+
+#if !defined(C0_CONFIG4_VALUE) || (C0_CONFIG4_VALUE & CFG4_MMUED) == 0
+# define MMU_SIZE (TLB_SIZE + 1)
+#elif (C0_CONFIG4_VALUE & CFG4_MMUED) == CFG4_MMUED_FTLBVEXT
+# define MMU_SIZE (FTLB_SIZE + VTLB_SIZE + TLB_SIZE + 1)
+#elif (C0_CONFIG4_VALUE & CFG4_MMUED) == CFG4_MMUED_SIZEEXT
+# define MMUSE_ENC (C0_CONFIG4_VALUE & CFG4_MMUSE_MASK) >> CFG4_MMUSE_SHIFT
+# define TLB_EXT_SIZE (MMUSE_ENC << CFG1_MMUS_BITS)
+# define MMU_SIZE (TLB_EXT_SIZE + TLB_SIZE + 1)
+#elif (C0_CONFIG4_VALUE & CFG4_MMUED) == CFG4_MMUED_FTLB
+# define MMU_SIZE (FTLB_SIZE + TLB_SIZE + 1)
+#endif /* C0_CONFIG4_VALUE & ...*/
+
+#else
+
+// ISA >= 6 always uses the FTLB + VTLB fields.
+#define MMU_SIZE (FTLB_SIZE + VTLB_SIZE + TLB_SIZE + 1)
+
+#endif /* __mips_isa_rev < 6 */
+
+
+// Invalidation
+#ifdef C0_CONFIG4_VALUE
+# define HAVE_HW_TLB_WALK ((C0_CONFIG4_VALUE & CFG4_IE_MASK) == CFG4_IE_INVALL)
+# define HAVE_SW_TLB_WALK ((C0_CONFIG4_VALUE & CFG4_IE_MASK) == CFG4_IE_INV)
+# define HAVE_EHINV_WALK ((C0_CONFIG4_VALUE & CFG4_IE_MASK) == CFG4_IE_EHINV)
+# define HAVE_NO_INV (!(HAVE_HW_TLB_WALK || HAVE_SW_TLB_WALK || HAVE_EHINV_WALK))
+#else
+# define HAVE_NO_INV 1
+#endif
+
+// LPA
+#define HAVE_LPA (C0_CONFIG3_VALUE & CFG3_LPA)
diff --git a/libgloss/mips/boot/reset.S b/libgloss/mips/boot/reset.S
new file mode 100644
index 000000000..163933b0b
--- /dev/null
+++ b/libgloss/mips/boot/reset.S
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014-2018 MIPS Tech, LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY 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)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _RESETCODE
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+MIPS_NOMIPS16
+
+ .set push
+ MIPS_NOMICROMIPS
+
+LEAF(__reset_vector)
+ lui k1, %hi(__cpu_init)
+ addiu k1, %lo(__cpu_init)
+ mtc0 zero, C0_COUNT /* Clear CP0 Count (Used to measure boot time.) */
+ jr k1
+ .space 32 /* Just to cope with a quirk of MIPS malta boards */
+ /* this can be deleted for anything else */
+END(__reset_vector)
+ .set pop
+
+LEAF(__cpu_init)
+
+ /*
+ * Verify the code is here due to a reset and not NMI. If this is an NMI then trigger
+ * a debugger breakpoint using a sdbbp instruction.
+ */
+
+ mfc0 k1, C0_STATUS
+ ext k1, k1, SR_NMI_SHIFT, 1
+ beqz k1, $Lnot_nmi
+ move k0, t9 /* Preserve t9 */
+ move k1, a0 /* Preserve a0 */
+ li t9, 15 /* UHI exception operation */
+ li a0, 0 /* Use hard register context */
+ sdbbp 1 /* Invoke UHI operation */
+
+$Lnot_nmi:
+
+ /* Init CP0 Status, Count, Compare, Watch*, and Cause */
+ jal __init_cp0
+
+ /*
+ * Initialise L2/L3 cache
+ * This could be done from cached code if there is a cca override or similar
+ */
+ jal __init_l23cache
+
+ /* Initialize the L1 instruction cache */
+ jal __init_icache
+
+ /*
+ * The changing of Kernel mode cacheability must be done from KSEG1
+ * Since the code is executing from KSEG0 it needs to do a jump to KSEG1, change K0
+ * and jump back to KSEG0.
+ */
+
+ lui a2, %hi(__change_k0_cca)
+ addiu a2, a2, %lo(__change_k0_cca)
+ li a1, 0xf
+ ins a2, a1, 29, 1 /* changed to KSEG1 address by setting bit 29 */
+ jalr a2
+
+ .weak __init_l23cache_cached
+ lui a2, %hi(__init_l23cache_cached)
+ addiu a2, a2, %lo(__init_l23cache_cached)
+ beqz a2, 1f
+ jalr a2
+1:
+ /* Initialize the L1 data cache */
+ jal __init_dcache
+
+ /* Initialize the TLB */
+ jal __init_tlb
+
+ /* Allow everything else to be initialized via a hook */
+ .weak __boot_init_hook
+ lui a2, %hi(__boot_init_hook)
+ addiu a2, a2, %lo(__boot_init_hook)
+ beqz a2, 1f
+ jalr a2
+1:
+ /* Skip copy to ram when executing in place */
+ .weak __xip
+ lui a1, %hi(__xip)
+ addiu a1, a1, %lo(__xip)
+ bnez a1, $Lcopy_to_ram_done
+ /* Copy code and data to RAM */
+ li s1, 0xffffffff
+
+ /* Copy code and read-only/initialized data from FLASH to (uncached) RAM */
+ lui a1, %hi(__flash_app_start)
+ addiu a1, a1, %lo(__flash_app_start)
+ ins a1, s1, 29, 1 /* Make it uncached (kseg1) */
+ lui a2, %hi(__app_start)
+ addiu a2, a2, %lo(__app_start)
+ ins a2, s1, 29, 1 /* Make it uncached (kseg1) */
+ lui a3, %hi(_edata)
+ addiu a3, a3, %lo(_edata)
+ ins a3, s1, 29, 1 /* Make it uncached (kseg1) */
+ beq a2, a3, $Lcopy_to_ram_done
+$Lnext_ram_word:
+ lw a0, 0(a1)
+ addiu a2, a2, 4
+ addiu a1, a1, 4
+ sw a0, -4(a2)
+ bne a3, a2, $Lnext_ram_word
+$Lcopy_to_ram_done:
+
+ # Prepare for eret to _start
+ lui ra, %hi($Lall_done) /* If main returns then go to all_done */
+ addiu ra, ra, %lo($Lall_done)
+ lui t0, %hi(_start)
+ addiu t0, t0, %lo(_start)
+ mtc0 t0, C0_ERRPC /* Set ErrorEPC to _start */
+ ehb
+ li a0, 0 /* UHI compliant null argument setup */
+
+ /* Return from exception will now execute the application startup code */
+ eret
+
+$Lall_done:
+ /*
+ * If _start returns it will return to this point.
+ * Just spin here reporting the exit.
+ */
+ li t9, 1 /* UHI exit operation */
+ move a0, va0 /* Collect exit code for UHI exit */
+ sdbbp 1 /* Invoke UHI operation */
+ b $Lall_done
+END(__cpu_init)
+
+/**************************************************************************************
+ B O O T E X C E P T I O N H A N D L E R S (CP0 Status[BEV] = 1)
+**************************************************************************************/
+/* NOTE: the linker script must insure that this code starts at start + 0x200 so the exception */
+/* vectors will be addressed properly. */
+
+/* TLB refill, 32 bit task. */
+.org 0x200
+LEAF(__boot_tlb_refill)
+ move k0, t9 /* Preserve t9 */
+ move k1, a0 /* Preserve a0 */
+ li t9, 15 /* UHI exception operation */
+ li a0, 0 /* Use hard register context */
+ sdbbp 1 /* Invoke UHI operation */
+END(__boot_tlb_refill)
+
+/* XTLB refill, 64 bit task. */
+.org 0x280
+LEAF(__boot_xtlb_refill)
+ move k0, t9 /* Preserve t9 */
+ move k1, a0 /* Preserve a0 */
+ li t9, 15 /* UHI exception operation */
+ li a0, 0 /* Use hard register context */
+ sdbbp 1 /* Invoke UHI operation */
+END(__boot_xtlb_refill)
+
+/* Cache error exception. */
+.org 0x300
+LEAF(__boot_cache_error)
+ move k0, t9 /* Preserve t9 */
+ move k1, a0 /* Preserve a0 */
+ li t9, 15 /* UHI exception operation */
+ li a0, 0 /* Use hard register context */
+ sdbbp 1 /* Invoke UHI operation */
+END(__boot_cache_error)
+
+/* General exception. */
+.org 0x380
+LEAF(__boot_general_exception)
+ move k0, t9 /* Preserve t9 */
+ move k1, a0 /* Preserve a0 */
+ li t9, 15 /* UHI exception operation */
+ li a0, 0 /* Use hard register context */
+ sdbbp 1 /* Invoke UHI operation */
+END(__boot_general_exception)
+
+# If you want the above code to fit into 1k flash you will need to leave out the
+# code below. This is the code that covers the debug exception which you normally will not get.
+
+/* EJTAG Debug */
+.org 0x480
+LEAF(__boot_debug_exception)
+ PTR_MFC0 k1, C0_DEPC
+ PTR_MTC0 k1, C0_DESAVE
+ lui k1, %hi(1f)
+ addiu k1, %lo(1f)
+ PTR_MTC0 k1, C0_DEPC
+ ehb
+ deret
+1: wait
+ b 1b /* Stay here */
+END(__boot_debug_exception)
diff --git a/libgloss/mips/boot/reset_predef.S b/libgloss/mips/boot/reset_predef.S
new file mode 100644
index 000000000..592b592b9
--- /dev/null
+++ b/libgloss/mips/boot/reset_predef.S
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2014-2018 MIPS T[...]
[diff truncated at 100000 bytes]
More information about the Newlib-cvs
mailing list