[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