[v2,01/13] mips: Implement MIPS HAL and UHI

Message ID 20250402141228.1973965-2-jovan.dmitrovic@htecgroup.com
State New
Headers
Series A series of updates related to MIPS |

Commit Message

Jovan Dmitrovic April 2, 2025, 2:13 p.m. UTC
  From: Jaydeep Patil <jaydeep.patil@imgtec.com>

Implement abstract interface for MIPS, including unified hosting
interface (UHI).
---
 config-ml.in                                |   25 +-
 config/mt-sde                               |    4 +-
 libgloss/config/mips.mt                     |   60 +-
 libgloss/configure                          |   19 +-
 libgloss/fstat.c                            |    3 +
 libgloss/kill.c                             |    1 +
 libgloss/libnosys/fstat.c                   |    3 +
 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                |   82 +
 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                |   51 +
 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                    |   45 -
 libgloss/mips/test.c                        |    7 +-
 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 +-
 125 files changed, 15849 insertions(+), 537 deletions(-)
 create mode 100644 libgloss/mips/boot/corecheck_predef.S
 create mode 100644 libgloss/mips/boot/init_caches.S
 create mode 100644 libgloss/mips/boot/init_caches_predef.S
 create mode 100644 libgloss/mips/boot/init_cm3l2.S
 create mode 100644 libgloss/mips/boot/init_cm3l2_predef.S
 create mode 100644 libgloss/mips/boot/init_cp0.S
 create mode 100644 libgloss/mips/boot/init_cp0_predef.S
 create mode 100644 libgloss/mips/boot/init_l23caches.S
 create mode 100644 libgloss/mips/boot/init_l23caches_predef.S
 create mode 100644 libgloss/mips/boot/init_tlb.S
 create mode 100644 libgloss/mips/boot/init_tlb_predef.S
 create mode 100644 libgloss/mips/boot/predef.h
 create mode 100644 libgloss/mips/boot/reset.S
 create mode 100644 libgloss/mips/boot/reset_predef.S
 create mode 100644 libgloss/mips/bootcode.ld
 delete mode 100644 libgloss/mips/crt0.S
 create mode 100644 libgloss/mips/fstat.c
 create mode 100644 libgloss/mips/hal/__exit.c
 create mode 100644 libgloss/mips/hal/abiflags.S
 create mode 100644 libgloss/mips/hal/cache.h
 create mode 100644 libgloss/mips/hal/crt0.S
 create mode 100644 libgloss/mips/hal/get_ram_range.c
 create mode 100644 libgloss/mips/hal/libcm3.a
 create mode 100644 libgloss/mips/hal/link.c
 create mode 100644 libgloss/mips/hal/minicrt.S
 create mode 100644 libgloss/mips/hal/mips64_tlb.c
 create mode 100644 libgloss/mips/hal/mips_clean_cache.c
 create mode 100644 libgloss/mips/hal/mips_cm3_l2size.c
 create mode 100644 libgloss/mips/hal/mips_dsp.S
 create mode 100644 libgloss/mips/hal/mips_excpt_boot.S
 create mode 100644 libgloss/mips/hal/mips_excpt_entry.S
 create mode 100644 libgloss/mips/hal/mips_excpt_handler.c
 create mode 100644 libgloss/mips/hal/mips_excpt_isr_fallback.S
 create mode 100644 libgloss/mips/hal/mips_excpt_isr_fragment.S
 create mode 100644 libgloss/mips/hal/mips_excpt_register.S
 create mode 100644 libgloss/mips/hal/mips_excpt_timer.S
 create mode 100644 libgloss/mips/hal/mips_flush_cache.c
 create mode 100644 libgloss/mips/hal/mips_fp.S
 create mode 100644 libgloss/mips/hal/mips_intctrl.c
 create mode 100644 libgloss/mips/hal/mips_l2size.c
 create mode 100644 libgloss/mips/hal/mips_lock_cache.c
 create mode 100644 libgloss/mips/hal/mips_msa.S
 create mode 100644 libgloss/mips/hal/mips_size_cache.c
 create mode 100644 libgloss/mips/hal/mips_sync_cache.c
 create mode 100644 libgloss/mips/hal/mips_tlb.c
 create mode 100644 libgloss/mips/hal/mips_xpa.S
 create mode 100644 libgloss/mips/hal/syscalls.c
 create mode 100644 libgloss/mips/include/mips/asm.h
 create mode 100644 libgloss/mips/include/mips/cm3.h
 create mode 100644 libgloss/mips/include/mips/cpu.h
 create mode 100644 libgloss/mips/include/mips/ctx.S
 create mode 100644 libgloss/mips/include/mips/dsp.h
 create mode 100644 libgloss/mips/include/mips/endian.h
 create mode 100644 libgloss/mips/include/mips/fgregdef.h
 create mode 100644 libgloss/mips/include/mips/fpa.h
 create mode 100644 libgloss/mips/include/mips/hal.h
 create mode 100644 libgloss/mips/include/mips/intctrl.h
 create mode 100644 libgloss/mips/include/mips/m32c0.h
 create mode 100644 libgloss/mips/include/mips/m32c1.h
 create mode 100644 libgloss/mips/include/mips/m32tlb.h
 create mode 100644 libgloss/mips/include/mips/m64c0.h
 create mode 100644 libgloss/mips/include/mips/m64tlb.h
 create mode 100644 libgloss/mips/include/mips/mips32.h
 create mode 100644 libgloss/mips/include/mips/mips64.h
 create mode 100644 libgloss/mips/include/mips/mt.h
 create mode 100644 libgloss/mips/include/mips/notlb.h
 create mode 100644 libgloss/mips/include/mips/prid.h
 create mode 100644 libgloss/mips/include/mips/regdef.h
 create mode 100644 libgloss/mips/include/mips/uhi_syscalls.h
 create mode 100644 libgloss/mips/include/mips/version.h
 create mode 100644 libgloss/mips/malta32-yamon.ld
 delete mode 100644 libgloss/mips/syscalls.c
 create mode 100644 libgloss/mips/uhi/uhi_assert.c
 create mode 100644 libgloss/mips/uhi/uhi_break.c
 create mode 100644 libgloss/mips/uhi/uhi_close.c
 create mode 100644 libgloss/mips/uhi/uhi_exception.c
 create mode 100644 libgloss/mips/uhi/uhi_exit.c
 create mode 100644 libgloss/mips/uhi/uhi_fstat.c
 create mode 100644 libgloss/mips/uhi/uhi_get_ram_range.c
 create mode 100644 libgloss/mips/uhi/uhi_getargs.S
 create mode 100644 libgloss/mips/uhi/uhi_indirect.c
 create mode 100644 libgloss/mips/uhi/uhi_link.c
 create mode 100644 libgloss/mips/uhi/uhi_lseek.c
 create mode 100644 libgloss/mips/uhi/uhi_open.c
 create mode 100644 libgloss/mips/uhi/uhi_plog.c
 create mode 100644 libgloss/mips/uhi/uhi_pread.c
 create mode 100644 libgloss/mips/uhi/uhi_pwrite.c
 create mode 100644 libgloss/mips/uhi/uhi_read.c
 create mode 100644 libgloss/mips/uhi/uhi_stat.c
 create mode 100644 libgloss/mips/uhi/uhi_stat.h
 create mode 100644 libgloss/mips/uhi/uhi_unlink.c
 create mode 100644 libgloss/mips/uhi/uhi_write.c
 create mode 100644 libgloss/mips/uhi/yamon_close.c
 create mode 100644 libgloss/mips/uhi/yamon_exception.c
 create mode 100644 libgloss/mips/uhi/yamon_exit.c
 create mode 100644 libgloss/mips/uhi/yamon_fstat.c
 create mode 100644 libgloss/mips/uhi/yamon_read.c
 create mode 100644 libgloss/mips/uhi/yamon_syscalls.h
 create mode 100644 libgloss/mips/uhi/yamon_write.c
 create mode 100644 libgloss/mips/uhi32.ld
 create mode 100644 libgloss/mips/uhi64_64.ld
 create mode 100644 libgloss/mips/uhi64_n32.ld
  

Patch

diff --git a/config-ml.in b/config-ml.in
index 5e519942b..fcf66ac0c 100644
--- a/config-ml.in
+++ b/config-ml.in
@@ -382,6 +382,23 @@  mips*-*-*)
 	    esac
 	  done
 	fi
+	if [ x$with_multi_buildlist != x ]
+	then
+	  old_multidirs="${multidirs}"
+	  if [ ! -f $with_multi_buildlist ]
+	  then
+	    echo "config-ml.in: Failed to find $with_multi_buildlist"
+	    exit 1
+	  fi
+	  multidirs=""
+	  for x in ${old_multidirs}; do
+	    found=`grep "^${x}$" $with_multi_buildlist`
+	    if [ -n "$found" ]
+	    then
+	      multidirs="${multidirs} ${x}"
+	    fi
+	  done
+	fi
 	;;
 powerpc*-*-* | rs6000*-*-*)
 	if [ x$enable_aix64 = xno ]
@@ -583,7 +600,8 @@  else
 fi
 
 if [ -z "${with_multisubdir}" ]; then
-  ml_subdir=
+  ml_top_subdir=`${CC-gcc} --print-multi-directory 2>/dev/null`
+  ml_subdir=/$ml_top_subdir
   ml_builddotdot=
   : # ml_srcdotdot= # already set
 else
@@ -662,6 +680,11 @@  if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then
 
   for ml_dir in ${multidirs}; do
 
+    if [ "${ml_dir}" == "${ml_top_subdir}" ]; then
+      echo "Skipping configure in multilib subdir ${ml_dir}"
+      continue
+    fi
+
     if [ "${ml_verbose}" = --verbose ]; then
       echo "Running configure in multilib subdir ${ml_dir}"
       echo "pwd: `${PWDCMD-pwd}`"
diff --git a/config/mt-sde b/config/mt-sde
index a3fc1e1d7..f8746167d 100644
--- a/config/mt-sde
+++ b/config/mt-sde
@@ -6,5 +6,5 @@ 
 # has two purposes: it allows libraries to be used in situations where
 # $gp != our _gp, and it allows them to be built with -G8 while
 # retaining link compatibility with -G0 and -G4.
-CFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-readable=pcrel -mno-gpopt
-CXXFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-readable=pcrel -mno-gpopt
+CFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-readable=no -mno-gpopt
+CXXFLAGS_FOR_TARGET += -Os -minterlink-mips16 -mcode-readable=no -mno-gpopt
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/fstat.c b/libgloss/fstat.c
index c9d14d103..d8f94af6f 100644
--- a/libgloss/fstat.c
+++ b/libgloss/fstat.c
@@ -19,6 +19,9 @@ 
  * fstat -- Since we have no file system, we just return an error.
  */
 int
+#if defined(__mips__) && defined(__mips16)
+__attribute__((nomips16))
+#endif
 fstat (int fd,
        struct stat *buf)
 {
diff --git a/libgloss/kill.c b/libgloss/kill.c
index a0eaee75b..9650fb800 100644
--- a/libgloss/kill.c
+++ b/libgloss/kill.c
@@ -13,6 +13,7 @@ 
  * they apply.
  */
 #include "glue.h"
+void _exit(int);
 
 /*
  * kill -- go out via exit...
diff --git a/libgloss/libnosys/fstat.c b/libgloss/libnosys/fstat.c
index c85b9f209..e3d4cec64 100644
--- a/libgloss/libnosys/fstat.c
+++ b/libgloss/libnosys/fstat.c
@@ -13,6 +13,9 @@  extern int errno;
 #include "warning.h"
 
 int
+#if defined(__mips__) && defined(__mips16)
+__attribute__((nomips16))
+#endif
 _fstat (int          fildes,
         struct stat *st)
 {
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 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 "predef.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:
+
+#ifndef SKIP_CORE_CHECK
+	jal	__core_check
+#endif
+
+	/* Init CP0 Status, Count, Compare, Watch*, and Cause */
+	jal	__init_cp0
+
+#if (defined(SLINE_ENC) && SLINE_ENC != 0) || (defined(MEM_MAPPED_L2C) && MEM_MAPPED_L2C != 0)
+	/*
+	 * Initialise L2/L3 cache
+	 * This could be done from cached code if there is a cca override or similar
+	 */
+	jal	 __init_l23cache
+#endif
+
+
+#if defined(ILINE_ENC) && ILINE_ENC != 0
+	/* 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
+#endif
+
+#if (defined(SLINE_ENC) && SLINE_ENC != 0) || (defined(MEM_MAPPED_L2C) && MEM_MAPPED_L2C != 0)
+	/* Support initialising L2 with L1 cache enabled */
+	jal	__init_l23cache_cached
+#endif
+
+#if defined(DLINE_ENC) && DLINE_ENC != 0
+	/* Initialize the L1 data cache */
+	jal	__init_dcache
+#endif
+
+#if defined(HAVE_TLB) && HAVE_TLB
+	/* Initialize the TLB */
+	jal	__init_tlb
+#endif
+
+	/* 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)
+#if defined(ILINE_ENC) && ILINE_ENC != 0
+	ins	a1, s1, 29, 1		/* Make it uncached (kseg1) */
+#endif
+	lui	a2, %hi(__app_start)
+	addiu	a2, a2, %lo(__app_start)
+#if defined(ILINE_ENC) && ILINE_ENC != 0
+	ins	a2, s1, 29, 1		/* Make it uncached (kseg1) */
+#endif
+	lui	a3, %hi(_edata)
+	addiu	a3, a3, %lo(_edata)
+#if defined(ILINE_ENC) && ILINE_ENC != 0
+	ins	a3, s1, 29, 1		/* Make it uncached (kseg1) */
+#endif
+	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/bootcode.ld b/libgloss/mips/bootcode.ld
new file mode 100644
index 000000000..5c1bcbff2
--- /dev/null
+++ b/libgloss/mips/bootcode.ld
@@ -0,0 +1,14 @@ 
+/* This script forces the inclusion of boot code by creating references
+   to all the initialisation functions.  These early references also
+   ensure custom versions of code are pulled out of user supplied
+   objects and libraries before default implementations.  */
+
+EXTERN (__reset_vector);
+EXTERN (__init_cp0);
+EXTERN (__init_l23cache);
+EXTERN (__init_icache);
+EXTERN (__change_k0_cca);
+EXTERN (__init_dcache);
+EXTERN (__init_tlb);
+EXTERN (__boot_init_hook);
+PROVIDE (__boot_init_hook = 0);
diff --git a/libgloss/mips/crt0.S b/libgloss/mips/crt0.S
deleted file mode 100644
index 254998242..000000000
--- a/libgloss/mips/crt0.S
+++ /dev/null
@@ -1,316 +0,0 @@ 
-/*
- * crt0.S -- startup file for MIPS.
- *
- * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support
- *
- * The authors hereby grant permission to use, copy, modify, distribute,
- * and license this software and its documentation for any purpose, provided
- * that existing copyright notices are retained in all copies and that this
- * notice is included verbatim in any distributions. No written agreement,
- * license, or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their authors
- * and need not follow the licensing terms described here, provided that
- * the new terms are clearly indicated on the first page of each file where
- * they apply.
- */
-
-/* This file does not use any floating-point ABI.  */
-	.gnu_attribute 4,0
-
-#ifdef __mips16
-/* This file contains 32 bit assembly code.  */
-	.set nomips16
-#endif
-
-#include "regs.S"
-#include "abiflags.S"
-
-/*
- * Set up some room for a stack. We just grab a chunk of memory.
- */
-#define STACK_SIZE  0x4000
-#define GLOBAL_SIZE 0x2000
-
-#define STARTUP_STACK_SIZE	0x0100
-
-/* This is for referencing addresses that are not in the .sdata or
-   .sbss section under embedded-pic, or before we've set up gp.  */
-#ifdef __mips_embedded_pic
-# ifdef __mips64
-#  define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
-# else
-#  define LA(t,x) la t,x-PICBASE ; addu t,s0,t
-# endif
-#else /* __mips_embedded_pic */
-# define LA(t,x) la t,x
-#endif /* __mips_embedded_pic */
-
-	.comm	__memsize, 12
-	.comm	__lstack, STARTUP_STACK_SIZE
-
-	.text
-	.align	2
-
-/* Without the following nop, GDB thinks _start is a data variable.
- * This is probably a bug in GDB in handling a symbol that is at the
- * start of the .text section.
- */
-	nop
-
-	.globl	hardware_hazard_hook .text
-	.globl	_start
-	.ent	_start
-_start:
-#ifdef __mips_embedded_pic
-#define PICBASE start_PICBASE
-	.set	noreorder
-	PICBASE = .+8
-        bal	PICBASE
-	nop
-	move	s0,$31
-	.set	reorder
-#endif
-#if __mips<3
-#  define STATUS_MASK (SR_CU1|SR_PE)
-#else
-/* Post-mips2 has no SR_PE bit.  */
-#  ifdef __mips64
-/* Turn on 64-bit addressing and additional float regs.  */
-#    define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX)
-#  else
-#    if __mips_fpr==32
-#      define STATUS_MASK (SR_CU1)
-#    else
-/* Turn on additional float regs.  */
-#      define STATUS_MASK (SR_CU1|SR_FR)
-#    endif
-#  endif
-#endif
-
-	/* Clear Cause register.  */
-	mtc0	zero,C0_CAUSE
-	nop
-
-	/* Read MIPS_abiflags structure and set status/config registers
-	   accordingly.  */
-	.weak	__MIPS_abiflags_start
-	.weak	__MIPS_abiflags_end
-	LA	(t0,__MIPS_abiflags_start)
-	LA	(t1,__MIPS_abiflags_end)
-	addiu	t1,t1,-24
-	move	v0,zero			/* Mask for C0_SR.  */
-
-	/* Branch to 1f is the .MIPS.abiflags section is not 24 bytes.  This
-	   indicates it is either missing or corrupt.  */
-	bne	t0,t1,1f
-
-	/* Check isa_level.  */
-	lbu	t1,ABIFlags_isa_level(t0)
-	sltu	v1,t1,3			/* Is MIPS < 3?  */
-	xori	t1,t1,64		/* Is MIPS64?  */
-	beq	v1,zero,4f
-	li	v1,SR_PE
-	or	v0,v0,v1		/* Enable soft reset.  */
-4:
-	li	v1,(SR_KX|SR_SX|SR_UX)
-	bne	t1,zero,5f
-	or	v0,v0,v1		/* Enable extended addressing.  */
-5:
-	/* Check fp_abi.  */
-	lbu	t1,ABIFlags_fp_abi(t0)
-	xori	t1,t1,Val_GNU_MIPS_ABI_FP_SOFT
-	li	v1,SR_CU1
-	beq	t1,zero,2f		/* Skip MSA and cpr1_size checks.  */
-	or	v0,v0,v1		/* Enable co-processor 1.  */
-
-	/* Check cpr1_size.  */
-	lbu	t1,ABIFlags_cpr1_size(t0)
-	xori	t1,t1,AFL_REG_64
-	li	v1,SR_FR
-	bne	t1,zero,3f
-	or	v0,v0,v1		/* Enable 64-bit FPU registers.  */
-3:
-	/* Check ases.  */
-	lw	t1,ABIFlags_ases(t0)
-	andi	t1,t1,AFL_ASE_MSA
-	li	v1,SR_FR
-	beq	t1,zero,2f
-	or	v0,v0,v1		/* Enable 64-bit FPU registers.  */
-	li	v1,SR_MSA
-	.set	push
-	.set	mips32
-	mtc0	v1,C0_CONFIG,5		/* Enable MSA.  */
-	.set	pop
-	b	2f
-
-1:
-	/* MIPS_abiflags structure is not available.  Set status/config
-	   registers based on flags defined by compiler.  */
-#ifdef __mips_soft_float
-	li	v0,(STATUS_MASK-(STATUS_MASK & SR_CU1))
-#else
-	li	v0,STATUS_MASK
-#endif
-
-2:
-	/* Set C0_SR,  */
-	mtc0	v0,C0_SR
-	nop
-
-	/* Avoid hazard from C0_SR changes.  */
-	LA	(t0, hardware_hazard_hook)
-	beq	t0,zero,2f
-	jalr	t0
-2:
-
-
-/* Fix high bits, if any, of the PC so that exception handling doesn't get
-   confused.  */
-	LA (v0, 3f)
-	jr	v0
-3:
-	LA (gp, _gp)				# set the global data pointer
-	.end _start
-
-/*
- * zero out the bss section.
- */
-	.globl	__memsize
-	.globl	get_mem_info .text
-	.globl	__stack
-	.globl	__global
-	.ent	zerobss
-zerobss:
-	LA (v0, _fbss)
-	LA (v1, _end)
-	beq	v0,v1,2f
-1:
-	addiu	v0,v0,4
-	sw	zero,-4(v0)
-	bne	v0,v1,1b
-2:
-	la	t0, __lstack			# make a small stack so we
-	addiu	sp, t0, STARTUP_STACK_SIZE	# can run some C code
-	la	a0, __memsize			# get the usable memory size
-	jal	get_mem_info
-
-	/* setup the stack pointer */
-	LA (t0, __stack)			# is __stack set ?
-	bne	t0,zero,4f
-
-	/* NOTE: a0[0] contains the amount of memory available, and
-	         not the last memory address. */
-	la	a0, __memsize
-	lw	t0,0(a0)			# last address of memory available
-	la	t1,K0BASE			# cached kernel memory
-	addu	t0,t0,t1			# get the end of memory address
-	/* Allocate 32 bytes for the register parameters.  Allocate 16
-	   bytes for a null argv and envp.  Round the result up to 64
-	   bytes to preserve alignment.  */
-	subu	t0,t0,64
-4:
-	move	sp,t0				# set stack pointer
-	.end	zerobss
-
-/*
- * initialize target specific stuff. Only execute these
- * functions it they exist.
- */
-	.globl	hardware_init_hook .text
-	.globl	software_init_hook .text
-	.type	_fini,@function
-	.type	_init,@function
-	.globl	atexit .text
-	.globl	exit .text
-	.ent	init
-init:
-	LA (t9, hardware_init_hook)		# init the hardware if needed
-	beq	t9,zero,6f
-	jalr	t9
-6:
-	LA (t9, software_init_hook)		# init the hardware if needed
-	beq	t9,zero,7f
-	jalr	t9
-7:
-	LA (a0, _fini)
-	jal	atexit
-
-#ifdef GCRT0
-	.globl	_ftext
-	.globl	_extext
-	LA (a0, _ftext)
-	LA (a1, _etext)
-	jal	monstartup
-#endif
-
-
-	jal	_init				# run global constructors
-
-	addiu	a1,sp,32			# argv = sp + 32
-	addiu	a2,sp,40			# envp = sp + 40
-#if __mips64
-	sd	zero,(a1)			# argv[argc] = 0
-	sd	zero,(a2)			# envp[0] = 0
-#else
-	sw	zero,(a1)
-	sw	zero,(a2)
-#endif
-	move	a0,zero				# set argc to 0
-	jal	main				# call the program start function
-
-	# fall through to the "exit" routine
-	move	a0,v0				# pass through the exit code
-	jal	exit				# call libc exit to run the G++
-						# destructors
-	.end	init
-
- 
-/* Assume the PICBASE set up above is no longer valid below here.  */
-#ifdef __mips_embedded_pic
-#undef PICBASE
-#endif
-	
-/*
- * _exit -- Exit from the application. Normally we cause a user trap
- *          to return to the ROM monitor for another run. NOTE: This is
- *	    the only other routine we provide in the crt0.o object, since
- *          it may be tied to the "_start" routine. It also allows
- *          executables that contain a complete world to be linked with
- *          just the crt0.o object.
- */
-	.globl	hardware_exit_hook .text
-	.globl	_exit
-	.ent _exit
-_exit:
-7:
-#ifdef __mips_embedded_pic
-	/* Need to reinit PICBASE, since we might be called via exit()
-	   rather than via a return path which would restore old s0.  */
-#define PICBASE exit_PICBASE
-	.set	noreorder
-	PICBASE = .+8
-	bal	PICBASE
-	nop
-	move	s0,$31
-	.set	reorder
-#endif
-#ifdef GCRT0
-	LA (t0, _mcleanup)
-	jalr	t0
-#endif
-	LA (t0, hardware_exit_hook)
-	beq	t0,zero,1f
-	jalr	t0
-1:
-
-	# break instruction can cope with 0xfffff, but GAS limits the range:
-	break	1023
-	b	7b				# but loop back just in-case
-	.end _exit
- 
-/* Assume the PICBASE set up above is no longer valid below here.  */
-#ifdef __mips_embedded_pic
-#undef PICBASE
-#endif
-
-/* EOF crt0.S */
diff --git a/libgloss/mips/fstat.c b/libgloss/mips/fstat.c
new file mode 100644
index 000000000..d8f94af6f
--- /dev/null
+++ b/libgloss/mips/fstat.c
@@ -0,0 +1,32 @@ 
+/* fstat.c -- get status of a file.
+ *
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include <sys/stat.h>
+#include "glue.h"
+
+/*
+ * fstat -- Since we have no file system, we just return an error.
+ */
+int
+#if defined(__mips__) && defined(__mips16)
+__attribute__((nomips16))
+#endif
+fstat (int fd,
+       struct stat *buf)
+{
+  buf->st_mode = S_IFCHR;	/* Always pretend to be a tty */
+  buf->st_blksize = 0;
+
+  return (0);
+}
diff --git a/libgloss/mips/hal/__exit.c b/libgloss/mips/hal/__exit.c
new file mode 100644
index 000000000..9041f8599
--- /dev/null
+++ b/libgloss/mips/hal/__exit.c
@@ -0,0 +1,48 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     void __exit (int32_t exit_code);
+ *
+ *               Parameters:
+ *                 $4 - Exit code
+ *
+ *               Return:
+ *                 None
+ *
+ * @Description  Transfer control to the debug port
+*/
+
+#include <stdint.h>
+
+void
+__exit (int32_t exit_code)
+{
+  return;
+}
+
diff --git a/libgloss/mips/hal/abiflags.S b/libgloss/mips/hal/abiflags.S
new file mode 100644
index 000000000..953caafb4
--- /dev/null
+++ b/libgloss/mips/hal/abiflags.S
@@ -0,0 +1,82 @@ 
+/*
+ * abiflags.S - MIPS ABI flags.
+ */
+
+/* Values for the xxx_size bytes of an ABI flags structure.  */
+#define AFL_REG_NONE         0x00       /* No registers.  */
+#define AFL_REG_32           0x01       /* 32-bit registers.  */
+#define AFL_REG_64           0x02       /* 64-bit registers.  */
+#define AFL_REG_128          0x03       /* 128-bit registers.  */
+
+/* Masks for the ases word of an ABI flags structure.  */
+#define AFL_ASE_DSP          0x00000001  /* DSP ASE.  */
+#define AFL_ASE_DSPR2        0x00000002  /* DSP R2 ASE.  */
+#define AFL_ASE_EVA          0x00000004  /* Enhanced VA Scheme.  */
+#define AFL_ASE_MCU          0x00000008  /* MCU (MicroController) ASE.  */
+#define AFL_ASE_MDMX         0x00000010  /* MDMX ASE.  */
+#define AFL_ASE_MIPS3D       0x00000020  /* MIPS-3D ASE.  */
+#define AFL_ASE_MT           0x00000040  /* MT ASE.  */
+#define AFL_ASE_SMARTMIPS    0x00000080  /* SmartMIPS ASE.  */
+#define AFL_ASE_VIRT         0x00000100  /* VZ ASE.  */
+#define AFL_ASE_MSA          0x00000200  /* MSA ASE.  */
+#define AFL_ASE_MIPS16       0x00000400  /* MIPS16 ASE.  */
+#define AFL_ASE_MICROMIPS    0x00000800  /* MICROMIPS ASE.  */
+#define AFL_ASE_XPA          0x00001000  /* XPA ASE.  */
+
+/* Values for the isa_ext word of an ABI flags structure.  */
+#define AFL_EXT_XLR           1  /* RMI Xlr instruction.  */
+#define AFL_EXT_OCTEON2       2  /* Cavium Networks Octeon2.  */
+#define AFL_EXT_OCTEONP       3  /* Cavium Networks OcteonP.  */
+#define AFL_EXT_LOONGSON_3A   4  /* Loongson 3A.  */
+#define AFL_EXT_OCTEON        5  /* Cavium Networks Octeon.  */
+#define AFL_EXT_5900          6  /* MIPS R5900 instruction.  */
+#define AFL_EXT_4650          7  /* MIPS R4650 instruction.  */
+#define AFL_EXT_4010          8  /* LSI R4010 instruction.  */
+#define AFL_EXT_4100          9  /* NEC VR4100 instruction.  */
+#define AFL_EXT_3900         10  /* Toshiba R3900 instruction.  */
+#define AFL_EXT_10000        11  /* MIPS R10000 instruction.  */
+#define AFL_EXT_SB1          12  /* Broadcom SB-1 instruction.  */
+#define AFL_EXT_4111         13  /* NEC VR4111/VR4181 instruction.  */
+#define AFL_EXT_4120         14  /* NEC VR4120 instruction.  */
+#define AFL_EXT_5400         15  /* NEC VR5400 instruction.  */
+#define AFL_EXT_5500         16  /* NEC VR5500 instruction.  */
+#define AFL_EXT_LOONGSON_2E  17  /* ST Microelectronics Loongson 2E.  */
+#define AFL_EXT_LOONGSON_2F  18  /* ST Microelectronics Loongson 2F.  */
+
+/* Values defined for Tag_GNU_MIPS_ABI_FP.  */
+#define Val_GNU_MIPS_ABI_FP_ANY    0  /* Not tagged or not using any ABIs affected by the differences.  */
+#define Val_GNU_MIPS_ABI_FP_DOUBLE 1  /* Using hard-float -mdouble-float.  */
+#define Val_GNU_MIPS_ABI_FP_SINGLE 2  /* Using hard-float -msingle-float.  */
+#define Val_GNU_MIPS_ABI_FP_SOFT   3  /* Using soft-float.  */
+#define Val_GNU_MIPS_ABI_FP_OLD_64 4  /* Using -mips32r2 -mfp64.  */
+#define Val_GNU_MIPS_ABI_FP_XX     5  /* Using -mfpxx */
+#define Val_GNU_MIPS_ABI_FP_64     6  /* Using -mips32r2 -mfp64.  */
+#define Val_GNU_MIPS_ABI_MSA_ANY   0  /* Not tagged or not using any ABIs affected by the differences.  */
+#define Val_GNU_MIPS_ABI_MSA_128   1  /* Using 128-bit MSA.  */
+
+/* MIPS ABI flags structure */
+  .struct 0
+ABIFlags_version:
+  .struct ABIFlags_version + 2
+ABIFlags_isa_level:
+  .struct ABIFlags_isa_level + 1
+ABIFlags_isa_rev:
+  .struct ABIFlags_isa_rev + 1
+ABIFlags_gpr_size:
+  .struct ABIFlags_gpr_size + 1
+ABIFlags_cpr1_size:
+  .struct ABIFlags_cpr1_size + 1
+ABIFlags_cpr2_size:
+  .struct ABIFlags_cpr2_size + 1
+ABIFlags_fp_abi:
+  .struct ABIFlags_fp_abi + 1
+ABIFlags_isa_ext:
+  .struct ABIFlags_isa_ext + 4
+ABIFlags_ases:
+  .struct ABIFlags_ases + 4
+ABIFlags_flags1:
+  .struct ABIFlags_flags1 + 4
+ABIFlags_flags2:
+  .struct ABIFlags_flags2 + 4
+
+/*> EOF abiflags.S <*/
diff --git a/libgloss/mips/hal/cache.h b/libgloss/mips/hal/cache.h
new file mode 100644
index 000000000..5cb90e212
--- /dev/null
+++ b/libgloss/mips/hal/cache.h
@@ -0,0 +1,82 @@ 
+/*
+ * 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 __MIPS_NO_IMPLICIT_EHB	/* No implicit EHB after mtc0 */
+#include <mips/cpu.h>
+#include <mips/cm3.h>
+#include <mips/m32c0.h>
+#include <mips/m64c0.h>
+#include <mips/hal.h>
+
+#if defined(__mips64) || (__mips == 64)
+#define mips_getentryhi()	mips64_getentryhi()
+#define mips_setentryhi(v)	mips64_setentryhi(v)
+#define mips_getentrylo0()	mips64_getentrylo0()
+#define mips_setentrylo0(v)	mips64_setentrylo0(v)
+#define mips_getentrylo1()	mips64_getentrylo1()
+#define mips_setentrylo1(v)	mips64_setentrylo1(v)
+#define mips_getpagemask()	mips64_getpagemask()
+#define mips_setpagemask(v)	mips64_setpagemask(v)
+#define mips_getindex()		mips64_getindex()
+#define mips_setindex(v)	mips64_setindex(v)
+#define mips_getcmgcrbase()	mips64_get_c0(C0_CMGCRBASE)
+#else
+#define mips_getentryhi()	mips32_getentryhi()
+#define mips_setentryhi(v)	mips32_setentryhi(v)
+#define mips_getentrylo0()	mips32_getentrylo0()
+#define mips_setentrylo0(v)	mips32_setentrylo0(v)
+#define mips_getentrylo1()	mips32_getentrylo1()
+#define mips_setentrylo1(v)	mips32_setentrylo1(v)
+#define mips_getpagemask()	mips32_getpagemask()
+#define mips_setpagemask(v)	mips32_setpagemask(v)
+#define mips_getindex()		mips32_getindex()
+#define mips_setindex(v)	mips32_setindex(v)
+#define mips_getcmgcrbase()	mips32_get_c0(C0_CMGCRBASE)
+#endif
+
+static inline __attribute__((always_inline)) _MIPS_HAL_NOMIPS16
+void mips_cache_op (vaddr_t kva, size_t n, int lsize, const int op)
+{
+  vaddr_t addr, maxaddr, mask;
+
+  if (n <= 0)
+    return;
+
+  mask = ~ (lsize - 1);
+  addr = (kva & mask) - lsize;
+  maxaddr = ((kva + n) - 1) & mask;
+
+  do
+    {
+      addr = addr + lsize;
+      mips_cache (op, addr);
+    }
+  while (addr != maxaddr);
+
+  return;
+}
diff --git a/libgloss/mips/hal/crt0.S b/libgloss/mips/hal/crt0.S
new file mode 100644
index 000000000..ac6e614df
--- /dev/null
+++ b/libgloss/mips/hal/crt0.S
@@ -0,0 +1,312 @@ 
+/*
+ * crt0.S -- startup file for MIPS.
+ *
+ * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support
+ * Copyright (C) 2016-2018 MIPS Tech, LLC
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+/* This file does not use any floating-point ABI.  */
+	.gnu_attribute 4,0
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include "abiflags.S"
+
+MIPS_NOMIPS16
+
+#define STARTUP_STACK_SIZE	0x40	  /* Temporary stack size to run C code */
+
+	.section .startdata, "aw", @nobits
+	.balign 16
+	.space	STARTUP_STACK_SIZE
+__lstack: # Points to the end of the stack
+__ram_extent:
+	.space 8
+
+	.data
+
+	.balign	SZREG
+__temp_space:	   /* Temporary space to save arguments */
+	.space	SZREG * 3
+
+	.text
+	.align	2
+
+/*
+ * Without the following nop, GDB thinks _start is a data variable.
+ * This is probably a bug in GDB in handling a symbol that is at the
+ * start of the .text section.
+ */
+	nop
+
+	.globl	hardware_hazard_hook .text
+	.globl	_start
+	.ent	_start
+_start:
+#if __mips<3
+#  define STATUS_MASK (SR_CU1|SR_PE)
+#else
+/* Post-mips2 has no SR_PE bit.  */
+#  ifdef __mips64
+/* Turn on 64-bit addressing and additional float regs.  */
+#    define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX)
+#  else
+#    if __mips_fpr==32
+#      define STATUS_MASK (SR_CU1)
+#    else
+/* Turn on additional float regs.  */
+#      define STATUS_MASK (SR_CU1|SR_FR)
+#    endif
+#  endif
+#endif
+
+	/* Save argument registers */
+	LA	t0, __temp_space
+	REG_S	a0, (SZREG * 0)(t0)
+	REG_S	a1, (SZREG * 1)(t0)
+	REG_S	a2, (SZREG * 2)(t0)
+
+	/* 
+	 * Save k0, k1, ra and sp and register
+	 * default exception handler.
+	*/
+	.weak	__register_excpt_handler
+	LA	t9, __register_excpt_handler
+	beqz	t9, 1f
+	move	a0, ra		/* save ra */
+	jalr	t9
+	b	2f
+1:
+	/* Clear Cause register.  */
+	mtc0	zero,C0_CAUSE
+	move	va0,zero			/* Mask for C0_SR.  */
+2:
+	/* Read MIPS_abiflags structure and set status/config registers
+	   accordingly.  */
+	.weak	__MIPS_abiflags_start
+	.weak	__MIPS_abiflags_end
+	LA	t0,__MIPS_abiflags_start
+	LA	t1,__MIPS_abiflags_end
+	PTR_ADDU t1,t1,-24
+
+	/* Branch to 1f is the .MIPS.abiflags section is not 24 bytes.  This
+	   indicates it is either missing or corrupt.  */
+	bne	t0,t1,1f
+
+	/* Check isa_level.  */
+	lbu	t1,ABIFlags_isa_level(t0)
+	sltu	t2,t1,3			/* Is MIPS < 3?  */
+	xori	t1,t1,64		/* Is MIPS64?  */
+	beq	t2,zero,3f
+	li	t2,SR_PE
+	or	va0,va0,t2		/* Enable soft reset.  */
+3:
+	li	t2,(SR_KX|SR_SX|SR_UX)
+	bne	t1,zero,3f
+	or	va0,va0,t2		/* Enable extended addressing.  */
+3:
+	/* Check DSP,DSP2,MDMX ase. */
+	lw      t1,ABIFlags_ases(t0)
+	andi    t1,t1,(AFL_ASE_DSP|AFL_ASE_DSPR2|AFL_ASE_MDMX)
+	li	t2,SR_MX
+	beq	t1,zero,3f
+	or	va0,va0,t2
+3:
+	/* Check fp_abi.  */
+	lbu	t1,ABIFlags_fp_abi(t0)
+	xori	t1,t1,Val_GNU_MIPS_ABI_FP_SOFT
+	li	t2,SR_CU1
+	beq	t1,zero,2f		/* Skip MSA and cpr1_size checks.  */
+	or	va0,va0,t2		/* Enable co-processor 1.  */
+
+	/* Check cpr1_size.  */
+	lbu	t1,ABIFlags_cpr1_size(t0)
+	xori	t1,t1,AFL_REG_64
+	li	t2,SR_FR
+	bne	t1,zero,3f
+	or	va0,va0,t2		/* Enable 64-bit FPU registers.  */
+3:
+	/* Check MSA ASE.  */
+	lw	t1,ABIFlags_ases(t0)
+	andi	t1,t1,AFL_ASE_MSA
+	li	t2,SR_FR
+	beq	t1,zero,2f
+	or	va0,va0,t2		/* Enable 64-bit FPU registers.  */
+	li	t2,CFG5_MSAEN
+	mtc0	t2,C0_CONFIG,5		/* Enable MSA.  */
+	b	2f
+
+1:
+	/* MIPS_abiflags structure is not available.  Set status/config
+	   registers based on flags defined by compiler.  */
+#ifdef __mips_soft_float
+	li	va0,(STATUS_MASK-(STATUS_MASK & SR_CU1))
+#else
+	li	va0,STATUS_MASK
+#endif
+
+2:
+	/* Set C0_SR,  */
+	mtc0	va0,C0_SR
+	ehb
+
+	/* set the global data pointer */
+	LA	gp, _gp
+	.end _start
+
+/*
+ * zero out the bss section.
+ */
+	.globl	_get_ram_info .text
+	.globl	__stack
+	.globl	__global
+	.ent	zerobss
+zerobss:
+	LA	t0, _fbss
+	LA	t1, _end
+	beq	t0,t1,1f
+2:
+	PTR_ADDU t0,t0,4
+	sw	zero,-4(t0)
+	bne	t0,t1,2b
+1:
+	/* setup the stack pointer */
+	LA	t0, __stack			/* is __stack set? */
+	bne	t0,zero,1f
+
+	LA	sp, __lstack			/* make a small stack so we can */
+						/* run some C code */
+	li	a0,0				/* no need for the ram base */
+	LA	a1, __ram_extent		/* storage for the extent of ram */
+	jal	_get_ram_range
+
+	/* NOTE: a0[0] contains the last address+1 of memory. */
+	LA	a0, __ram_extent
+	PTR_L	t0,0(a0)			/* the extent of ram */
+	lw	$0,-4(t0)			/* check for valid memory */
+	/* Allocate 32 bytes for the register parameters.  Allocate 16
+	   bytes for a null argv and envp.  Round the result up to 64
+	   bytes to preserve alignment.  */
+1:
+	PTR_ADDU t0,t0,-64
+	move	sp,t0				/* set stack pointer */
+	.end	zerobss
+
+/*
+ * initialize target specific stuff. Only execute these
+ * functions it they exist.
+ */
+	.globl	hardware_init_hook .text
+	.globl	software_init_hook .text
+	.type	_fini,@function
+	.type	_init,@function
+	.globl	atexit .text
+	.globl	exit .text
+	.ent	init
+init:
+	/* Init the hardware if needed */
+	LA	t9, hardware_init_hook
+	beq	t9,zero,1f
+	jalr	t9
+1:
+	/* Init the software if needed */
+	LA	t9, software_init_hook
+	beq	t9,zero,1f
+	jalr	t9
+1:
+	/* Register exit handlers */
+	LA	a0, _fini
+	jal	atexit
+
+	/* run global constructors */
+	jal	_init
+
+	/* Restore argument registers */
+	LA	t0, __temp_space
+	REG_L	a0,(SZREG * 0)(t0)
+	REG_L	a1,(SZREG * 1)(t0)
+	REG_L	a2,(SZREG * 2)(t0)
+
+	/* Convert pointers potentially */
+	.weak	__convert_argv_pointers
+	LA	t0, __convert_argv_pointers
+	beqz	t0, 1f
+	jalr	t0
+1:
+	/* if a0 > 0 then we have arguments ready in a0 to a2 registers */
+	bgtz	a0,.Lmain
+	/* if a0 == 0 then no arguments have been set up */
+	beqz	a0, 1f
+	/* if a0 < -1 then we have undefined behaviour so assume no
+	   arguments have been set up */
+	addiu	t0, a0, 1
+	bltz	t0, 1f
+
+	/* a0 == -1 */
+	.weak	__getargs
+	LA	t0, __getargs
+	beqz	t0, 1f
+	jalr	t0				/* get arguments */
+	b	.Lmain
+1:
+	/* no arguments */
+	move	a0,zero				/* set argc to 0 */
+	PTR_ADDU a1,sp,32			/* argv = sp + 32 */
+	PTR_ADDU a2,sp,40			/* envp = sp + 40 */
+	REG_S	zero,(a1)			/* argv[argc] = 0 */
+	REG_S	zero,(a2)			/* envp[0] = 0 */
+
+.Lmain:
+	jal	main				/* call the program start function */
+	move	a0,va0				/* pass through the exit code */
+	jal	exit				/* call libc exit to run the G++ */
+						/* destructors */
+	.end	init
+
+/*
+ * _exit -- Exit from the application. Normally we cause a user trap
+ *          to return to the ROM monitor for another run. NOTE: This is
+ *	    the only other routine we provide in the crt0.o object, since
+ *          it may be tied to the "_start" routine. It also allows
+ *          executables that contain a complete world to be linked with
+ *          just the crt0.o object.
+ */
+	.globl	hardware_exit_hook .text
+	.globl	_exit
+	.ent _exit
+_exit:
+1:
+	/* Save exit code */
+	LA	t0, __temp_space
+	REG_S	a0,0(t0)
+
+	LA	t0, hardware_exit_hook
+	beq	t0,zero,2f
+	jalr	t0
+2:
+
+	/* Restore return value from main */
+	LA	t0, __temp_space
+	REG_L	a0,0(t0)
+
+	.global __exit .text
+	jal	__exit
+
+	/* The BREAK instruction can cope with 0xfffff, but GAS limits the
+	   range */
+	break	1023
+	b	1b				# but loop back just in-case
+	.end _exit
+ 
+/* EOF crt0.S */
diff --git a/libgloss/mips/hal/get_ram_range.c b/libgloss/mips/hal/get_ram_range.c
new file mode 100644
index 000000000..61711e051
--- /dev/null
+++ b/libgloss/mips/hal/get_ram_range.c
@@ -0,0 +1,65 @@ 
+/*
+ * 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.
+*/
+
+#include <_ansi.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if _MIPS_SIM == _ABI64
+# define K0BASE 0xFFFFFFFF80000000LL
+#else
+# define K0BASE 0x80000000
+#endif
+void
+_get_ram_range (void **ram_base, void **ram_extent)
+{
+  struct s_mem
+  {
+    unsigned int size;
+    unsigned int icsize;
+    unsigned int dcsize;
+  } mem;
+  void get_mem_info (struct s_mem*);
+
+  /* The sizeof (s_mem.size) must be 4 bytes.  The compiler should be
+     able to eliminate this check */
+  if (sizeof (unsigned int) != 4)
+    {
+      *ram_extent = 0;
+      return;
+    }
+
+  get_mem_info (&mem);
+
+  /* NOTE: The value returned from the get_mem_info call is the amount
+     of memory, and not the address of the (last byte + 1) */
+
+  if (ram_base)
+    *ram_base = (void*)K0BASE;
+  *ram_extent = (void*)(long)(K0BASE + mem.size);
+}
diff --git a/libgloss/mips/hal/libcm3.a b/libgloss/mips/hal/libcm3.a
new file mode 100644
index 000000000..7b7f49b69
--- /dev/null
+++ b/libgloss/mips/hal/libcm3.a
@@ -0,0 +1,34 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * libcm3.a - Create a reference to __cache_size_hook near the
+ * start of the link to include the actual implementation.
+ */
+EXTERN (__cache_size_hook);
+GROUP(-lcm3_impl);
diff --git a/libgloss/mips/hal/link.c b/libgloss/mips/hal/link.c
new file mode 100644
index 000000000..d4de6f98a
--- /dev/null
+++ b/libgloss/mips/hal/link.c
@@ -0,0 +1,39 @@ 
+/*
+ * 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.
+*/
+
+#include <errno.h>
+
+int
+link (const char *oldname, const char *newname)
+{
+  (void) oldname;
+  (void) newname;
+  errno = EIO;
+  return -1;
+}
+
diff --git a/libgloss/mips/hal/minicrt.S b/libgloss/mips/hal/minicrt.S
new file mode 100644
index 000000000..fa4759499
--- /dev/null
+++ b/libgloss/mips/hal/minicrt.S
@@ -0,0 +1,31 @@ 
+#include <mips/asm.h>
+#include <mips/regdef.h>
+
+LEAF(_start)
+	/* Preserve return address */
+	move s0, ra
+	/* Set up global pointer for small data access */
+	LA gp, _gp
+	/* Set up stack pointer */
+	LA sp, __stack
+	/* Zero the BSS */
+	LA v0, _fbss
+	LA v1, _end
+	beq v0,v1,2f
+1:
+	addiu v0,v0,4
+	sw zero,-4(v0)
+	bne v0,v1,1b
+2:
+	/* Set arguments to be null for main */
+	li a0, 0
+
+	/* Reserve the ABI required argument area */
+	addiu sp, sp, -(NARGSAVE * SZARG)
+	/* Jump to C code */
+	jal main
+
+	/* Return to boot */
+	move ra, s0
+	jr ra
+END(_start)
diff --git a/libgloss/mips/hal/mips64_tlb.c b/libgloss/mips/hal/mips64_tlb.c
new file mode 100644
index 000000000..6e96e757d
--- /dev/null
+++ b/libgloss/mips/hal/mips64_tlb.c
@@ -0,0 +1,219 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+#include <mips/hal.h>
+
+/* Writes hi, lo0, lo1 and mask into the TLB entry specified by index */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+m64_tlbwi2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
+	    unsigned long long mask,
+	    int index)
+{
+  mips64_setentryhi (hi);
+  mips64_setentrylo0 (lo0);
+  mips64_setentrylo1 (lo1);
+  mips64_setpagemask (mask);
+  mips64_setindex (index);
+  mips_ehb ();
+  mips_tlbwi ();
+  return;
+}
+
+/* 
+ * Writes hi, lo0, lo1 and mask into the TLB entry specified by the
+ * Random register.
+*/
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+m64_tlbwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
+	    unsigned long long mask)
+{
+  mips64_setentryhi (hi);
+  mips64_setentrylo0 (lo0);
+  mips64_setentrylo1 (lo1);
+  mips64_setpagemask (mask);
+  mips_ehb ();
+  mips_tlbwr ();
+  return;
+}
+
+/* 
+ * Probes the TLB for an entry matching hi and if present rewrites that entry,
+ * otherwise updates a random entry. A safe way to update the TLB.
+*/
+int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+m64_tlbrwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
+	     unsigned long long mask)
+{
+  tlbhi64_t prev_hi;
+  int index;
+
+  prev_hi = mips64_getentryhi ();
+  mips64_setentryhi (hi);
+
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbp ();
+  mips_ehb ();	/* tlbp hazard on mfc0 */
+
+  index = mips64_getindex ();
+
+  mips64_setentrylo0 (lo0);
+  mips64_setentrylo1 (lo1);
+  mips64_setpagemask (mask);
+
+  mips_ehb ();	/* mtc0 hazard on tlbwi/tlbwr */
+
+  if (index < 0)
+    mips_tlbwr ();
+  else
+    mips_tlbwi ();
+
+  mips64_setentryhi (prev_hi);
+
+  return index;
+}
+
+/*
+ * Reads the TLB entry specified index, and returns the EntryHi,
+ * EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmask
+ * respectively.
+*/
+void _MIPS_HAL_NOMIPS16
+m64_tlbri2 (tlbhi64_t *phi, tlblo64_t *plo0, tlblo64_t *plo1,
+	    unsigned long long *pmask, int index)
+{
+  mips64_setindex (index);
+  mips_ehb ();	/* mtc0 hazard on tlbr */
+  mips_tlbr ();
+  mips_ehb ();	/* tlbr hazard on mfc0 */
+  *phi = mips64_getentryhi ();
+  *plo0 = mips64_getentrylo0 ();
+  *plo1 = mips64_getentrylo1 ();
+  *pmask = mips64_getpagemask ();
+  return;
+}
+
+/* 
+ * Probes the TLB for an entry matching hi and returns its index, or -1 if
+ * not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of the
+ * entry are also returned in *plo0, *plo1 and *pmask respectively.
+*/
+int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+m64_tlbprobe2 (tlbhi64_t hi, tlblo64_t *plo0, tlblo64_t *plo1,
+	       unsigned long long *pmask)
+{
+  tlbhi64_t prev_hi;
+  int index;
+
+  prev_hi = mips64_getentryhi ();
+  mips64_setentryhi (hi);
+
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbp ();
+  mips_ehb ();	/* tlbp hazard on mfc0 */
+
+  index = mips64_getindex ();
+
+  if (index >= 0)
+    {
+      mips_tlbr ();
+      mips_ehb ();	/* tlbr hazard on mfc0 */
+      *plo0 = mips64_getentrylo0 ();
+      *plo1 = mips64_getentrylo1 ();
+      *pmask = mips64_getpagemask ();
+    }
+  else
+    index = -1;
+
+  mips64_setentryhi (prev_hi);
+
+  return index;
+}
+
+/* Probes the TLB for an entry matching hi, and if present invalidates it */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+m64_tlbinval (tlbhi64_t hi)
+{
+  int index, tmp_idx;
+  tlbhi64_t prev_hi, tmp_hi;
+  register const unsigned long zero = 0;
+  unsigned long cfg;
+
+  prev_hi = mips64_getentryhi ();
+  mips64_setentryhi (hi);
+
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbp ();
+  mips_ehb ();	/* tlbp hazard on mfc0 */
+
+  index = mips64_getindex ();
+
+  if (index < 0)
+    goto restore;
+
+  mips64_setentrylo0 (zero);
+  mips64_setentrylo1 (zero);
+
+  /* Check if Config4 is implemented */
+  cfg = mips64_getconfig3 ();
+  if ((cfg & CFG3_M) != 0)
+    {
+      cfg = mips64_getconfig4 ();
+      if ((cfg & CFG4_IE_MASK) != 0)
+	{
+	  tmp_hi = C0_ENTRYHI_EHINV_MASK;
+	  goto do_tlbwi;
+	}
+    }
+
+  tmp_hi = (tlbhi64_t) ((unsigned long) KSEG0_BASE - 0x4000);
+
+  do
+    {
+      tmp_hi = tmp_hi + 0x4000;
+      mips64_setentryhi (tmp_hi);
+      mips_ehb ();		/* mtc0 hazard on tlbp */
+      mips_tlbp ();
+      mips_ehb ();		/* tlbp hazard on mfc0 */
+      tmp_idx = mips64_getindex ();
+    }
+  while (tmp_idx >= 0);
+
+  mips64_setindex (index);	/* restore Index */
+
+do_tlbwi:
+  mips64_setentryhi (tmp_hi);
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbwi ();
+  mips_ehb ();	/* tlbwi hazard on mfc0 */
+
+restore:
+  mips64_setentryhi (prev_hi); /* restore EntryHi */
+
+  return;
+}
diff --git a/libgloss/mips/hal/mips_clean_cache.c b/libgloss/mips/hal/mips_clean_cache.c
new file mode 100644
index 000000000..e749e8fd5
--- /dev/null
+++ b/libgloss/mips/hal/mips_clean_cache.c
@@ -0,0 +1,113 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include <mips/hal.h>
+#include "cache.h"
+
+/* Writeback and invalidate address range in all caches */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_clean_cache (vaddr_t kva, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If D-cache is present */
+  if (mips_dcache_linesize > 0)
+    mips_cache_op (kva, n, mips_dcache_linesize, Hit_Writeback_Inv_D);
+
+  /* If I-cache is present */
+  if (mips_icache_linesize > 0)
+    mips_cache_op (kva, n, mips_icache_linesize, Hit_Invalidate_I);
+
+  /* If L2-cache is present */
+  if (mips_scache_linesize > 0)
+    mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S);
+
+  mips_sync ();
+  return;
+}
+
+/* Writeback and invalidate address range in I-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_clean_icache (vaddr_t kva, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If I-cache is present */
+  if (mips_icache_linesize > 0)
+    mips_cache_op (kva, n, mips_icache_linesize, Hit_Invalidate_I);
+
+  /* If L2-cache is present */
+  if (mips_scache_linesize > 0)
+    mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S);
+
+  mips_sync ();
+  return;
+}
+
+/* Writeback and invalidate address range in D-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_clean_dcache (vaddr_t kva, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If D-cache is present */
+  if (mips_dcache_linesize > 0)
+    mips_cache_op (kva, n, mips_dcache_linesize, Hit_Writeback_Inv_D);
+
+  /* If L2-cache is present */
+  if (mips_scache_linesize > 0)
+    mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S);
+
+  mips_sync ();
+  return;
+}
+
+/* 
+ * Invalidate but don't writeback address range in data caches
+ * Only safe if region is totally cache-line aligned. 
+*/
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_clean_dcache_nowrite (vaddr_t kva, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If D-cache is present */
+  if (mips_dcache_linesize > 0)
+    mips_cache_op (kva, n, mips_dcache_linesize, Hit_Invalidate_D);
+
+  /* If L2-cache is present */
+  if (mips_scache_linesize > 0)
+    mips_cache_op (kva, n, mips_scache_linesize, Hit_Invalidate_S);
+
+  mips_sync ();
+  return;
+}
diff --git a/libgloss/mips/hal/mips_cm3_l2size.c b/libgloss/mips/hal/mips_cm3_l2size.c
new file mode 100644
index 000000000..ae93202e7
--- /dev/null
+++ b/libgloss/mips/hal/mips_cm3_l2size.c
@@ -0,0 +1,88 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+
+_MIPS_HAL_NOMIPS16
+void __def_cache_size_hook (void);
+
+/*
+ * Routine for calculating L2 cache size from CM3 configuration
+ * registers.  Sizing information is stored directly to memory. 
+*/
+void _MIPS_HAL_NOMIPS16
+__cache_size_hook (void)
+{
+  unsigned long cm_gcr_base, cm_gcr_l2_config;
+  int associ;
+
+  /* 
+   * Fall back to Config2 based L2 if Config3[M] or Config4[M]
+   * or Config5[L2C] is not present.
+  */
+  if ((mips32_getconfig3 () & CFG3_M) == 0
+      || (mips32_getconfig4 () & CFG4_M) == 0
+      || (mips32_getconfig5 () & CFG5_L2C) == 0)
+    {
+      __def_cache_size_hook ();
+      return;
+    }
+
+  /* Read CMGCRBase to find CMGCR_BASE_ADDR */
+  cm_gcr_base = (mips_getcmgcrbase () << 4) | 0xB0000000UL;
+
+  /* Read GCR_L2_CONFIG */
+  cm_gcr_l2_config = * ((unsigned long *) (cm_gcr_base + GCR_L2_CONFIG));
+
+  /* Extract line size */
+  mips_scache_linesize = (cm_gcr_l2_config & GCR_L2_SL_MASK) >> GCR_L2_SL_SHIFT;
+
+  /* Check for no cache */
+  if (mips_scache_linesize == 0)
+    return;
+  
+  /* Now have true L2 line size */
+  mips_scache_linesize = 2 << mips_scache_linesize;
+
+  /* Extract sets/way */
+  mips_scache_ways = (cm_gcr_l2_config & GCR_L2_SS_MASK) >> GCR_L2_SS_SHIFT;
+
+  /* Now we have true L2 sets/way */
+  mips_scache_ways = 64 << mips_scache_ways;
+  
+  /* Extract L2 associativity */
+  associ = (cm_gcr_l2_config & GCR_L2_SA_MASK) >> GCR_L2_SA_SHIFT;
+
+  /* Get total number of sets */
+  associ = (associ + 1) * mips_scache_ways;
+
+  /* L2 cache size */
+  mips_scache_size = mips_scache_linesize * associ;
+
+  return;
+}
diff --git a/libgloss/mips/hal/mips_dsp.S b/libgloss/mips/hal/mips_dsp.S
new file mode 100644
index 000000000..da4b8b33c
--- /dev/null
+++ b/libgloss/mips/hal/mips_dsp.S
@@ -0,0 +1,127 @@ 
+/*
+ * Copyright (C) 2016-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.
+*/
+
+.set nomips16
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+
+#
+# FUNCTION:	_dsp_save
+# DESCRIPTION:	save the DSP context.
+# RETURNS:	int
+#		0:	No context saved
+#		CTX_*:	Type of conext stored
+#
+LEAF(_dsp_save)
+	move	a1, a0
+	PTR_S	zero, LINKCTX_NEXT(a1)
+	move    va0, zero
+
+	/* Test for DSP support */
+	mfc0	t0, C0_CONFIG3
+	ext	t0, t0, CFG3_DSPP_SHIFT, 1
+	beqz    t0, 1f
+
+	/* Test for DSP enabled */
+	mfc0	t0, C0_STATUS
+	ext	t0, t0, SR_MX_SHIFT, 1
+	beqz	t0, 1f
+
+	li	va0, LINKCTX_TYPE_DSP
+	.set push
+	.set dsp
+	rddsp	t1
+	mfhi	t2, $ac1
+	mflo	t3, $ac1
+	mfhi	t4, $ac2
+	mflo	t5, $ac2
+	mfhi	t6, $ac3
+	mflo	t7, $ac3
+	.set pop
+	sw	t1, DSPCTX_DSPC(a1)
+	sw	t2, DSPCTX_HI1(a1)
+	sw	t3, DSPCTX_LO1(a1)
+	sw	t4, DSPCTX_HI2(a1)
+	sw	t5, DSPCTX_LO2(a1)
+	sw	t6, DSPCTX_HI3(a1)
+	sw	t7, DSPCTX_LO3(a1)
+	REG_S	va0, LINKCTX_ID(a1)
+1:
+	jr ra
+END(_dsp_save)
+
+#
+# FUNCTION:	_dsp_load
+# DESCRIPTION:	load the DSP context.
+# RETURNS:	int
+#		0:	Unrecognised context
+#		CTX_*:	Type of context restored
+#
+LEAF(_dsp_load)
+	move	a1, a0
+	REG_L   va0, LINKCTX_ID(a1)
+	li	v1, LINKCTX_TYPE_DSP
+	bne	va0,v1,1f
+
+	/* Test for DSP support */
+	mfc0	t0, C0_CONFIG3
+	ext	t0, t0, CFG3_DSPP_SHIFT, 1
+	beqz    t0, 1f
+
+	/* Force on DSP */
+	di	t3
+	ehb
+	or	t3, t3, SR_MX
+	mtc0	t3, C0_STATUS
+	ehb
+
+	lw	t1, DSPCTX_DSPC(a1)
+	lw	t2, DSPCTX_HI1(a1)
+	lw	t3, DSPCTX_LO1(a1)
+	lw	t4, DSPCTX_HI2(a1)
+	lw	t5, DSPCTX_LO2(a1)
+	lw	t6, DSPCTX_HI3(a1)
+	lw	t7, DSPCTX_LO3(a1)
+	.set push
+	.set dsp
+	wrdsp	t1
+	mthi	t2, $ac1
+	mtlo	t3, $ac1
+	mthi	t4, $ac2
+	mtlo	t5, $ac2
+	mthi	t6, $ac3
+	mtlo	t7, $ac3
+	.set pop
+	jr ra
+1:
+	/* Don't recognise this context, fail */
+	move	va0, zero
+	jr ra
+END(_dsp_load)
diff --git a/libgloss/mips/hal/mips_excpt_boot.S b/libgloss/mips/hal/mips_excpt_boot.S
new file mode 100644
index 000000000..342afb9e8
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_boot.S
@@ -0,0 +1,378 @@ 
+/*
+ * 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.
+*/
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+
+MIPS_NOMIPS16
+
+	# Create space to store k0, k1, ra and sp
+	.data
+	.global	__start_ctx
+	.balign	SZREG
+__start_ctx:
+	.space	SZREG * 18
+#define	start_ctx_sr	(SZREG * 0)
+#define	start_ctx_s0	(SZREG * 1)
+#define	start_ctx_s1	(SZREG * 2)
+#define	start_ctx_s2	(SZREG * 3)
+#define	start_ctx_s3	(SZREG * 4)
+#define	start_ctx_s4	(SZREG * 5)
+#define	start_ctx_s5	(SZREG * 6)
+#define	start_ctx_s6	(SZREG * 7)
+#define	start_ctx_s7	(SZREG * 8)
+#define	start_ctx_k0	(SZREG * 9)
+#define	start_ctx_k1	(SZREG * 10)
+#define	start_ctx_gp	(SZREG * 11)
+#define	start_ctx_sp	(SZREG * 12)
+#define	start_ctx_fp	(SZREG * 13)
+#define	start_ctx_ra	(SZREG * 14)
+#define	start_ctx_ictl	(SZREG * 15)
+#define	start_ctx_ebase	(SZREG * 16)	/* saved EBASE */
+#define	chain_ebase	(SZREG * 17)	/* chained EBASE */
+
+#if defined (__mips_micromips)
+	.space	SZREG
+#define	start_ctx_conf3	(SZREG * 18)	/* saved Config3 $16,3 for micromips */
+#endif
+
+#
+# FUNCTION:	void* __register_excpt_boot (void*, int, void*)
+#
+# DESCRIPTION: Save all boot state. Some state is already clobbered but passed
+#	       in as arguments:
+#              a0 = Boot ra
+#	       a1 = Boot SR
+#	       a2 = caller's RA (to be returned back)
+#
+WLEAF(__register_excpt_boot)
+	.set	push
+	.set	noat
+
+	/* Save C0_SR IE and BEV */
+	LA	t1, __start_ctx
+	REG_S	a0, start_ctx_ra(t1)
+	REG_S	a1, start_ctx_sr(t1)
+
+	REG_S	s0, start_ctx_s0(t1)
+	REG_S	s1, start_ctx_s1(t1)
+	REG_S	s2, start_ctx_s2(t1)
+	REG_S	s3, start_ctx_s3(t1)
+	REG_S	s4, start_ctx_s4(t1)
+	REG_S	s5, start_ctx_s5(t1)
+	REG_S	s6, start_ctx_s6(t1)
+	REG_S	s7, start_ctx_s7(t1)
+	REG_S	k0, start_ctx_k0(t1)
+	REG_S	k1, start_ctx_k1(t1)
+	REG_S	gp, start_ctx_gp(t1)
+	REG_S	sp, start_ctx_sp(t1)
+	REG_S	fp, start_ctx_fp(t1)
+
+#if defined (__mips_micromips)
+	/* Save Config3 */
+	mfc0	t0, C0_CONFIG3
+	REG_S	t0, start_ctx_conf3(t1)
+#endif
+	mfc0	t0, C0_INTCTL
+	REG_S	t0, start_ctx_ictl(t1)
+
+	/* Save C0_EBASE */
+	PTR_MFC0 t2, C0_EBASE
+	REG_S	t2, start_ctx_ebase(t1)
+
+	/* Check if we booted with BEV==1 */
+	ext	t3, a1, SR_BEV_SHIFT, 1
+	beqz	t3, 1f
+
+	/*
+	 * BEV==0 - set chain_ebase to 0xbfc00200
+	 * Apply the offset of 0x200 so that the boot vector entries line up
+	 * with the offsets in a non-boot vectora.
+	 */
+	li	t2, 0xbfc00200
+
+	/* No - set chain_ebase to C0_EBASE */
+1:	REG_S	t2, chain_ebase(t1)
+
+	/* Return the third argument */
+	move	va0, a2
+	jr	ra
+
+	.set	pop
+WEND(__register_excpt_boot)
+
+#
+# FUNCTION:	int __return_to_boot (int)
+#
+# DESCRIPTION: This is used if UHI EXIT was not handled. Return back to
+#	       caller of _start.
+#	       a0 = exit code to return to caller
+#
+WLEAF(__return_to_boot)
+	.set	push
+	.set	noat
+	/* Disable interrupts for safety */
+	di
+	ehb
+	/* Set BEV=1 to allow changing EBASE */
+	mfc0	t0, C0_SR
+	li	t1, SR_BEV
+	or	t0, t0, t1
+	mtc0	t0, C0_SR
+	ehb
+
+	/* Restore C0_EBASE */
+	LA	t0, __start_ctx
+	REG_L	t0, start_ctx_ebase(t0)
+	/* Set the write gate to potentially change upper bits */
+	ori	t1, t0, EBASE_WG
+	PTR_MTC0 t1, C0_EBASE
+	ehb
+	/* Check if the write gate was set on startup */
+	andi	t1, t0, EBASE_WG
+	bnez	t1, 1f
+
+	/* If write gate wasn't set then clear the write gate again */
+	PTR_MTC0 t0, C0_EBASE
+	ehb
+
+1:	/* Restore original state */
+	LA	t0, __start_ctx
+	REG_L	s0, start_ctx_s0(t0)
+	REG_L	s1, start_ctx_s1(t0)
+	REG_L	s2, start_ctx_s2(t0)
+	REG_L	s3, start_ctx_s3(t0)
+	REG_L	s4, start_ctx_s4(t0)
+	REG_L	s5, start_ctx_s5(t0)
+	REG_L	s6, start_ctx_s6(t0)
+	REG_L	s7, start_ctx_s7(t0)
+	REG_L	k0, start_ctx_k0(t0)
+	REG_L	k1, start_ctx_k1(t0)
+	REG_L	gp, start_ctx_gp(t0)
+	REG_L	sp, start_ctx_sp(t0)
+	REG_L	fp, start_ctx_fp(t0)
+	REG_L	ra, start_ctx_ra(t0)
+
+#if defined (__mips_micromips)
+	/* Restore Config3 */
+	REG_L	t1, start_ctx_conf3(t0)
+	mtc0	t1, C0_CONFIG3
+#endif
+	/* Restore IntCtl */
+	REG_L	t1, start_ctx_ictl(t0)
+	mtc0	t1, C0_INTCTL
+
+	REG_L	t0, start_ctx_sr(t0)
+
+	/* Restore C0_STATUS IE and BEV to boot value */
+	mtc0	t0, C0_SR
+	mtc0	zero, C0_CAUSE
+
+	/* Return with exit code */
+	move	va0, a0
+	MIPS_JRHB(ra)
+	.set	pop
+WEND(__return_to_boot)
+
+#
+# FUNCTION:	void __chain_uhi_excpt (struct gpctx *);
+#
+# DESCRIPTION: Transfer to the exception handler in the boot environment.
+#	       a0 == pointer to the context to restore
+#
+WLEAF(__chain_uhi_excpt)
+	.set	push
+	.set	noat
+
+	/*
+	 * Move context pointer into position.  Use $3 as scratch
+	 * as it is the only register that is clobbered by all
+	 * UHI calls and is not used as an input.
+	 */
+	move	r3, a0
+
+#if (__mips_isa_rev < 6)
+	REG_L	t0, CTX_HI0(r3)
+	REG_L	t1, CTX_LO0(r3)
+	mthi	t0
+	mtlo	t1
+#endif
+
+	lw	t0, CTX_STATUS(r3)
+	mtc0	t0, C0_SR
+	REG_L	t0, CTX_EPC(r3)
+	PTR_MTC0 t0, C0_EPC
+	ehb
+
+	/* Restore the common context */
+	REG_L	r1, CTX_REG(1)(r3)
+	REG_L	r2, CTX_REG(2)(r3)
+	REG_L	r4, CTX_REG(4)(r3)
+	REG_L	r5, CTX_REG(5)(r3)
+	REG_L	r6, CTX_REG(6)(r3)
+	REG_L	r7, CTX_REG(7)(r3)
+	REG_L	r8, CTX_REG(8)(r3)
+	REG_L	r9, CTX_REG(9)(r3)
+	REG_L	r10, CTX_REG(10)(r3)
+	REG_L	r11, CTX_REG(11)(r3)
+	REG_L	r12, CTX_REG(12)(r3)
+	REG_L	r13, CTX_REG(13)(r3)
+	REG_L	r14, CTX_REG(14)(r3)
+	REG_L	r15, CTX_REG(15)(r3)
+	REG_L	r16, CTX_REG(16)(r3)
+	REG_L	r17, CTX_REG(17)(r3)
+	REG_L	r18, CTX_REG(18)(r3)
+	REG_L	r19, CTX_REG(19)(r3)
+	REG_L	r20, CTX_REG(20)(r3)
+	REG_L	r21, CTX_REG(21)(r3)
+	REG_L	r22, CTX_REG(22)(r3)
+	REG_L	r23, CTX_REG(23)(r3)
+	REG_L	r24, CTX_REG(24)(r3)
+	REG_L	r25, CTX_REG(25)(r3)
+	REG_L	r28, CTX_REG(28)(r3)
+	REG_L	r29, CTX_REG(29)(r3)
+	REG_L	r30, CTX_REG(30)(r3)
+	REG_L	r31, CTX_REG(31)(r3)
+
+	/* Restore chained exception handlers kernel regs */
+	LA	r3, __start_ctx
+	REG_L	k0, start_ctx_k0(r3)
+	REG_L	k1, start_ctx_k1(r3)
+
+#if defined (__mips_micromips)
+	/* OR the address with Config3.ISAOnExc bit */
+	REG_L	r3, start_ctx_conf3(r3)
+	ext	r3, r3, CFG3_IOE_SHIFT, 1
+	beqz	r3, 1f
+
+	/* Compute exception vector */
+	LA	r3, __start_ctx
+	REG_L	r3, chain_ebase(r3)
+	PTR_ADDU r3, r3, 0x181		# OR ISAOnExc bit
+
+	/* Chain */
+	jr	r3
+1:
+	/* Compute exception vector */
+	LA	r3, __start_ctx
+#endif
+
+	REG_L	r3, chain_ebase(r3)
+	PTR_ADDU r3, r3, 0x180
+
+	/* Chain */
+	jr	r3
+
+	.set	pop
+WEND(__chain_uhi_excpt)
+
+#
+# FUNCTION:	int __get_startup_BEV (void)
+#
+# DESCRIPTION: Return value of BEV flag saved in __register_excpt_handler.
+#
+WLEAF(__get_startup_BEV)
+	.set	push
+	.set	noat
+
+	LA	t0, __start_ctx
+	REG_L	va0, start_ctx_sr(t0)
+	li	t1, SR_BEV
+	and	va0, va0, t1
+	jr	ra
+
+	.set	pop
+WEND(__get_startup_BEV)
+
+
+EXPORTS(__MIPS_UHI_BAD_POINTER, 32)
+	.ascii "UHI: BAD POINTER\000"
+
+#
+# FUNCTION: __convert_argv_pointers (int, char*[], char*[])
+#
+# DESCRIPTION: Convert 64-bit pointers to 32-bit.  This allocates the new
+#	       argument structure on the stack and verifies all pointers are
+#	       canonical for a 32-bit address space.
+#
+#if _MIPS_SIM==_ABIO32 || _MIPS_SIM==_ABIN32
+WLEAF(__convert_argv_pointers)
+	/* Early out if a0 <= 0 */
+	blez	a0, .Lend
+
+	/* Verify we came from 64-bit mode */
+	LA      t0, __start_ctx
+	REG_L   t0, start_ctx_sr(t0)
+	ext	t1, t0, SR_KX_SHIFT, 1
+	beqz	t1, .Lend
+
+	/* Set up stack pointer */
+	move	t0, a0
+	sll	t1, t0, 2
+	/* Round to stack alignment */
+	addiu   t1, t1, ALSZ
+	and     t1, t1, ALMASK
+
+	PTR_SUBU sp, sp, t1
+	move	t2, sp
+	move	t3, a1
+	li	t1, -1
+
+.Lloop:
+#if BYTE_ORDER == LITTLE_ENDIAN
+	lw	t8, 0(t3)
+	lw	t9, 4(t3)
+#elif BYTE_ORDER == BIG_ENDIAN
+	lw	t9, 0(t3)
+	lw	t8, 4(t3)
+#else
+#error BYTE_ORDER
+#endif
+	/* if s1 != 0 && s1 != 0xFFFFFFFF */
+	beqz	t9, .LGoodp
+	beq	t9, t1, .LGoodp
+	/* Overwrite bad pointer with stock bad value */
+	LA	t8, __MIPS_UHI_BAD_POINTER
+.LGoodp:
+	sw	t8, 0(t2)
+
+	PTR_ADDU t2, t2, 4
+	PTR_ADDU t3, t3, 8
+	addiu	t0, t0, -1
+	bnez	t0, .Lloop
+
+	move	a1, sp
+	PTR_SUBU sp, sp, (NARGSAVE*SZARG)
+
+	move	a2, zero
+.Lend:
+	jr	ra
+WEND(__convert_argv_pointers)
+#endif /* ABI TEST */
diff --git a/libgloss/mips/hal/mips_excpt_entry.S b/libgloss/mips/hal/mips_excpt_entry.S
new file mode 100644
index 000000000..f1e6a4149
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_entry.S
@@ -0,0 +1,210 @@ 
+/*
+ * 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 _FUNCTION_SECTIONS_
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+#include <mips/ctx.S>
+
+MIPS_NOMIPS16
+
+/* Stack adjustment for ABI parameter area.  */
+#define ADJ (NARGSAVE * SZARG)
+/*
+ * Round the context size up to a 16-byte boundary which is the maximum
+ * stack alignment required for any supported ABI.
+ */
+#define CTX_SIZEROUND ((CTX_SIZE + ALSZ) & ALMASK)
+
+/*
+ * Exception entry points.  These are designed for use at EBASE when
+ * STATUS.BEV is clear.
+ * The entry points will either chain on to a user-supplied function
+ * or loop indefinitely.
+ */
+
+LEAF(__exception_entry)
+	.set	push
+	.set	noat
+.weak   _mips_tlb_refill
+	_mips_tlb_refill = __exception_save
+__tlb_refill_loop:
+	/*
+	 * Support an alternative entry point at the start of the exception
+	 * vector.  Since the exception vector is normally placed first
+	 * in the link map this allows a user to start execution from the
+	 * same address that an executable is loaded to.
+	 */
+	LA	k1, __first_boot
+	lw	k1, 0(k1)
+	beqz	k1, 1f
+	/*
+	 * The start code is responsible for clearing __first_boot prior
+	 * to installing the exception handlers.
+	 */
+	LA	k1, _start
+	jr	k1
+1:
+	/* Support the case where no handler is defined.  */
+	LA	k1, _mips_tlb_refill
+	beqz	k1, __tlb_refill_loop
+	jr	k1
+
+	.org 0x80
+.weak   _mips_xtlb_refill
+	_mips_xtlb_refill = __exception_save
+__xtlb_refill_loop:
+	LA	k1, _mips_xtlb_refill
+	beqz	k1, __xtlb_refill_loop
+	jr	k1
+
+	.org 0x100
+.weak   _mips_cache_error
+__cache_error_loop:
+	LA	k1, _mips_cache_error
+	beqz	k1, __cache_error_loop
+	jr	k1
+
+	.org 0x180
+.weak   _mips_general_exception
+__general_exception_loop:
+	/*
+	 * Free up k1, defering sp adjustment until later.  Preserving k1
+	 * may be undesirable if an exception occurs due to a corrupt
+	 * stack but since the default handlers use the user-stack to
+	 * store the context then there is nothing to lose.
+	 */
+	REG_S	k1, (-CTX_SIZEROUND + CTX_K1)(sp)
+
+	LA	k1, _mips_general_exception
+	beqz	k1, __general_exception_loop
+	jr	k1
+	.set    pop
+END(__exception_entry)
+
+/*
+ * FUNCTION:	__exception_save
+ *
+ * DESCRIPTION:	Saves the GP context to the stack and invokes
+ *		_mips_handle_exception with appropriate arguments.
+*/
+ANESTED(__exception_save, _mips_general_exception, CTX_SIZEROUND + ADJ, zero)
+	.globl  __exception_save;
+	.set	push
+	.set	noat
+
+	/* Create pointer to gp_ctx.  */
+	PTR_ADDU k1, sp, -CTX_SIZEROUND
+
+	/* Save context.  */
+	_gpctx_save
+	/* va0 now holds C0_STATUS.  */
+
+	/* Finish storing the rest of the CP0 registers.  */
+	PTR_MFC0 t0, C0_BADVADDR
+	REG_S	t0, CTX_BADVADDR(k1)
+
+#if __mips_isa_rev < 6
+	move	t0, zero
+	move	t1, zero
+	mfc0	t2, C0_CONFIG3
+	ext	t3, t2, CFG3_BP_SHIFT, 1
+	beqz	t3, 1f
+#else
+	/* MIPSR6 guarantees all CP0 regs are defined to at
+	   least return zero.  */
+#endif
+	mfc0	t0, C0_BADPINSTR
+#if __mips_isa_rev < 6
+1:
+	ext	t2, t2, CFG3_BI_SHIFT, 1
+	beqz	t2, 1f
+#endif
+	mfc0	t1, C0_BADINSTR
+1:
+	sw	t0, CTX_BADPINSTR(k1)
+	sw	t1, CTX_BADINSTR(k1)
+
+	/* Get and store the exception cause.  */
+	mfc0	t0, C0_CR
+	sw	t0, CTX_CAUSE(k1)
+
+	/* Extract the cause code for argument 1.  */
+	ext	a1, t0, CR_X_SHIFT, CR_X_BITS
+
+	/* Create the argument space.  */
+	addiu	sp, k1, -ADJ
+
+	/* Clear EXL.  Exceptions can now nest.  */
+	ins	va0, zero, SR_EXL_SHIFT, 1
+	mtc0	va0, C0_SR
+
+	/* Move the gp_ctx pointer for argument 0.  */
+	addiu	a0, sp, ADJ
+
+	/* Manually set up the return address to restore the context below.  */
+	LA	ra, __exception_restore
+
+	/* Call the handler, indirect through t9 albeit not for any specific
+	   reason.  */
+	LA	t9, _mips_handle_exception
+	jr	t9
+
+	.set pop
+END(__exception_save)
+
+/*
+ * FUNCTION:	__exception_restore
+ *
+ * DESCRIPTION:  Load the GP context from immediately above the stack
+ *		 pointer and eret.
+ */
+LEAF(__exception_restore)
+	.set	push
+	.set	noat
+
+	/* Skip past the argument save area and fall through.  */
+	addiu	a0, sp, ADJ
+
+/*
+ * FUNCTION:	__gpctx_load_eret
+ *
+ * DESCRIPTION:  Load the GP context from the address in register a0
+ *		 and eret.
+ */
+AENT(__gpctx_load_eret)
+
+	_gpctx_load
+
+	/* Return from exception.  */
+	eret
+	.set	pop
+END(__exception_restore)
diff --git a/libgloss/mips/hal/mips_excpt_handler.c b/libgloss/mips/hal/mips_excpt_handler.c
new file mode 100644
index 000000000..c763d7fb3
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_handler.c
@@ -0,0 +1,309 @@ 
+/*
+ * 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.
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <mips/cpu.h>
+#include <mips/fpa.h>
+#include <mips/hal.h>
+#include <mips/uhi_syscalls.h>
+
+/* Defined in .ld file */
+extern char __use_excpt_boot[];
+extern char __attribute__((weak)) __flush_to_zero[];
+
+#ifdef VERBOSE_EXCEPTIONS
+/*
+ * Write a string, a formatted number, then a string.
+ */
+static void
+putsnds (const char *pre, reg_t value, int digits, const char *post)
+{
+  char buf[digits];
+  int shift;
+  int idx = 0;
+
+  if (pre != NULL)
+    write (1, pre, strlen (pre));
+
+  for (shift = ((digits - 1) * 4) ; shift >= 0 ; shift -= 4)
+    buf[idx++] = "0123456789ABCDEF"[(value >> shift) & 0xf];
+  write (1, buf, digits);
+
+  if (post != NULL)
+    write (1, post, strlen (post));
+}
+
+static void
+putsns (const char *pre, reg_t value, const char *post)
+{
+  putsnds (pre, value, sizeof (reg_t) * 2, post);
+}
+
+# define WRITE(MSG) write (1, (MSG), strlen (MSG))
+# define PUTSNDS(PRE, VALUE, DIGITS, POST) \
+    putsnds ((PRE), (VALUE), (DIGITS), (POST))
+# define PUTSNS(PRE, VALUE, POST) \
+    putsns ((PRE), (VALUE), (POST))
+
+#else
+
+# define WRITE(MSG)
+# define PUTSNDS(PRE, VALUE, DIGITS, POST)
+# define PUTSNS(PRE, VALUE, POST)
+
+#endif // !VERBOSE_EXCEPTIONS
+
+/* Handle an exception */
+#ifdef VERBOSE_EXCEPTIONS
+void _MIPS_HAL_NOMIPS16
+__exception_handle_verbose (struct gpctx *ctx, int exception)
+#else
+void _MIPS_HAL_NOMIPS16
+__exception_handle_quiet (struct gpctx *ctx, int exception)
+#endif
+{
+  switch (exception)
+    {
+   case EXC_MOD:
+      WRITE ("TLB modification exception\n");
+      break;
+    case EXC_TLBL:
+      PUTSNS ("TLB error on load from 0x", ctx->badvaddr, NULL);
+      PUTSNS (" @0x", ctx->epc, "\n");
+      break;
+    case EXC_TLBS:
+      PUTSNS ("TLB error on store to 0x", ctx->badvaddr, NULL);
+      PUTSNS (" @0x", ctx->epc, "\n");
+      break;
+    case EXC_ADEL:
+      PUTSNS ("Address error on load from 0x", ctx->badvaddr, NULL);
+      PUTSNS (" @0x", ctx->epc, "\n");
+      break;
+    case EXC_ADES:
+      PUTSNS ("Address error on store to 0x", ctx->badvaddr, NULL);
+      PUTSNS (" @0x", ctx->epc, "\n");
+      break;
+    case EXC_IBE:
+      WRITE ("Instruction bus error\n");
+      break;
+    case EXC_DBE:
+      WRITE ("Data bus error\n");
+      break;
+    case EXC_SYS:
+      /* Process a UHI SYSCALL, all other SYSCALLs should have been processed
+	 by our caller.  __use_excpt_boot has following values:
+	 0 = Do not use exception handler present in boot.
+	 1 = Use exception handler present in boot if BEV
+	     is 0 at startup.
+	 2 = Always use exception handler present in boot.   */
+
+      /* Special handling for boot/low level failures.  */
+      if (ctx->t2[1] == __MIPS_UHI_BOOTFAIL)
+	{
+	  switch (ctx->a[0])
+	    {
+	    case __MIPS_UHI_BF_CACHE:
+	      WRITE ("L2 cache configuration error\n");
+	      break;
+	    default:
+	      WRITE ("Unknown boot failure error\n");
+	      break;
+	    }
+
+	  /* These are unrecoverable.  Abort.  */
+	  ctx->epc = (sreg_t)(long)&__exit;
+	  /* Exit code of 255 */
+	  ctx->a[0] = 0xff;
+	  return;
+	}
+
+      if (((long) __use_excpt_boot == 2
+	   || ((long) __use_excpt_boot == 1
+	       && __get_startup_BEV
+	       && __get_startup_BEV () == 0))
+	  && __chain_uhi_excpt)
+	/* This will not return.  */
+	__chain_uhi_excpt (ctx);
+      else
+	__uhi_indirect (ctx);
+      return;
+    case EXC_BP:
+      /* Return from exception handler if breakpoint is handled.  */
+      if (__uhi_break && __uhi_break (ctx))
+	return;
+      PUTSNS ("Breakpoint @0x", ctx->epc, "\n");
+      break;
+    case EXC_RI:
+      PUTSNS ("Illegal instruction @0x", ctx->epc, "\n");
+      break;
+    case EXC_CPU:
+      PUTSNS ("Coprocessor unusable @0x", ctx->epc, "\n");
+      break;
+    case EXC_OVF:
+      WRITE ("Overflow\n");
+      break;
+    case EXC_TRAP:
+      WRITE ("Trap\n");
+      break;
+    case EXC_MSAFPE:
+#if MIPS_MSA_USABLE
+      if (__flush_to_zero
+	  && (msa_getsr () & FPA_CSR_UNI_X)
+	  && (msa_getsr () & FPA_CSR_FS) == 0)
+	{
+	  unsigned int sr = msa_getsr ();
+	  sr &= ~FPA_CSR_UNI_X;
+	  sr |= FPA_CSR_FS;
+	  msa_setsr (sr);
+	  return;
+	}
+#endif
+      WRITE ("MSA Floating point error\n");
+      break;
+    case EXC_FPE:
+      /* Turn on flush to zero the first time we hit an unimplemented
+	 operation.  If we hit it again then stop.  */
+      if (__flush_to_zero
+	  && (fpa_getsr () & FPA_CSR_UNI_X)
+	  && (fpa_getsr () & FPA_CSR_FS) == 0)
+	{
+	  unsigned int sr = fpa_getsr ();
+	  sr &= ~FPA_CSR_UNI_X;
+	  sr |= FPA_CSR_FS;
+	  fpa_setsr (sr);
+
+	  return;
+	}
+      WRITE ("Floating point error\n");
+      break;
+    case EXC_IS1:
+      WRITE ("Implementation specific exception (16)\n");
+      break;
+    case EXC_IS2:
+      WRITE ("Implementation specific exception (17)\n");
+      break;
+    case EXC_C2E:
+      WRITE ("Precise Coprocessor 2 exception\n");
+      break;
+    case EXC_TLBRI:
+      WRITE ("TLB read inhibit exception\n");
+      break;
+    case EXC_TLBXI:
+      WRITE ("TLB execute inhibit exception\n");
+      break;
+    case EXC_MSAU:
+      PUTSNS ("MSA unusable @0x", ctx->epc, "\n");
+      break;
+    case EXC_MDMX:
+      PUTSNS ("MDMX exception @0x", ctx->epc, "\n");
+      break;
+    case EXC_WATCH:
+      PUTSNS ("Watchpoint @0x", ctx->epc, "\n");
+      break;
+    case EXC_MCHECK:
+      WRITE ("Machine check error\n");
+      break;
+    case EXC_THREAD:
+      WRITE ("Thread exception\n");
+      break;
+    case EXC_DSPU:
+      WRITE ("DSP unusable\n");
+      break;
+    case EXC_RES30:
+      WRITE ("Cache error\n");
+      break;
+    default:
+      PUTSNS ("Unhandled exception ", exception, "\n");
+    }
+
+  /* Dump registers */
+  PUTSNS (" 0:\t", 0, "\t");
+  PUTSNS ("at:\t", ctx->at, "\t");
+  PUTSNS ("v0:\t", ctx->v[0], "\t");
+  PUTSNS ("v1:\t", ctx->v[1], "\n");
+
+  PUTSNS ("a0:\t", ctx->a[0], "\t");
+  PUTSNS ("a1:\t", ctx->a[1], "\t");
+  PUTSNS ("a2:\t", ctx->a[2], "\t");
+  PUTSNS ("a3:\t", ctx->a[3], "\n");
+
+  PUTSNS ("t0:\t", ctx->t[0], "\t");
+  PUTSNS ("t1:\t", ctx->t[1], "\t");
+  PUTSNS ("t2:\t", ctx->t[2], "\t");
+  PUTSNS ("t3:\t", ctx->t[3], "\n");
+
+  PUTSNS ("t4:\t", ctx->t[4], "\t");
+  PUTSNS ("t5:\t", ctx->t[5], "\t");
+  PUTSNS ("t6:\t", ctx->t[6], "\t");
+  PUTSNS ("t7:\t", ctx->t[7], "\n");
+
+  PUTSNS ("s0:\t", ctx->s[0], "\t");
+  PUTSNS ("s1:\t", ctx->s[1], "\t");
+  PUTSNS ("s2:\t", ctx->s[2], "\t");
+  PUTSNS ("s3:\t", ctx->s[3], "\n");
+
+  PUTSNS ("s4:\t", ctx->s[4], "\t");
+  PUTSNS ("s5:\t", ctx->s[5], "\t");
+  PUTSNS ("s6:\t", ctx->s[6], "\t");
+  PUTSNS ("s7:\t", ctx->s[7], "\n");
+
+  PUTSNS ("t8:\t", ctx->t2[0], "\t");
+  PUTSNS ("t9:\t", ctx->t2[1], "\t");
+  PUTSNS ("k0:\t", ctx->k[0], "\t");
+  PUTSNS ("k1:\t", ctx->k[1], "\n");
+
+  PUTSNS ("gp:\t", ctx->gp, "\t");
+  PUTSNS ("sp:\t", ctx->sp, "\t");
+  PUTSNS ("fp:\t", ctx->fp, "\t");
+  PUTSNS ("ra:\t", ctx->ra, "\n");
+
+#if __mips_isa_rev < 6
+  PUTSNS ("hi:\t", ctx->hi, "\t");
+  PUTSNS ("lo:\t", ctx->lo, "\n");
+#endif
+
+  PUTSNS ("epc:     \t", ctx->epc, "\n");
+  PUTSNS ("BadVAddr:\t", ctx->badvaddr, "\n");
+
+  PUTSNDS ("Status:   \t", ctx->status, 8, "\n");
+  PUTSNDS ("Cause:    \t", ctx->cause, 8, "\n");
+  PUTSNDS ("BadInstr: \t", ctx->badinstr, 8, "\n");
+  PUTSNDS ("BadPInstr:\t", ctx->badpinstr, 8, "\n");
+
+  /* Raise UHI exception which may or may not return.  */
+  if (__uhi_exception (ctx, UHI_ABI) != 0)
+    {
+      /* The exception was acknowledged but not handled.  Abort.  */
+      ctx->epc = (sreg_t)(long)&__exit;
+      /* Exit code of 255 */
+      ctx->a[0] = 0xff;
+    }
+}
diff --git a/libgloss/mips/hal/mips_excpt_isr_fallback.S b/libgloss/mips/hal/mips_excpt_isr_fallback.S
new file mode 100644
index 000000000..54cac97fe
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_isr_fallback.S
@@ -0,0 +1,50 @@ 
+/*
+ * 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 _FUNCTION_SECTIONS_
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+.set	noat
+MIPS_NOMIPS16
+
+_TEXT_SECTION_NAMED(__isr_vec_fallback)
+
+	/* The alignment used here must match __isr_vec_space.  */
+	.balign (SZPTR * 8);
+	.globl  __isr_vec_fallback;
+	.ent    __isr_vec_fallback;
+__isr_vec_fallback:
+.weak   _mips_interrupt
+1:
+	LA      k1, _mips_interrupt
+	beqz    k1, 1b
+	jr      k1
+END(__isr_vec_fallback)
diff --git a/libgloss/mips/hal/mips_excpt_isr_fragment.S b/libgloss/mips/hal/mips_excpt_isr_fragment.S
new file mode 100644
index 000000000..e71f3561f
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_isr_fragment.S
@@ -0,0 +1,71 @@ 
+/*
+ * 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 _FUNCTION_SECTIONS_
+
+#include <mips/regdef.h>
+#include <mips/asm.h>
+#include <mips/cpu.h>
+
+.set	noat
+MIPS_NOMIPS16
+
+.extern	__isr_vec_fallback
+
+/* For the vectors shared between VINT and VEIC we rename the numeric
+ * vector indices to the named form instead.  */
+
+#define	_mips_isr_000 _mips_isr_sw0
+#define	_mips_isr_001 _mips_isr_sw1
+#define	_mips_isr_002 _mips_isr_hw0
+#define	_mips_isr_003 _mips_isr_hw1
+#define	_mips_isr_004 _mips_isr_hw2
+#define	_mips_isr_005 _mips_isr_hw3
+#define	_mips_isr_006 _mips_isr_hw4
+#define	_mips_isr_007 _mips_isr_hw5
+
+.extern	REF
+.weak	ISR
+
+#ifdef __mips_micromips
+# define NOP nop32
+#else
+# define NOP nop
+#endif
+
+_TEXT_SECTION_NAMED(DEF);
+/* The alignment used here must match __isr_vec_space.  */
+	.balign (SZPTR * 8);
+	.globl  DEF;
+	.ent    DEF;
+DEF:
+	NOP		  /* May become: mtc0 k1, C0_KSCRATCH1 */
+	LA	k1, ISR
+	beqz	k1, __isr_vec_fallback
+	jr	k1
+END(DEF)
diff --git a/libgloss/mips/hal/mips_excpt_register.S b/libgloss/mips/hal/mips_excpt_register.S
new file mode 100644
index 000000000..72eab49db
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_register.S
@@ -0,0 +1,145 @@ 
+/*
+ * 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.
+*/
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+
+MIPS_NOMIPS16
+
+/*
+ * Used to support an alternate entry point that overlays the TLB refill
+ * exception entry point.  This flag must be cleared before exceptions
+ * are ready to be handled.
+ */
+.data
+EXPORTS(__first_boot, 4)
+	.word	0x1
+
+_TEXT_SECTION
+
+/*
+ * FUNCTION:	__register_excpt_handler
+ *
+ * DESCRIPTION: Register __exception_entry at EBASE+0x180. Return the new
+ *		value for C0_SR.
+ */
+WLEAF(__register_excpt_handler)
+	.set	push
+	.set	noat
+
+	/* Fetch initial status */
+	mfc0	a1, C0_SR
+
+	/*
+	 * Get into a clean state.
+	 * Important things: base mode is kernel and ERL, ESL, IE are clear
+	 * Set BEV=1 to allow changing EBASE later.
+	 */
+	li	t0, SR_BEV
+	mtc0	t0, C0_SR
+	ehb
+
+	/*
+	 * Enable use of a boot state hook
+	 * a0 = Boot time RA
+	 * a1 = Boot time SR
+	 * a2 = Current RA. There is no stack so get the callee to pass this
+	 *      back.
+	 */
+.weak	__register_excpt_boot
+	LA	t0, __register_excpt_boot
+	beqz	t0, 1f
+	move	a2, ra
+	jalr	t0
+	move	ra, va0
+1:
+	/* Clear first boot flag */
+	LA	t0, __first_boot
+	sw	zero, 0(t0)
+
+	mfc0	t3, C0_CONFIG3
+#if defined (__mips_micromips)
+	/* Set Config3.ISAOnExc for microMIPS */
+	li	t0, CFG3_IOE
+	or	t0, t0, t3
+	mtc0	t0, C0_CONFIG3
+#endif
+
+	/* Set desired EBASE */
+	LA	t0, __excpt_ebase
+	/*
+	 * Always set the write gate as the requested EBASE may not be in kseg0.
+	 * This may or may not exist in hardware but if it doesn't then the
+	 * ebase address will simply get masked with inevitable consequences.
+	 */
+	ori	t0, t0, EBASE_WG
+	PTR_MTC0 t0, C0_EBASE
+	ehb
+
+	/* Set up new empty status value */
+	move	va0, zero
+
+	/* Set up vector spacing */
+	LA	t0, __isr_vec_space
+
+	/* Check for vectored interrupt support */
+	andi	t1, t3, CFG3_VI | CFG3_VEIC
+	/* Skip vector spacing setup if neither VINT nor VEIC is present */
+	beqz	t1, 1f
+
+	/* Set vector spacing */
+	mfc0	t1, C0_INTCTL
+	srl	t0, t0, 5
+	ins	t1, t0, INTCTL_VS_SHIFT, INTCTL_VS_BITS
+	mtc0	t1, C0_INTCTL
+	b	2f
+1:
+	/*
+	 * Check non-zero vector spacing without vectored interrupt support.
+	 * If so, do not enable interrupts.
+	 */
+	bnez	t0, 3f
+2:
+	/* Turn on use of the special exception vector and enable interrupts */
+	li	t0, CR_IV
+	mtc0	t0, C0_CAUSE
+	ehb
+
+	/* Check for VEIC and do not enable interrupts if EIC is active */
+	ext     t0, t3, CFG3_VEIC_SHIFT, 1
+	bnez	t0, 3f
+
+	/* Enable interrupts in the new status value */
+	ori	va0, va0, SR_IE
+3:
+	jr	ra
+
+	.set	pop
+WEND(__register_excpt_handler)
diff --git a/libgloss/mips/hal/mips_excpt_timer.S b/libgloss/mips/hal/mips_excpt_timer.S
new file mode 100644
index 000000000..f4420f3ab
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_timer.S
@@ -0,0 +1,101 @@ 
+/*
+ * 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.
+*/
+
+#include <mips/cpu.h>
+#include <mips/asm.h>
+
+MIPS_NOMIPS16
+
+EXPORTS(_count_wrap, 4)
+	.word	0x0
+
+#
+# FUNCTION:
+#
+# DESCRIPTION:
+#
+LEAF(mips_start_minimal_counter)
+	di	$8
+	ehb
+	ori	$8, $8, SR_HINT5
+	ori	$8, $8, SR_IE
+	LA	$9, _count_wrap
+	sw	$0, 0($9)
+	li	$9, 1
+	mtc0	$9, C0_COUNT
+	mtc0	$0, C0_COMPARE
+	mtc0	$8, C0_SR
+	ehb
+	jr	$31
+END(mips_start_minimal_counter)
+
+LEAF(_mips_isr_sw0)
+	.set push
+	.set noreorder
+	.set noat
+	LA	$k0, _count_wrap
+	lw	$k1, 0($k0)
+	addiu	$k1, $k1, 1
+	sw	$k1, 0($k0)
+	mtc0	$0, C0_COMPARE
+	eret
+	.set pop
+END(_mips_isr_sw0)
+
+LEAF(_mips_interrupt)
+	.set push
+	.set noreorder
+	.set noat
+	LA	$k0, _count_wrap
+	lw	$k1, 0($k0)
+	addiu	$k1, $k1, 1
+	sw	$k1, 0($k0)
+	mtc0	$0, C0_COMPARE
+	eret
+	.set pop
+END(_mips_interrupt)
+
+LEAF(mips_stop_minimal_counter)
+	LA	$11, _count_wrap
+	mfc0	$9, C0_COUNT
+	di	$8
+	ehb
+	lw	$11, 0($11)
+	li	$12, ~SR_HINT5
+	and	$8, $8, $12
+	mfc0	$10, C0_COUNT
+	sltu	$9, $10, $9
+	ori	$8, $8, SR_IE
+	beqz	$9, 1f
+	addiu	$11, $11, 1
+1:
+	sw	$11, 0($4)
+	sw	$10, 0($5)
+	mtc0	$8, C0_SR
+	jr	$31
+END(mips_stop_minimal_counter)
diff --git a/libgloss/mips/hal/mips_flush_cache.c b/libgloss/mips/hal/mips_flush_cache.c
new file mode 100644
index 000000000..09f2dbfbe
--- /dev/null
+++ b/libgloss/mips/hal/mips_flush_cache.c
@@ -0,0 +1,106 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+
+/* Writeback and invalidate all caches */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_flush_cache (void)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If D-cache is present */
+  if (mips_dcache_size > 0)
+    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_dcache_size,
+		   mips_dcache_linesize, Index_Writeback_Inv_D);
+
+  /* If I-cache is present */
+  if (mips_icache_size > 0)
+    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_icache_size,
+		   mips_icache_linesize, Index_Invalidate_I);
+
+  /* If L2-cache is present */
+  if (mips_scache_size > 0)
+    {
+      mips_sync ();
+      mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size,
+		     mips_scache_linesize, Index_Writeback_Inv_S);
+    }
+
+  mips_sync ();
+  return;
+}
+
+/* Writeback and invalidate D-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_flush_dcache (void)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If D-cache is present */
+  if (mips_dcache_size > 0)
+    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_dcache_size,
+		   mips_dcache_linesize, Index_Writeback_Inv_D);
+
+  /* If L2-cache is present */
+  if (mips_scache_size > 0)
+    {
+      mips_sync ();
+      mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size,
+		     mips_scache_linesize, Index_Writeback_Inv_S);
+    }
+
+  mips_sync ();
+  return;
+}
+
+/* Writeback and invalidate I-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_flush_icache (void)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If I-cache is present */
+  if (mips_icache_size > 0)
+    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_icache_size,
+		   mips_icache_linesize, Index_Invalidate_I);
+
+  /* If L2-cache is present */
+  if (mips_scache_size > 0)
+    {
+      mips_sync ();
+      mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size,
+		     mips_scache_linesize, Index_Writeback_Inv_S);
+    }
+
+  mips_sync ();
+  return;
+}
diff --git a/libgloss/mips/hal/mips_fp.S b/libgloss/mips/hal/mips_fp.S
new file mode 100644
index 000000000..6d15aa6fb
--- /dev/null
+++ b/libgloss/mips/hal/mips_fp.S
@@ -0,0 +1,182 @@ 
+/*
+ * 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.
+*/
+
+.module hardfloat
+.module doublefloat
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+
+MIPS_NOMIPS16
+
+#undef fp
+
+/*
+ * FUNCTION:	_fpctx_save
+ * DESCRIPTION:	save floating point registers to memory starting at a0
+ * RETURNS:	int
+ *		0:	No context saved
+ *		CTX_*:	Type of context stored
+ */
+LEAF(_fpctx_save)
+	move	a1, a0
+	PTR_S 	zero, LINKCTX_NEXT(a1)
+	mfc0	t0, C0_STATUS
+	li	t1, SR_CU1
+	and	t1, t0, t1
+	bnez	t1, 1f
+	/* FP not enabled, bail out */
+	move	va0, zero
+	jr	ra
+
+1:	/* Save FP32 base */
+	li	t1, SR_FR
+	and	t0, t0, t1
+	cfc1	t2, $31
+	REG_S	t2, FP32CTX_CSR(a1)
+	sdc1	$f0, FP32CTX_0(a1)
+	sdc1	$f2, FP32CTX_2(a1)
+	sdc1	$f4, FP32CTX_4(a1)
+	sdc1	$f6, FP32CTX_6(a1)
+	sdc1	$f8, FP32CTX_8(a1)
+	sdc1	$f10, FP32CTX_10(a1)
+	sdc1	$f12, FP32CTX_12(a1)
+	sdc1	$f14, FP32CTX_14(a1)
+	sdc1	$f16, FP32CTX_16(a1)
+	sdc1	$f18, FP32CTX_18(a1)
+	sdc1	$f20, FP32CTX_20(a1)
+	sdc1	$f22, FP32CTX_22(a1)
+	sdc1	$f24, FP32CTX_24(a1)
+	sdc1	$f26, FP32CTX_26(a1)
+	sdc1	$f28, FP32CTX_28(a1)
+	sdc1	$f30, FP32CTX_30(a1)
+	bnez	t0, 2f
+	li	va0, LINKCTX_TYPE_FP32
+	REG_S	va0, LINKCTX_ID(a1)
+	jr	ra
+
+2:	/* Save FP64 extra */
+.set	push
+.set	fp=64
+	sdc1	$f1, FP64CTX_1(a1)
+	sdc1	$f3, FP64CTX_3(a1)
+	sdc1	$f5, FP64CTX_5(a1)
+	sdc1	$f7, FP64CTX_7(a1)
+	sdc1	$f9, FP64CTX_9(a1)
+	sdc1	$f11, FP64CTX_11(a1)
+	sdc1	$f13, FP64CTX_13(a1)
+	sdc1	$f15, FP64CTX_15(a1)
+	sdc1	$f17, FP64CTX_17(a1)
+	sdc1	$f19, FP64CTX_19(a1)
+	sdc1	$f21, FP64CTX_21(a1)
+	sdc1	$f23, FP64CTX_23(a1)
+	sdc1	$f25, FP64CTX_25(a1)
+	sdc1	$f27, FP64CTX_27(a1)
+	sdc1	$f29, FP64CTX_29(a1)
+	sdc1	$f31, FP64CTX_31(a1)
+.set	pop
+	li	va0, LINKCTX_TYPE_FP64
+	REG_S	va0, LINKCTX_ID(a0)
+	jr	ra
+END(_fpctx_save)
+
+/*
+ * FUNCTION:	_fpctx_load
+ * DESCRIPTION:	load floating point registers from context chain starting at a0
+ * RETURNS:	int
+ *		0:	Unrecognised context
+ *		CTX_*:	Type of context restored
+ */
+LEAF(_fpctx_load)
+	move	a1, a0
+	REG_L	va0, LINKCTX_ID(a1)
+	/* Detect type */
+	li	t0, LINKCTX_TYPE_FP64
+	li	t1, LINKCTX_TYPE_FP32
+	li	t2, SR_CU1
+	beq	va0, t0, 0f
+	beq	va0, t1, 1f
+	/* Don't recognise this context, fail */
+	move	va0, zero
+	jr	ra
+
+0: 	/* FP64 context - Enable CU1 */
+	di	t3
+	ehb
+	or	t3, t3, t2
+	mtc0	t3, C0_STATUS
+	ehb
+	/* Load FP64 extra */
+.set	push
+.set	fp=64
+	ldc1	$f1, FP64CTX_1(a1)
+	ldc1	$f3, FP64CTX_3(a1)
+	ldc1	$f5, FP64CTX_5(a1)
+	ldc1	$f7, FP64CTX_7(a1)
+	ldc1	$f9, FP64CTX_9(a1)
+	ldc1	$f11, FP64CTX_11(a1)
+	ldc1	$f13, FP64CTX_13(a1)
+	ldc1	$f15, FP64CTX_15(a1)
+	ldc1	$f17, FP64CTX_17(a1)
+	ldc1	$f19, FP64CTX_19(a1)
+	ldc1	$f21, FP64CTX_21(a1)
+	ldc1	$f23, FP64CTX_23(a1)
+	ldc1	$f25, FP64CTX_25(a1)
+	ldc1	$f27, FP64CTX_27(a1)
+	ldc1	$f29, FP64CTX_29(a1)
+	ldc1	$f31, FP64CTX_31(a1)
+.set	pop
+1: 	/* FP32 context - Enable CU1 */
+	di	t3
+	ehb
+	or	t3, t3, t2
+	mtc0	t3, C0_STATUS
+	ehb
+	/* Load FP32 base */
+	REG_L	t1, FP32CTX_CSR(a1)
+	ctc1	t1, $31
+	ldc1	$f0, FP32CTX_0(a1)
+	ldc1	$f2, FP32CTX_2(a1)
+	ldc1	$f4, FP32CTX_4(a1)
+	ldc1	$f6, FP32CTX_6(a1)
+	ldc1	$f8, FP32CTX_8(a1)
+	ldc1	$f10, FP32CTX_10(a1)
+	ldc1	$f12, FP32CTX_12(a1)
+	ldc1	$f14, FP32CTX_14(a1)
+	ldc1	$f16, FP32CTX_16(a1)
+	ldc1	$f18, FP32CTX_18(a1)
+	ldc1	$f20, FP32CTX_20(a1)
+	ldc1	$f22, FP32CTX_22(a1)
+	ldc1	$f24, FP32CTX_24(a1)
+	ldc1	$f26, FP32CTX_26(a1)
+	ldc1	$f28, FP32CTX_28(a1)
+	ldc1	$f30, FP32CTX_30(a1)
+	/* Return CTX_FP32/64 */
+	jr	ra
+END(_fpctx_load)
diff --git a/libgloss/mips/hal/mips_intctrl.c b/libgloss/mips/hal/mips_intctrl.c
new file mode 100644
index 000000000..a2bd2a1bc
--- /dev/null
+++ b/libgloss/mips/hal/mips_intctrl.c
@@ -0,0 +1,148 @@ 
+/*
+ * Copyright (C) 2017-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.
+ */
+
+#include <mips/cpu.h>
+#include <mips/hal.h>
+#include <mips/intctrl.h>
+
+#define  _mips_intpatch_kscratch1 0x00
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined (__mips_micromips)
+# define  _mips_intpatch_isroff1  0x06
+# define  _mips_intpatch_isroff2  0x0a
+# define  _mips_intpatch_isroff3  0x12
+# define  _mips_intpatch_isroff4  0x1a
+#else
+# define  _mips_intpatch_isroff1  0x04
+# define  _mips_intpatch_isroff2  0x08
+# define  _mips_intpatch_isroff3  0x10
+# define  _mips_intpatch_isroff4  0x1c
+#endif
+
+extern void m32_sync_icache(unsigned kva, size_t n);
+
+void _MIPS_HAL_NOMIPS16
+_mips_intpatch (const reg_t index, uintptr_t handler, bool k1_to_kscratch1)
+{
+  extern void *__isr_vec_space;
+  uint16_t *patch;
+  uint32_t *patch32;
+  uintptr_t isrbase = (uintptr_t) (mips32_getebase() & EBASE_BASE)
+		      + 0x200 + (index * ((uintptr_t) &__isr_vec_space));
+  if (k1_to_kscratch1)
+    {
+#ifdef __mips_micromips
+      patch = (uint16_t *) (isrbase + _mips_intpatch_kscratch1);
+      *(patch++) = 0x037f;
+      *(patch) = 0x12fc;
+#else
+      patch32 = (uint32_t *) (isrbase + _mips_intpatch_kscratch1);
+      *patch32 = 0x409bf802;
+#endif
+    }
+#if SZPTR==4
+  handler += (handler & 0x8000) << 1;
+  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff1);
+  *patch = (uint16_t) (handler >> 16);		/* %hi */
+  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff2);
+  *patch = (uint16_t) (handler & 0xffff);	/* %lo */
+  m32_sync_icache (isrbase, 32);
+#elif SZPTR==8
+  handler += (handler & 0x800080008000) << 1;
+  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff1);
+  *patch = (uint16_t) (handler >> 48);			/* %highest */
+  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff2);
+  *patch = (uint16_t) ((handler >> 32) & 0xffff);	/* %higher */
+  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff3);
+  *patch = (uint16_t) ((handler >> 16) & 0xffff);	/* %hi */
+  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff4);
+  *patch = (uint16_t) (handler & 0xffff);		/* %lo */
+  m32_sync_icache (isrbase, 64);
+#else
+# error "Unknown pointer size"
+#endif
+}
+
+/*
+ * Interrupt masking and acknowledging functions - these are weak so they can
+ * be replaced with versions that understand more complex interrupt models.
+ */
+
+reg_t __attribute__ ((weak)) _MIPS_HAL_NOMIPS16
+_mips_intmask (const reg_t index, const reg_t enable)
+{
+  register reg_t enbefore, valbefore = 0, indexedbit;
+
+  /*
+   * Calculate which bit upfront to minimise critical section.
+   * Note that this function supports the MCU ASE, unlike the .h files.
+   */
+  if ((index >= 0) && (index <= 8))
+    /* Traditional/1st MCU ASE interrupt.  */
+    indexedbit = SR_IM0 << index;
+  else if (index == 9)
+    /* 2nd MCU ASE interrupt.  */
+    indexedbit = SR_IM7 << 2;
+
+  /* Make sure we can safely adjust the mask.  */
+  enbefore = _mips_intdisable ();
+
+  /* Make the change.  */
+  valbefore = mips32_bcssr (indexedbit, enable ? indexedbit : 0);
+
+  /* Go live again.  */
+  _mips_intrestore (enbefore);
+
+  /* Return true if it was enabled, again outside critical section.  */
+  return (valbefore & indexedbit) != 0;
+}
+
+reg_t __attribute__ ((weak)) _MIPS_HAL_NOMIPS16
+_mips_intack (const reg_t index)
+{
+  reg_t enbefore, indexedbit;
+  reg_t valbefore = 0;
+
+  /* We only handle software interrupts - bail out otherwise.  */
+  if ((index < 0) && (index > 1))
+    return 0;
+
+  /* Calculate which bit upfront to minimise critical section.  */
+  indexedbit = CR_IP0 << index;
+
+  /* Make sure we can safely adjust the state.  */
+  enbefore = _mips_intdisable ();
+
+  /* Make the change. */
+  valbefore = mips32_bicsr (indexedbit);
+
+  /* Go live again.  */
+  _mips_intrestore (enbefore);
+
+  /* Return true if it was enabled, again outside critical section.  */
+  return (valbefore & indexedbit) != 0;
+}
diff --git a/libgloss/mips/hal/mips_l2size.c b/libgloss/mips/hal/mips_l2size.c
new file mode 100644
index 000000000..b97edd400
--- /dev/null
+++ b/libgloss/mips/hal/mips_l2size.c
@@ -0,0 +1,94 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+#include <mips/uhi_syscalls.h>
+
+static void __attribute__ ((noreturn)) _MIPS_HAL_NOMIPS16
+__boot_fail (void)
+{
+  register long arg1 asm ("$4") = __MIPS_UHI_BF_CACHE;	/* L2 cache configuration error */
+  register long op asm ("$25") = __MIPS_UHI_BOOTFAIL;
+  register long ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+
+  __asm__ volatile (" # %0 = bootfail(%0, %1) op=%2\n"
+		    SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+		    : "+r" (ret)
+		    : "r" (arg1), "r" (op));
+
+  __boot_fail ();
+}
+
+/*
+ * Internal routine to determine cache sizes by looking at config
+ * registers.  Sizing information is stored directly to memory.
+*/
+void _MIPS_HAL_NOMIPS16
+__def_cache_size_hook (void)
+{
+  /* 
+   * Fall back to Config2 based L2 if Config3[M] or Config4[M]
+   * or Config5[L2C] is not present.
+  */
+  if ((mips32_getconfig3 () & CFG3_M) == 0
+      || (mips32_getconfig4 () & CFG4_M) == 0
+      || (mips32_getconfig5 () & CFG5_L2C) == 0)
+    {
+      unsigned int cfg, tmp1, tmp2;
+
+      cfg = mips32_getconfig2 ();
+
+      /* Get S-cache line size (log2) */
+      tmp1 = (cfg & CFG2_SL_MASK) >> CFG2_SL_SHIFT;
+      if (tmp1 == 0)
+	return;	/* No S-cache */
+
+      tmp1++;
+
+      /* Get number of S-cache ways */
+      mips_scache_ways = ((cfg & CFG2_SA_MASK) >> CFG2_SA_SHIFT) + 1;
+
+      /* Total scache size = lines/way * linesize * ways */
+      mips_scache_linesize = 1 << tmp1;
+      tmp2 = mips_scache_ways << tmp1;
+
+      /* Get scache lines per way */
+      tmp1 = ((cfg & CFG2_SS_MASK) >> CFG2_SS_SHIFT) + 6;
+      mips_scache_size = tmp2 << tmp1;
+
+      return;
+    }
+
+  /*
+   * No CM3 code supplied but we have a memory mapped L2 config.
+   * Report a boot failure through UHI.
+  */
+  __boot_fail ();
+}
+
+void __cache_size_hook (void) __attribute__ ((weak, alias ("__def_cache_size_hook")));
diff --git a/libgloss/mips/hal/mips_lock_cache.c b/libgloss/mips/hal/mips_lock_cache.c
new file mode 100644
index 000000000..35011abfb
--- /dev/null
+++ b/libgloss/mips/hal/mips_lock_cache.c
@@ -0,0 +1,81 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+
+/*  
+ * The MIPS32 cache architecture does support per-line cache locking.
+ * If you lock any cache lines, then don't call the mips_flush_cache
+ * routine, because these will flush the locked data out of the cache
+ * too; use only mips_clean_xcache routines.
+*/
+
+/* Load and lock a block of data into the D-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_lock_dcache (vaddr_t data, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If D-cache is present */
+  if (mips_dcache_linesize > 0)
+    mips_cache_op (data, n, mips_dcache_linesize, Fetch_Lock_D);
+  
+  mips_sync ();
+  return;
+}
+
+/* Load and lock a block of instructions into the I-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_lock_icache (vaddr_t code, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If I-cache is present */
+  if (mips_icache_linesize > 0)
+    mips_cache_op (code, n, mips_icache_linesize, Fetch_Lock_I);
+  
+  mips_sync ();
+  return;
+}
+
+/* Load and lock a block of data into the L2-cache */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_lock_scache (vaddr_t data, size_t n)
+{
+  /* Calculate cache sizes */
+  mips_size_cache ();
+
+  /* If L2-cache is present */
+  if (mips_scache_linesize > 0)
+    mips_cache_op (data, n, mips_scache_linesize, Fetch_Lock_S);
+  
+  mips_sync ();
+  return;
+}
diff --git a/libgloss/mips/hal/mips_msa.S b/libgloss/mips/hal/mips_msa.S
new file mode 100644
index 000000000..1e0350322
--- /dev/null
+++ b/libgloss/mips/hal/mips_msa.S
@@ -0,0 +1,181 @@ 
+/*
+ * 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.
+*/
+
+#if __mips_isa_rev < 6 || !defined(__mips_micromips)
+.module hardfloat
+.module doublefloat
+#undef fp
+.module fp=64
+.module msa
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+
+MIPS_NOMIPS16
+
+/*
+ * FUNCTION:	_msactx_save
+ * DESCRIPTION:	save MSA registers to memory starting at a0
+ * RETURNS:	int
+ *		0:	No context saved
+ *		CTX_*:	Type of context stored
+ */
+LEAF(_msactx_save)
+	move	a1, a0
+	PTR_S	zero, LINKCTX_NEXT(a1)
+	mfc0	t0, C0_CONFIG5
+	ext	t0, t0, CFG5_MSAEN_SHIFT, 1
+	bnez	t0, 1f
+	/* MSA not enabled, bail out */
+	move	va0, zero
+	jr	ra
+
+	/* Save FCSR if necessary */
+1:	mfc0	t0, C0_STATUS
+	ext	t1, t0, SR_CU1_SHIFT, 1
+	lui	va0, %hi(LINKCTX_TYPE_MSA)
+	beqz	t1, 2f
+	lui	va0, %hi(LINKCTX_TYPE_FMSA)
+	cfc1	t2, $31
+	REG_S	t2, MSACTX_FCSR(a1)
+	/* Save MSA */
+2:	ori	va0, va0, %lo(LINKCTX_TYPE_MSA)
+	cfcmsa	t0, $1
+	REG_S	t0, MSACTX_MSACSR(a1)
+	st.d	 $w0, MSACTX_0(a1)
+	st.d	 $w1, MSACTX_1(a1)
+	st.d	 $w2, MSACTX_2(a1)
+	st.d	 $w3, MSACTX_3(a1)
+	st.d	 $w4, MSACTX_4(a1)
+	st.d	 $w5, MSACTX_5(a1)
+	st.d	 $w6, MSACTX_6(a1)
+	st.d	 $w7, MSACTX_7(a1)
+	st.d	 $w8, MSACTX_8(a1)
+	st.d	 $w9, MSACTX_9(a1)
+	st.d	$w10, MSACTX_10(a1)
+	st.d	$w11, MSACTX_11(a1)
+	st.d	$w12, MSACTX_12(a1)
+	st.d	$w13, MSACTX_13(a1)
+	st.d	$w14, MSACTX_14(a1)
+	st.d	$w15, MSACTX_15(a1)
+	st.d	$w16, MSACTX_16(a1)
+	st.d	$w17, MSACTX_17(a1)
+	st.d	$w18, MSACTX_18(a1)
+	st.d	$w19, MSACTX_19(a1)
+	st.d	$w20, MSACTX_20(a1)
+	st.d	$w21, MSACTX_21(a1)
+	st.d	$w22, MSACTX_22(a1)
+	st.d	$w23, MSACTX_23(a1)
+	st.d	$w24, MSACTX_24(a1)
+	st.d	$w25, MSACTX_25(a1)
+	st.d	$w26, MSACTX_26(a1)
+	st.d	$w27, MSACTX_27(a1)
+	st.d	$w28, MSACTX_28(a1)
+	st.d	$w29, MSACTX_29(a1)
+	st.d	$w30, MSACTX_30(a1)
+	st.d	$w31, MSACTX_31(a1)
+	REG_S	va0, LINKCTX_ID(a1)
+	jr	ra
+END(_msactx_save)
+
+/*
+ * FUNCTION:	_msactx_load
+ * DESCRIPTION:	load MSA/floating point registers from memory starting at a0
+ * RETURNS:	int
+ *		0:	Unrecognised context
+ *		CTX_*:	Type of context restored
+ */
+LEAF(_msactx_load)
+	move	a1, a0
+	REG_L	va0, LINKCTX_ID(a1)
+	/* Detect type */
+	li	t0, LINKCTX_TYPE_FMSA
+	li	t1, LINKCTX_TYPE_MSA
+	li	t2, SR_CU1
+	beq	va0, t0, 0f
+	beq	va0, t1, 1f
+	/* Don't recognise this context, fail */
+	move	va0, zero
+	jr	ra
+
+0:	/* FPU+MSA context - Enable CU1 */
+	di	t3
+	ehb
+	or	t3, t3, t2
+	mtc0	t3, C0_STATUS
+	ehb
+	REG_L	t1, MSACTX_FCSR(a1)
+	ctc1	t1, $31
+1:	/* MSA context - Enable MSA */
+	li	t3, CFG5_MSAEN
+	mfc0	t2, C0_CONFIG5
+	or	t2, t3, t2
+	mtc0	t2, C0_CONFIG5
+	ehb
+	/* Load MSA */
+	lw	t3, MSACTX_MSACSR(a1)
+	ctcmsa	$1, t3
+	ld.d	 $w0, MSACTX_0(a1)
+	ld.d	 $w1, MSACTX_1(a1)
+	ld.d	 $w2, MSACTX_2(a1)
+	ld.d	 $w3, MSACTX_3(a1)
+	ld.d	 $w4, MSACTX_4(a1)
+	ld.d	 $w5, MSACTX_5(a1)
+	ld.d	 $w6, MSACTX_6(a1)
+	ld.d	 $w7, MSACTX_7(a1)
+	ld.d	 $w8, MSACTX_8(a1)
+	ld.d	 $w9, MSACTX_9(a1)
+	ld.d	$w10, MSACTX_10(a1)
+	ld.d	$w11, MSACTX_11(a1)
+	ld.d	$w12, MSACTX_12(a1)
+	ld.d	$w13, MSACTX_13(a1)
+	ld.d	$w14, MSACTX_14(a1)
+	ld.d	$w15, MSACTX_15(a1)
+	ld.d	$w16, MSACTX_16(a1)
+	ld.d	$w17, MSACTX_17(a1)
+	ld.d	$w18, MSACTX_18(a1)
+	ld.d	$w19, MSACTX_19(a1)
+	ld.d	$w20, MSACTX_20(a1)
+	ld.d	$w21, MSACTX_21(a1)
+	ld.d	$w22, MSACTX_22(a1)
+	ld.d	$w23, MSACTX_23(a1)
+	ld.d	$w24, MSACTX_24(a1)
+	ld.d	$w25, MSACTX_25(a1)
+	ld.d	$w26, MSACTX_26(a1)
+	ld.d	$w27, MSACTX_27(a1)
+	ld.d	$w28, MSACTX_28(a1)
+	ld.d	$w29, MSACTX_29(a1)
+	ld.d	$w30, MSACTX_30(a1)
+	ld.w	$w31, MSACTX_31(a1)
+	/* Return CTX_(F)MSA */
+	jr	ra
+END(_msactx_load)
+
+#endif // __mips_isa_rev < 6 || !defined(__micromips__)
diff --git a/libgloss/mips/hal/mips_size_cache.c b/libgloss/mips/hal/mips_size_cache.c
new file mode 100644
index 000000000..75f88973b
--- /dev/null
+++ b/libgloss/mips/hal/mips_size_cache.c
@@ -0,0 +1,106 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+
+int mips_icache_size = -1;
+int mips_icache_linesize = -1;
+int mips_icache_ways = 1;
+
+int mips_dcache_size = -1;
+int mips_dcache_linesize = -1;
+int mips_dcache_ways = 1;
+
+int mips_scache_size = -1;
+int mips_scache_linesize = -1;
+int mips_scache_ways = 1;
+
+int mips_tcache_size = -1;
+int mips_tcache_linesize = -1;
+int mips_tcache_ways = 1;
+
+extern void __cache_size_hook (void);
+
+/*
+ * Size caches without reinitialising and losing dirty cache lines.
+ * Update mips_icache_* and mips_dcache_* global variables.
+*/
+void _MIPS_HAL_NOMIPS16
+mips_size_cache (void)
+{
+  int lsize, ways;
+  unsigned int cfg;
+
+  /* Return if sizes are already known */
+  if (mips_icache_size > 0)
+    return;
+
+  /* Check presence of Config1 */
+  cfg = mips32_getconfig0 ();
+  if ((cfg & CFG0_M))
+    {
+      /* Check if I-cache is present */
+      cfg = mips32_getconfig1 ();
+      lsize = (cfg & CFG1_IL_MASK) >> CFG1_IL_SHIFT;
+      if (lsize)
+	{
+	  lsize++;
+
+	  /* Get number of I-cache ways */
+	  ways = ((cfg & CFG1_IA_MASK) >> CFG1_IA_SHIFT) + 1;
+	  mips_icache_ways = ways;
+	  mips_icache_linesize = 1 << lsize;
+	  ways = ways << lsize;
+
+	  /* Get I-cache lines per way */
+	  lsize = ((((cfg & CFG1_IS_MASK) >> CFG1_IS_SHIFT) + 1) & 7) + 5;
+	  mips_icache_size = ways << lsize;
+	}
+
+      /* Check if D-cache is present */
+      lsize = (cfg & CFG1_DL_MASK) >> CFG1_DL_SHIFT;
+      if (lsize)
+	{
+	  lsize++;
+
+	  /* Get number of D-cache ways */
+	  ways = ((cfg & CFG1_DA_MASK) >> CFG1_DA_SHIFT) + 1;
+	  mips_dcache_ways = ways;
+	  mips_dcache_linesize = 1 << lsize;
+	  ways = ways << lsize;
+
+	  /* Get D-cache lines per way */
+	  lsize = ((((cfg & CFG1_DS_MASK) >> CFG1_DS_SHIFT) + 1) & 7) + 5;
+	  mips_dcache_size = ways << lsize;
+	}
+    }
+
+  __cache_size_hook ();
+
+  return;
+}
diff --git a/libgloss/mips/hal/mips_sync_cache.c b/libgloss/mips/hal/mips_sync_cache.c
new file mode 100644
index 000000000..98fd2a00a
--- /dev/null
+++ b/libgloss/mips/hal/mips_sync_cache.c
@@ -0,0 +1,62 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+
+/* Synchronise I-cache for virtual address range */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_sync_icache (vaddr_t kva, size_t n)
+{
+  int step;
+  vaddr_t addr, maxaddr, mask;
+
+  /* Check for bad size */
+  if (n <= 0)
+    return;
+
+  /* Get synci step and skip if not required */
+  step = mips_synci_step ();
+  if (step == 0)
+    return;
+
+  mips_sync ();
+
+  mask = ~ (step - 1);
+  addr = (kva & mask) - step;
+  maxaddr = ((kva + n) - 1) & mask;
+
+  do
+    {
+      addr = addr + step;
+      mips_synci (addr);
+    }
+  while (addr != maxaddr);
+  
+  mips_sync ();
+  return;
+}
diff --git a/libgloss/mips/hal/mips_tlb.c b/libgloss/mips/hal/mips_tlb.c
new file mode 100644
index 000000000..0b1217998
--- /dev/null
+++ b/libgloss/mips/hal/mips_tlb.c
@@ -0,0 +1,477 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+#include "cache.h"
+#include <mips/hal.h>
+#include <mips/m32tlb.h>
+
+/* Writes hi, lo0, lo1 and mask into the TLB entry specified by index */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_tlbwi2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask,
+		  int index)
+{
+  mips32_setentryhi (hi);
+  mips32_setentrylo0 (lo0);
+  mips32_setentrylo1 (lo1);
+  mips32_setpagemask (mask);
+  mips32_setindex (index);
+  mips_ehb ();
+  mips_tlbwi ();
+  return;
+}
+
+/* 
+ * Writes hi, lo0, lo1 and mask into the TLB entry specified by the
+ * random register.
+*/
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_tlbwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask)
+{
+  mips32_setentryhi (hi);
+  mips32_setentrylo0 (lo0);
+  mips32_setentrylo1 (lo1);
+  mips32_setpagemask (mask);
+  mips_ehb ();
+  mips_tlbwr ();
+  return;
+}
+
+/* 
+ * Probes the TLB for an entry matching hi and if present rewrites that entry,
+ * otherwise updates a random entry.  A safe way to update the TLB.
+*/
+int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_tlbrwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask)
+{
+  int index;
+  tlbhi_t prev_hi;
+
+  prev_hi = mips32_getentryhi ();
+  mips32_setentryhi (hi);
+
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbp ();
+  mips_ehb ();	/* tlbp hazard on mfc0 */
+
+  index = mips32_getindex ();
+  mips32_setentrylo0 (lo0);
+  mips32_setentrylo1 (lo1);
+  mips32_setpagemask (mask);
+  mips_ehb ();	/* mtc0 hazard on tlbwi/tlbwr */
+
+  /* Check if entry matches */
+  if (index >= 0)
+    mips_tlbwi ();
+  else
+    mips_tlbwr ();
+
+  mips32_setentryhi (prev_hi);
+
+  return index;
+}
+
+/* 
+ * Reads the TLB entry specified by index, and returns the EntryHi,
+ * EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmask
+ * respectively.
+*/
+void _MIPS_HAL_NOMIPS16
+mips_tlbri2 (tlbhi_t *phi, tlblo_t *plo0, tlblo_t *plo1,
+	     unsigned int *pmask, int index)
+{
+  mips32_setindex (index);
+  mips_ehb ();	/* mtc0 hazard on tlbr */
+  mips_tlbr ();
+  mips_ehb ();	/* tlbr hazard on mfc0 */
+  *phi = mips32_getentryhi ();
+  *plo0 = mips32_getentrylo0 ();
+  *plo1 = mips32_getentrylo1 ();
+  *pmask = mips32_getpagemask ();
+  return;
+}
+
+/* 
+ * Probes the TLB for an entry matching hi and return its index, or -1 if
+ * not found. If found, the EntryLo0, EntryLo1 and PageMask parts of the
+ * entry are also returned in *plo0, *plo1 and *pmask respectively.
+*/
+int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_tlbprobe2 (tlbhi_t hi, tlblo_t *plo0, tlblo_t *plo1,
+		unsigned int *pmask)
+{
+  int index;
+  tlbhi_t prev_hi;
+
+  prev_hi = mips32_getentryhi ();
+  mips32_setentryhi (hi);
+
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbp ();
+  mips_ehb ();	/* tlbp hazard on mfc0 */
+
+  index = mips32_getindex ();
+
+  if (index >= 0)
+    {
+      mips_tlbr ();
+      mips_ehb ();	/* tlbr hazard on mfc0 */
+      *plo0 = mips32_getentrylo0 ();
+      *plo1 = mips32_getentrylo1 ();
+      *pmask = mips32_getpagemask ();
+    }
+  else
+     index = -1;
+
+  mips32_setentryhi (prev_hi); /* restore EntryHi */
+
+  return index;
+}
+
+/* Probes the TLB for an entry matching hi, and if present invalidates it */
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_tlbinval (tlbhi_t hi)
+{
+  int index, tmp_idx;
+  tlbhi_t prev_hi, tmp_hi = 0;
+  register const int zero = 0;
+  unsigned int cfg;
+
+  prev_hi = mips32_getentryhi ();
+  mips32_setentryhi (hi);
+
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbp ();
+  mips_ehb ();	/* tlbp hazard on mfc0 */
+
+  index = mips32_getindex ();
+
+  if (index < 0)
+    goto restore;
+
+  mips32_setentrylo0 (zero);
+  mips32_setentrylo1 (zero);
+
+  /* Check if Config4 is implemented */
+  cfg = mips32_getconfig3 ();
+  if ((cfg & CFG3_M) != 0)
+    {
+      cfg = mips32_getconfig4 ();
+      if ((cfg & CFG4_IE_MASK) != 0)
+	{
+	  tmp_hi = C0_ENTRYHI_EHINV_MASK;
+	  goto do_tlbwi;
+	}
+    }
+
+  tmp_hi = (tlbhi_t) ((unsigned long) KSEG0_BASE - 0x4000);
+
+  do
+    {
+      tmp_hi = tmp_hi + 0x4000;
+      mips32_setentryhi (tmp_hi);
+      mips_ehb ();		/* mtc0 hazard on tlbp */
+      mips_tlbp ();
+      mips_ehb ();		/* tlbp hazard on mfc0 */
+      tmp_idx = mips32_getindex ();
+    }
+  while (tmp_idx >= 0);
+
+  mips32_setindex (index);	/* restore Index */
+
+do_tlbwi:
+  mips32_setentryhi (tmp_hi);
+  mips_ehb ();	/* mtc0 hazard on tlbp */
+  mips_tlbwi ();
+  mips_ehb ();	/* tlbwi hazard on mfc0 */
+
+restore:
+  mips32_setentryhi (prev_hi); /* restore EntryHi */
+
+  return;
+}
+
+/* 
+ * Return number of entries and sets in TLB.
+ * Return number of entries in *pentries and 
+ * sets in *psets
+*/
+static void _MIPS_HAL_NOMIPS16
+mips_tlb_entries_sets (int *pentries, int *psets)
+{
+  int entries = 0, sets = 0, ways = 0;
+  unsigned int cfg, cfg1, tcfg, tmp;
+
+  cfg = mips32_getconfig ();
+  cfg = (cfg & CFG0_MT_MASK) >> CFG0_MT_SHIFT;
+  if ((cfg == 0) /* No MMU */
+      || (cfg == (CFG0_MT_FIXED >> CFG0_MT_SHIFT)) /* fixed address translation */
+      || (cfg == (CFG0_MT_BAT >> CFG0_MT_SHIFT)) /* block address translator */
+      || ((cfg & ((CFG0_MT_TLB | CFG0_MT_DUAL) >> CFG0_MT_SHIFT)) == 0)) /* presence of TLB */
+    {
+      *pentries = 0;
+      *psets = 0;
+      return;
+    }
+
+  cfg1 = mips32_getconfig1 ();
+
+  /* 
+   * As per PRA, field holds number of entries - 1
+   * Standard TLBs and dual TLBs have extension fields.
+  */
+  entries = ((cfg1 & CFG1_MMUS_MASK) >> CFG1_MMUSSHIFT) + 1;
+  
+  tcfg = mips32_getconfig3 ();
+  if ((tcfg & CFG3_M) == 0)
+    goto doReturn;
+
+  tcfg = mips32_getconfig4 ();
+
+#if (__mips_isa_rev < 6)
+  tmp = (tcfg & CFG4_MMUED) >> CFG4_MMUED_SHIFT;
+
+  /* MMU Extension Definition */
+  if (tmp == (CFG4_MMUED_FTLBVEXT >> CFG4_MMUED_SHIFT))
+    goto doFTLBVTLB;
+
+  /* MMUSizeExt */
+  if (tmp == (CFG4_MMUED_SIZEEXT >> CFG4_MMUED_SHIFT))
+    goto doSizeExt;
+
+  if (tmp == 0)
+    goto doReturn;
+
+  goto doFTLBSize;
+
+doSizeExt:
+  entries += ((tcfg & CFG4_MMUSE_MASK) >> CFG4_MMUSE_SHIFT)
+	      << CFG1_MMUS_BITS;
+  goto doReturn;
+#endif
+
+doFTLBVTLB:
+  entries += ((tcfg & CFG4_VTLBSEXT_MASK) >> CFG4_VTLBSEXT_SHIFT)
+	      << CFG1_MMUS_BITS;
+
+doFTLBSize:
+  /* Skip FTLB size calculations if Config:MT != 4 */
+  if (cfg != (CFG0_MT_DUAL >> CFG0_MT_SHIFT))
+    goto doReturn;
+
+  /* Ways */
+  ways = 2 + ((tcfg & CFG4_FTLBW_MASK) >> CFG4_FTLBW_SHIFT);
+
+  /* Sets per way */
+  tmp = ((tcfg & CFG4_FTLBS_MASK) >> CFG4_FTLBS_SHIFT);
+  sets = 1 << tmp;
+
+  /* Total sets */
+  entries += ways << tmp;
+
+doReturn:
+  *pentries = entries;
+  *psets = sets;
+
+  return;
+}
+
+/* 
+ * Return number of entries in TLB
+ * This function is used for both mips64 and mips32 
+*/
+int _MIPS_HAL_NOMIPS16
+mips_tlb_size (void)
+{
+  int entries = 0, sets = 0;
+  mips_tlb_entries_sets (&entries, &sets);
+  (void) sets;
+  return entries;
+}
+
+/* 
+ * Invalidate the whole TLB.
+ * This function is used for both mips64 and mips32 
+*/
+void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
+mips_tlbinvalall (void)
+{
+  unsigned int cfg0, cfg;
+  unsigned long tmp_hi, tmp_hi2;
+  int entries = 0, sets = 0, tlb_stride = 0;
+  int end_ptr = 0, index = 0;
+  register const unsigned long zero = 0;
+  extern void *__tlb_stride_length;
+
+  cfg0 = mips32_getconfig ();
+  cfg0 = (cfg0 & CFG0_MT_MASK) >> CFG0_MT_SHIFT;
+  if ((cfg0 == 0) /* No MMU */
+      || (cfg0 == (CFG0_MT_FIXED >> CFG0_MT_SHIFT)) /* fixed address translation */
+      || (cfg0 == (CFG0_MT_BAT >> CFG0_MT_SHIFT))) /* block address translator */
+    goto doReturn;
+
+  mips_setentrylo0 (zero);
+  mips_setentrylo1 (zero);
+  mips_setpagemask (zero);
+
+  /* Fetch size & number of sets */
+  mips_tlb_entries_sets (&entries, &sets);
+
+  cfg = mips32_getconfig3 ();
+  if ((cfg & CFG3_M) == 0)
+    goto doBasicInval;
+
+  cfg = mips32_getconfig4 ();
+  cfg = (cfg & CFG4_IE_MASK) >> CFG4_IE_SHIFT;
+
+  /* If Config4[IE] = 0, use old method for invalidation */
+  if (cfg == 0)
+    goto doBasicInval;
+
+  /* If Config4[IE] = 1, EHINV loop */
+  if (cfg == (CFG4_IE_EHINV >> CFG4_IE_SHIFT))
+    goto doEHINV;
+
+  /* If Config[MT] = 1, one instruction required */
+  if (cfg0 == (CFG0_MT_TLB >> CFG0_MT_SHIFT)
+      || cfg == (CFG4_IE_INVALL >> CFG4_IE_SHIFT))
+    {
+      /* TLB walk done by hardware, Config4[IE] = 3 or Config[MT] = 1 */
+      mips32_setindex (zero);
+      mips_ehb ();
+      mips_eva_tlbinvf ();
+      goto doReturn;
+    }
+
+  /* 
+   * 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 set.
+   *
+   * We'll clean out the TLB by computing the Size of the VTLB
+   * but not add the 1. This will give us a finger that points
+   * at the last VTLB entry.
+  */
+
+  /* Clear VTLB */
+  mips32_setindex (zero);
+  mips_ehb ();
+  mips_eva_tlbinvf ();
+
+  tlb_stride = (int) ((unsigned long) &__tlb_stride_length);
+  sets = sets * tlb_stride;
+  end_ptr = entries - sets;
+
+  do
+    {
+      entries = entries - tlb_stride;
+      mips32_setindex (entries);
+      mips_ehb ();
+      mips_eva_tlbinvf ();
+    }
+  while (entries != end_ptr);
+
+  goto doReturn;
+
+doEHINV:
+  /*
+   * Config4[IE] = 1. EHINV supported, but not tlbinvf.
+   *
+   * Invalidate the TLB for R3 onwards by loading EHINV and writing to all
+   * TLB entries.
+  */
+  index = 0;
+  tmp_hi = C0_ENTRYHI_EHINV_MASK;
+  mips_setentryhi (tmp_hi);
+  do
+    {
+      mips32_setindex (index);
+      mips_ehb ();		/* mtc0 hazard on tlbwi */
+      mips_tlbwi ();
+      index++;
+    }
+  while (entries != index);
+
+  goto doReturn;
+
+doBasicInval:
+  /* 
+   * Perform a basic invalidation of 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.
+  */
+  tmp_hi = 0;
+  cfg = mips32_getconfig3 ();
+
+  /* If XPA is present */
+  if ((cfg & CFG3_LPA) != 0)
+    {
+      cfg = mips32_getpagegrain ();
+      if ((cfg & PAGEGRAIN_ELPA) == 0)
+	tmp_hi = 0xFFFFFFFF;
+    }
+
+  tmp_hi2 = (unsigned long) KSEG0_BASE - 0x4000;
+  index = 0;
+
+  do
+    {
+      tmp_hi2 += 0x4000;
+      mips_setentryhi (tmp_hi2);
+      if (tmp_hi != 0)
+	mips32_sethientryhi (tmp_hi);
+      mips_ehb ();		/* mtc0 hazard on tlbp */
+      mips_tlbp ();
+      mips_ehb ();		/* tlbp hazard on mfc0 */
+      if (mips32_getindex () == 0)
+	continue;
+      mips32_setindex (index);
+      mips_ehb ();		/* mtc0 hazard on tlbwi */
+      mips_tlbwi ();
+      index++;
+    }
+  while (entries != index);
+
+doReturn:
+  /* 
+   * Clear EntryHI. The upper half is cleared 
+   * autmatically as mtc0 writes zeroes.
+  */
+  mips_setentryhi (zero);
+
+  return;
+}
+
+_MIPS_HAL_NOMIPS16
+int m64_tlb_size (void) __attribute__ ((alias ("mips_tlb_size")));
+_MIPS_HAL_NOMIPS16
+void m64_tlbinvalall (void) __attribute__ ((alias ("mips_tlbinvalall")));
diff --git a/libgloss/mips/hal/mips_xpa.S b/libgloss/mips/hal/mips_xpa.S
new file mode 100644
index 000000000..a2bf981c7
--- /dev/null
+++ b/libgloss/mips/hal/mips_xpa.S
@@ -0,0 +1,75 @@ 
+/*
+ * 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.
+*/
+
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/asm.h>
+#include <mips/hal.h>
+
+MIPS_NOMIPS16
+
+/*
+ * FUNCTION:	_xpa_save
+ * DESCRIPTION:	save the XPA version of badvaddr.
+ * RETURNS:	int
+ *		0:	No context saved
+ *		CTX_*:	Type of conext stored
+ */
+LEAF(_xpa_save)
+	move	a1, a0
+	PTR_S	zero, LINKCTX_NEXT(a1)
+	/* Test for LPA support */
+	mfc0	t0, C0_CONFIG3
+	ext	t0, t0, CFG3_LPA_SHIFT, 1
+	beqz	t0, 1f
+	/* Test for LPA enabled */
+	mfc0	t0, C0_PAGEGRAIN
+	ext	t0, t0, PAGEGRAIN_ELPA_SHIFT, PAGEGRAIN_ELPA_BITS
+	bnez	t0, 2f
+
+	/* LPA either unavailable or not enabled - return 0 */
+1:	move	va0, zero
+	jr	ra
+
+2:	lui	va0, %hi(LINKCTX_TYPE_XPA)
+	addiu	va0, va0, %lo(LINKCTX_TYPE_XPA)
+	mfc0	t0, C0_BADVADDR
+	.set push
+	.set xpa
+	mfhc0	t1, C0_BADVADDR
+	.set pop
+#if BYTE_ORDER == BIG_ENDIAN
+	sw	t0, XPACTX_BADVADDR(a1)
+	sw	t1, (XPACTX_BADVADDR+4)(a1)
+#else /* BYTE ORDER == LITTLE_ENDIAN */
+	sw	t1, XPACTX_BADVADDR(a1)
+	sw	t0, (XPACTX_BADVADDR+4)(a1)
+#endif
+	REG_S	va0, LINKCTX_ID(a1)
+	jr ra
+END(_xpa_save)
diff --git a/libgloss/mips/hal/syscalls.c b/libgloss/mips/hal/syscalls.c
new file mode 100644
index 000000000..d296f538f
--- /dev/null
+++ b/libgloss/mips/hal/syscalls.c
@@ -0,0 +1,51 @@ 
+#include <_ansi.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <mips/hal.h>
+
+extern char _end[];
+
+/* FIXME: This is not ideal, since we do a get_ram_range() call for
+   every sbrk() call. */
+char *
+sbrk (int nbytes)
+{
+  static char *heap_ptr = NULL;
+  static char *heap_start = NULL;
+  static unsigned long heap_size = 0;
+  char        *base;
+  unsigned int avail = 0;
+  void *ram_base;
+  void *ram_extent;
+
+  if (heap_start == NULL)
+    {
+      _get_ram_range (&ram_base, &ram_extent);
+
+      /* If the _end symbol is within the RAM then use _end.  */
+      if ((void*)_end > ram_base && (void*)_end < ram_extent)
+	{
+	  heap_start = _end;
+	  heap_ptr = _end;
+	  heap_size = ram_extent - (void*)_end;
+	}
+      else
+	{
+	  heap_start = ram_base;
+	  heap_ptr = ram_base;
+	  heap_size = ram_extent - ram_base;
+	}
+    }
+
+  if ((heap_ptr >= heap_start) && (heap_ptr < (heap_start + heap_size))) {
+    avail = (heap_start + heap_size) - heap_ptr;
+    base = heap_ptr;
+  } /* else will fail since "nbytes" will be greater than zeroed "avail" value */
+
+  if ((nbytes > avail) || (heap_ptr + nbytes < heap_start))
+   base = (char *)-1;
+  else
+   heap_ptr += nbytes;
+
+  return base;
+}
diff --git a/libgloss/mips/idtmon.S b/libgloss/mips/idtmon.S
index 304aaa412..d09b2e0b2 100644
--- a/libgloss/mips/idtmon.S
+++ b/libgloss/mips/idtmon.S
@@ -28,7 +28,8 @@ 
 #define INDIRECT(name,index)			\
 	.globl	name;				\
 	.ent	name;				\
-name:	la	$2,+(0xbfc00000+((index)*8));	\
+name:	lui	$2,%hi(0xbfc00000+((index)*8));	\
+	addiu	$2,$2,%lo(0xbfc00000+((index)*8));	\
 	j	$2;				\
 	.end name
 
diff --git a/libgloss/mips/include/mips/asm.h b/libgloss/mips/include/mips/asm.h
new file mode 100644
index 000000000..209d151c5
--- /dev/null
+++ b/libgloss/mips/include/mips/asm.h
@@ -0,0 +1,354 @@ 
+/*
+ * 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 _MIPS_ASM_H_
+#define _MIPS_ASM_H_
+
+/*
+ * asm.h: various macros to help assembly language writers
+ */
+
+/* ABI specific stack frame layout and manipulation. */
+#if _MIPS_SIM==_ABIO32
+/* Standard O32 */
+#define SZREG		4	/* saved register size */
+#define	REG_S		sw	/* store saved register */
+#define	REG_L		lw	/* load saved register */
+#define SZARG		4	/* argument register size */
+#define	NARGSAVE	4	/* arg register space on caller stack */
+#define ALSZ		7	/* stack alignment - 1 */
+#define ALMASK		(~7)	/* stack alignment mask */
+#define LOG2_STACK_ALGN	3	/* log2(8) */
+#define SZPTR		4	/* pointer size */
+#define LOG2_SZPTR	2	/* log2(4) */
+#define PTR_S		sw	/* store pointer */
+#define PTR_L		lw	/* load pointer */
+#define PTR_SUBU	subu	/* decrement pointer */
+#define PTR_ADDU	addu	/* increment pointer */
+#define PTR_MFC0	mfc0	/* access CP0 pointer width register */
+#define PTR_MTC0	mtc0	/* access CP0 pointer width register */
+#define LA		la	/* load an address */
+#define PTR		.word	/* pointer type pseudo */
+#elif _MIPS_SIM==_ABIO64
+/* Cygnus O64 */
+#define SZREG		8	/* saved register size */
+#define	REG_S		sd	/* store saved register */
+#define	REG_L		ld	/* load saved register */
+#define SZARG		8	/* argument register size */
+#define	NARGSAVE	4	/* arg register space on caller stack */
+#define ALSZ		7	/* stack alignment - 1 */
+#define ALMASK		(~7)	/* stack alignment mask */
+#define LOG2_STACK_ALGN	3	/* log2(8) */
+#define SZPTR		4	/* pointer size */
+#define LOG2_SZPTR	2	/* log2(4) */
+#define PTR_S		sw	/* store pointer */
+#define PTR_L		lw	/* load pointer */
+#define PTR_SUBU	subu	/* decrement pointer */
+#define PTR_ADDU	addu	/* increment pointer */
+#define PTR_MFC0	dmfc0	/* access CP0 pointer width register */
+#define PTR_MTC0	mtc0	/* access CP0 pointer width register */
+#define LA		la	/* load an address */
+#define PTR		.word	/* pointer type pseudo */
+#elif _MIPS_SIM==_ABIN32
+/* Standard N32 */
+#define SZREG		8	/* saved register size */
+#define	REG_S		sd	/* store saved register */
+#define	REG_L		ld	/* load saved register */
+#define SZARG		8	/* argument register size */
+#define	NARGSAVE	0	/* arg register space on caller stack */
+#define ALSZ		15	/* stack alignment - 1 */
+#define ALMASK		(~15)	/* stack alignment mask */
+#define LOG2_STACK_ALGN	4	/* log2(16) */
+#define SZPTR		4	/* pointer size */
+#define LOG2_SZPTR	2	/* log2(4) */
+#define PTR_S		sw	/* store pointer */
+#define PTR_L		lw	/* load pointer */
+#define PTR_SUBU	subu	/* decrement pointer (SGI uses sub) */
+#define PTR_ADDU	addu	/* increment pointer (SGI uses add) */
+#define PTR_MFC0	mfc0	/* access CP0 pointer width register */
+#define PTR_MTC0	mtc0	/* access CP0 pointer width register */
+#define LA		la	/* load an address */
+#define PTR		.word	/* pointer type pseudo */
+#elif _MIPS_SIM==_ABI64
+/* Standard N64 */
+#define SZREG		8	/* saved register size */
+#define	REG_S		sd	/* store saved register */
+#define	REG_L		ld	/* load saved register */
+#define SZARG		8	/* argument register size */
+#define	NARGSAVE	0	/* arg register space on caller stack */
+#define ALSZ		15	/* stack alignment - 1 */
+#define ALMASK		(~15)	/* stack alignment mask */
+#define LOG2_STACK_ALGN	4	/* log2(16) */
+#define SZPTR		8	/* pointer size */
+#define LOG2_SZPTR	3	/* log2(8) */
+#define PTR_S		sd	/* store pointer */
+#define PTR_L		ld	/* load pointer */
+#define PTR_SUBU	dsubu	/* decrement pointer */
+#define PTR_ADDU	daddu	/* increment pointer */
+#define PTR_MFC0	dmfc0	/* access CP0 pointer width register */
+#define PTR_MTC0	dmtc0	/* access CP0 pointer width register */
+#define LA		dla	/* load an address */
+#define PTR		.dword	/* pointer type pseudo */
+#else
+#error Unknown ABI
+#endif
+
+#if defined(__ASSEMBLER__)
+
+/* Concatenate two names. */
+#ifdef __STDC__
+# define _ASMCONCAT(A, B) A ## B
+#else
+# define _ASMCONCAT(A, B) A/**/B
+#endif
+
+/* Name of reset code section. */
+#ifndef _RESET_SECTION
+# define _RESET_SECTION .section .reset, "ax", @progbits
+#endif
+
+#ifndef _RESET_SECTION_NAMED
+/* No function section support for now, since binutils fails to cope with
+   external branches. */
+# define _RESET_SECTION_NAMED(name) .pushsection .reset, "ax", @progbits
+#endif
+
+/* Name of boot code section. */
+#ifndef _BOOT_SECTION
+# define _BOOT_SECTION .section .boot, "ax", @progbits
+#endif
+
+#ifndef _BOOT_SECTION_NAMED
+/* No function section support for now, since binutils fails to cope with
+   external branches. */
+# define _BOOT_SECTION_NAMED(name) .pushsection .boot, "ax", @progbits
+#endif
+
+/* Name of standard code section. */
+#ifndef _NORMAL_SECTION_UNNAMED
+# define _NORMAL_SECTION_UNNAMED .section .text, "ax", @progbits
+#endif
+
+#ifndef _NORMAL_SECTION_NAMED
+# ifdef _FUNCTION_SECTIONS_
+#  define _NORMAL_SECTION_NAMED(name) .pushsection .text ##.name, "ax", @progbits
+# else
+#  define _NORMAL_SECTION_NAMED(name) .pushsection .text, "ax", @progbits
+# endif
+#endif
+
+/* Default code section. */
+#ifndef _TEXT_SECTION_NAMED
+# if defined(_RESETCODE)
+#  define _TEXT_SECTION_NAMED _RESET_SECTION_NAMED
+# elif defined(_BOOTCODE)
+#  define _TEXT_SECTION_NAMED _BOOT_SECTION_NAMED
+# else
+#  define _TEXT_SECTION_NAMED _NORMAL_SECTION_NAMED
+# endif
+#endif
+
+#ifndef _TEXT_SECTION
+# if defined(_RESETCODE)
+#  define _TEXT_SECTION _RESET_SECTION
+# elif defined(_BOOTCODE)
+#  define _TEXT_SECTION _BOOT_SECTION
+# else
+#  define _TEXT_SECTION _NORMAL_SECTION_UNNAMED
+# endif
+	_TEXT_SECTION
+#endif
+
+/*
+ * Leaf functions declarations.
+ */
+
+/* Global leaf function. */
+#define LEAF(name) 			\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.globl	name; 			\
+	.ent	name; 			\
+name:
+
+/* Static/Local leaf function. */
+#define SLEAF(name) 			\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.ent	name; 			\
+name:
+
+/* Weak leaf function. */
+#define WLEAF(name) 			\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.weak	name; 			\
+	.ent	name; 			\
+name:
+
+/* Weak alias leaf function. */
+#define ALEAF(name,alias) 		\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.weak	alias;			\
+	.ent	name; 			\
+	alias = name;			\
+name:
+
+/*
+ * Alternative function entrypoints.
+ */
+
+/* Global alternative entrypoint. */
+#define AENT(name) 			\
+	.globl	name; 			\
+	.aent	name; 			\
+name:
+#define XLEAF(name)	AENT(name)
+
+/* Local/static alternative entrypoint. */
+#define SAENT(name) 			\
+	.aent	name; 			\
+name:
+#define SXLEAF(name)	SAENT(name)
+
+
+/*
+ * Leaf functions declarations.
+ */
+
+/* Global nested function. */
+#define NESTED(name, framesz, rareg)	\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.globl	name; 			\
+	.ent	name; 			\
+	.frame	sp, framesz, rareg;	\
+name:
+
+/* Static/Local nested function. */
+#define SNESTED(name, framesz, rareg)	\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.ent	name; 			\
+	.frame	sp, framesz, rareg;	\
+name:
+
+/* Weak nested function. */
+#define WNESTED(name, framesz, rareg)	\
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.weak	name; 			\
+	.ent	name; 			\
+	.frame	sp, framesz, rareg;	\
+name:
+
+/* Weak alias nested function. */
+#define ANESTED(name, alias, framesz, rareg) \
+	_TEXT_SECTION_NAMED(name);	\
+	.balign	4; 			\
+	.weak	alias;			\
+	.ent	name; 			\
+	alias = name;			\
+	.frame	sp, framesz, rareg;	\
+name:
+
+/*
+ * Function termination
+ */
+#define END(name) 			\
+	.size name,.-name; 		\
+	.end	name;			\
+	.popsection
+
+#define SEND(name)	END(name)
+#define WEND(name)	END(name)
+#define AEND(name,alias) END(name)
+
+/*
+ * Global data declaration.
+ */
+#define EXPORT(name) \
+	.globl name; \
+	.type name,@object; \
+name:
+
+/*
+ * Global data declaration with size.
+ */
+#define EXPORTS(name,sz) 		\
+	.globl name; 			\
+	.type name,@object; 		\
+	.size name,sz; 			\
+name:
+
+/*
+ * Weak data declaration with size.
+ */
+#define WEXPORT(name,sz) 		\
+	.weak name; 			\
+	.type name,@object; 		\
+	.size name,sz; 			\
+name:
+
+/*
+ * Global data reference with size.
+ */
+#define	IMPORT(name, size) 		\
+	.extern	name,size
+
+/*
+ * Global zeroed data.
+ */
+#define BSS(name,size) 			\
+	.type name,@object; 		\
+	.comm	name,size
+
+/*
+ * Local zeroed data.
+ */
+#define LBSS(name,size) 		\
+	.lcomm	name,size
+
+/*
+ * Insert call to _mcount if profiling.
+ */
+#ifdef __PROFILING__
+#define _MCOUNT 			\
+	.set push; 			\
+	.set noat; 			\
+	move	$1,$31; 		\
+	jal	_mcount; 		\
+	.set pop
+#else
+#define _MCOUNT
+#endif
+
+#endif /* __ASSEMBLER__ */
+
+#endif /*_MIPS_ASM_H_*/
diff --git a/libgloss/mips/include/mips/cm3.h b/libgloss/mips/include/mips/cm3.h
new file mode 100644
index 000000000..3a1c5a13e
--- /dev/null
+++ b/libgloss/mips/include/mips/cm3.h
@@ -0,0 +1,75 @@ 
+/*
+ * 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.
+*/
+
+#ifndef _CM3_H_
+#define _CM3_H_
+
+#define CMGCR_BASE_ADDR_SHIFT	11
+
+#define CMGCR_BASE_ADDR_LSHIFT	4
+/* Offsets of memory-mapped registers */
+#define GCR_L2_CONFIG		0x130
+#define GCR_L2_RAM_CONFIG	0x240
+#define GCR_TAG_ADDR		0x600
+#define GCR_TAG_STATE		0x608
+#define GCR_TAG_DATA		0x610
+#define GCR_TAG_ECC		0x618
+
+/* Contents of  L2 RAM field */
+#define GCR_L2_RAM_HCID_SHIFT	30
+#define GCR_L2_RAM_HCID_BITS	1
+#define GCR_L2_RAM_HCIS_SHIFT	29
+#define GCR_L2_RAM_HCIS_BITS	1
+
+/* L2 Configuration Register */
+#define GCR_L2_REG_EXISTS_MASK	0x80000000
+#define GCR_L2_REG_EXISTS_SHIFT	31
+#define GCR_L2_REG_EXISTS_BITS	1
+#define GCR_L2_LRU_WE_MASK	(1<<GCR_L2_LRU_WE_SHIFT)
+#define GCR_L2_LRU_WE_SHIFT	26
+#define GCR_L2_LRU_WE_BITS	1
+#define GCR_L2_TAG_WE_MASK	(1<<GCR_L2_TAG_WE_SHIFT)
+#define GCR_L2_TAG_WE_SHIFT	25
+#define GCR_L2_TAG_WE_BITS	1
+#define GCR_L2_ECC_WE_MASK	(1<<GCR_L2_ECC_WE_SHIFT)
+#define GCR_L2_ECC_WE_SHIFT	24
+#define GCR_L2_ECC_WE_BITS	1
+#define GCR_L2_BYPASS_MASK	(1<<GCR_L2_BYPASS_SHIFT)
+#define GCR_L2_BYPASS_SHIFT	20
+#define GCR_L2_BYPASS_BITS	1
+#define GCR_L2_SS_MASK		0x0000F000
+#define GCR_L2_SS_SHIFT		12
+#define GCR_L2_SS_BITS		4
+#define GCR_L2_SL_MASK		0x00000F00
+#define GCR_L2_SL_SHIFT		8
+#define GCR_L2_SL_BITS		4
+#define GCR_L2_SA_MASK		0x000000FF
+#define GCR_L2_SA_SHIFT		0
+#define GCR_L2_SA_BITS		8
+
+#endif /* _CM3_H_ */
diff --git a/libgloss/mips/include/mips/cpu.h b/libgloss/mips/include/mips/cpu.h
new file mode 100644
index 000000000..d67a0585b
--- /dev/null
+++ b/libgloss/mips/include/mips/cpu.h
@@ -0,0 +1,354 @@ 
+/*
+ * 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 _CPU_H_
+#define _CPU_H_
+
+#if !defined(__ASSEMBLER__)
+#include <sys/types.h>
+#endif
+
+#ifndef SR_IMASK
+#if __mips == 64
+#include <mips/m64c0.h>
+#elif __mips == 32
+#include <mips/m32c0.h>
+#endif
+#endif /* SR_IMASK */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(__ASSEMBLER__)
+/*
+ * Generic MIPS cache handling
+ *
+ *   primary: virtual index, physical tag, write back;
+ *   secondary: physical index, physical tag, write back;
+ *   pass correct virtual address to primary cache routines.
+ */
+
+#ifdef __mips16
+# define _MIPS_CPU_NOMIPS16 __attribute__((nomips16))
+#else
+# define _MIPS_CPU_NOMIPS16
+#endif
+
+extern int	mips_icache_size, mips_icache_linesize, mips_icache_ways;
+extern int	mips_dcache_size, mips_dcache_linesize, mips_dcache_ways;
+extern int	mips_scache_size, mips_scache_linesize, mips_scache_ways;
+extern int	mips_tcache_size, mips_tcache_linesize, mips_tcache_ways;
+
+/* these are now the only standard interfaces to the caches */
+_MIPS_CPU_NOMIPS16
+extern void	mips_size_cache (void);
+_MIPS_CPU_NOMIPS16
+extern void	mips_flush_cache (void);
+_MIPS_CPU_NOMIPS16
+extern void	mips_flush_dcache (void);
+_MIPS_CPU_NOMIPS16
+extern void	mips_flush_icache (void);
+_MIPS_CPU_NOMIPS16
+extern void	mips_sync_icache (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_clean_cache (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_clean_dcache (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_clean_dcache_nowrite (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_clean_icache (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_lock_dcache (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_lock_icache (vaddr_t, size_t);
+_MIPS_CPU_NOMIPS16
+extern void	mips_lock_scache (vaddr_t, size_t);
+
+/*
+ * Other common utilities for all CPUs
+ */
+extern void	mips_wbflush (void);
+extern void	mips_cycle (unsigned);
+_MIPS_CPU_NOMIPS16
+extern int	mips_tlb_size (void);
+
+/*
+ * Coprocessor 0 register manipulation
+ * Warning: all non-atomic in face of interrupts.
+ */
+#if defined(_mips_mfc0)
+
+/* exchange (swap) VAL and cp0 register REG */
+#define _mips_mxc0(reg, val) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _mips_mfc0 (reg); \
+    _mips_mtc0 (reg, (val)); \
+    __o; \
+})
+
+/* bit clear non-zero bits from CLR in cp0 register REG */
+#define _mips_bcc0(reg, clr) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _mips_mfc0 (reg); \
+    _mips_mtc0 (reg, __o & ~(clr)); \
+    __o; \
+})
+
+/* bit set non-zero bits from SET in cp0 register REG */
+#define _mips_bsc0(reg, set) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _mips_mfc0 (reg); \
+    _mips_mtc0 (reg, __o | (set)); \
+    __o; \
+})
+
+/* bit clear nz bits in from CLR and set nz bits from SET in REG */
+#define _mips_bcsc0(reg, clr, set) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _mips_mfc0 (reg); \
+    _mips_mtc0 (reg, (__o & ~(clr)) | (set)); \
+    __o; \
+})
+
+/*
+ * Standard MIPS CP0 register access functions
+ */
+
+/* CP0 Status register (NOTE: not atomic operations) */
+#define mips_getsr()		_mips_mfc0(C0_SR)
+#define mips_setsr(v)		_mips_mtc0(C0_SR,v)
+#define mips_xchsr(v)		_mips_mxc0(C0_SR,v)
+#define mips_bicsr(clr)		_mips_bcc0(C0_SR,clr)
+#define mips_bissr(set)		_mips_bsc0(C0_SR,set)
+#define mips_bcssr(c,s)		_mips_bcsc0(C0_SR,c,s)
+
+/* CP0 Cause register (NOTE: not atomic operations) */
+#define mips_getcr()		_mips_mfc0(C0_CR)
+#define mips_setcr(v)		_mips_mtc0(C0_CR,v)
+#define mips_xchcr(v)		_mips_mxc0(C0_CR,v)
+#define mips_biccr(clr)		_mips_bcc0(C0_CR,clr)
+#define mips_biscr(set)		_mips_bsc0(C0_CR,set)
+#define mips_bcscr(c,s)		_mips_bcsc0(C0_CR,c,s)
+
+/* CP0 PrID register */
+#define mips_getprid()		_mips_mfc0(C0_PRID)
+
+#ifdef C0_COUNT
+/* CP0 Count register */
+#define mips_getcount()		_mips_mfc0(C0_COUNT)
+#define mips_setcount(v)	_mips_mtc0(C0_COUNT,v)
+#define mips_xchcount(v)	_mips_mxc0(C0_COUNT,v)
+#endif
+
+#ifdef C0_COMPARE
+/* CP0 Compare register*/
+#define mips_getcompare()	_mips_mfc0(C0_COMPARE)
+#define mips_setcompare(v)	_mips_mtc0(C0_COMPARE,v)
+#define mips_xchcompare(v)	_mips_mxc0(C0_COMPARE,v)
+#endif
+
+#ifdef C0_CONFIG
+/* CP0 Config register */
+#define mips_getconfig()	_mips_mfc0(C0_CONFIG)
+#define mips_setconfig(v)	_mips_mtc0(C0_CONFIG,v)
+#define mips_xchconfig(v)	_mips_mxc0(C0_CONFIG,v)
+#define mips_bicconfig(c)	_mips_bcc0(C0_CONFIG,c)
+#define mips_bisconfig(s)	_mips_bsc0(C0_CONFIG,s)
+#define mips_bcsconfig(c,s)	_mips_bcsc0(C0_CONFIG,c,s)
+#endif
+
+#ifdef C0_ECC
+/* CP0 ECC register */
+#define mips_getecc()		_mips_mfc0(C0_ECC)
+#define mips_setecc(x)		_mips_mtc0(C0_ECC, x)
+#define mips_xchecc(x)		_mips_mxc0(C0_ECC, x)
+#endif
+
+#ifdef C0_TAGLO
+/* CP0 TagLo register */
+#define mips_gettaglo()		_mips_mfc0(C0_TAGLO)
+#define mips_settaglo(x)	_mips_mtc0(C0_TAGLO, x)
+#define mips_xchtaglo(x)	_mips_mxc0(C0_TAGLO, x)
+#endif
+
+#ifdef C0_TAGHI
+/* CP0 TagHi register */
+#define mips_gettaghi()		_mips_mfc0(C0_TAGHI)
+#define mips_settaghi(x)	_mips_mtc0(C0_TAGHI, x)
+#define mips_xchtaghi(x)	_mips_mxc0(C0_TAGHI, x)
+#endif
+
+#ifdef C0_WATCHLO
+/* CP0 WatchLo register */
+#define mips_getwatchlo()	_mips_mfc0(C0_WATCHLO)
+#define mips_setwatchlo(x)	_mips_mtc0(C0_WATCHLO, x)
+#define mips_xchwatchlo(x)	_mips_mxc0(C0_WATCHLO, x)
+#endif
+
+#ifdef C0_WATCHHI
+/* CP0 WatchHi register */
+#define mips_getwatchhi()	_mips_mfc0(C0_WATCHHI)
+#define mips_setwatchhi(x)	_mips_mtc0(C0_WATCHHI, x)
+#define mips_xchwatchhi(x)	_mips_mxc0(C0_WATCHHI, x)
+#endif
+
+#endif /*_mips_mfc0*/
+
+/*
+ * Count-leading zeroes and ones.
+ * Simulate with a function call if this CPU hasn't defined a
+ * macro with a suitable asm.
+ */
+#if !defined(mips_clz)
+extern unsigned int _mips_clz(unsigned int);
+#define	mips_clz(x)	_mips_clz(x)
+#define	mips_clo(x)	_mips_clz(~(x))
+#else
+#define _mips_have_clz 1
+#endif
+
+#if !defined(mips_dclz)
+extern unsigned int _mips_dclz(unsigned long long);
+#define	mips_dclz(x)	_mips_dclz(x)
+#define	mips_dclo(x)	_mips_dclz(~(x))
+#else
+#define _mips_have_dclz 1
+#endif
+
+/*
+ * Generic MIPS prefetch instruction for MIPS IV and
+ * above. CPU-specific include files must define
+ * prefetch "hint" codes.
+ */
+#if __mips >= 4
+#define _mips_pref(OP,LOC) \
+do { \
+    __asm__ ("pref %0,%1" : : "n" (OP), "m" (LOC));	\
+} while (0)
+#else
+/* pref not available for MIPS16 */
+#define _mips_pref(OP,LOC) (void)0
+#endif
+
+#ifndef PREF_LOAD
+#define PREF_LOAD		0
+#endif
+#ifndef PREF_STORE
+#define PREF_STORE		0
+#endif
+#ifndef PREF_LOAD_STREAMED
+#define PREF_LOAD_STREAMED	PREF_LOAD
+#define PREF_STORE_STREAMED	PREF_STORE
+#endif
+#ifndef PREF_LOAD_RETAINED
+#define PREF_LOAD_RETAINED	PREF_LOAD
+#define PREF_STORE_RETAINED	PREF_STORE
+#endif
+
+#define mips_prefetch __builtin_prefetch
+
+#ifdef PREF_WRITEBACK_INVAL
+/* MIPS specific "nudge" (push to memory) operation */
+#define mips_nudge(ADDR) \
+    _mips_pref(PREF_WRITEBACK_INVAL, *(ADDR))
+#else
+#define mips_nudge(ADDR) (void)0
+#endif
+
+#ifdef PREF_PREPAREFORSTORE
+/* MIPS specific "prepare for store" operation */
+/* XXX Warning - may zero whole cache line, ensure cache line alignment */
+#define mips_prepare_for_store(ADDR) \
+    _mips_pref(PREF_PREPAREFORSTORE, *(ADDR))
+#else
+#define mips_prepare_for_store(ADDR) (void)0
+#endif
+
+/*
+ * Default versions of get/put for any MIPS CPU.
+ */
+#ifndef mips_get_byte
+#define mips_get_byte(addr, errp)	(*(volatile unsigned char *)(addr))
+#define mips_get_half(addr, errp)	(*(volatile unsigned short *)(addr))
+#define mips_get_word(addr, errp)	(*(volatile unsigned int *)(addr))
+#define mips_get_dword(addr, errp)	(*(volatile unsigned long long *)(addr))
+
+#define mips_put_byte(addr, v)	(*(volatile unsigned char *)(addr)=(v), 0)
+#define mips_put_half(addr, v)	(*(volatile unsigned short *)(addr)=(v), 0)
+#define mips_put_word(addr, v)	(*(volatile unsigned int *)(addr)=(v), 0)
+#define mips_put_dword(addr, v)	(*(volatile unsigned long long *)(addr)=(v), 0)
+#endif /* mips_get_byte */
+
+/* unoptimisable 2 instruction loop */
+
+#define mips_cycle(count)				\
+    do {						\
+      unsigned int __count = (count);			\
+      __asm__ volatile ("%(nop; nop; 1: bnez %0,1b; subu %0,1%)"	\
+	: "+d" (__count)); 				\
+    } while (0)
+
+/* default implementation of _mips_intdisable is a function */
+
+/* There are no microMIPS implementations that support MSA currently.  */
+#if !defined(__mips_micromips)
+# define MIPS_MSA_USABLE 1
+#else
+# define MIPS_MSA_USABLE 0
+#endif
+
+#else /* ASSEMBLER */
+
+/* The correct way to use a hazard barrier return */
+
+/* JR.HB does not resolve hazards from its delay slot.  */
+#define MIPS_JRHB(REG) \
+  .set push;	  \
+  .set noreorder;  \
+  jr.hb REG;	  \
+  nop;		  \
+  .set pop
+
+#define MIPS_NOMICROMIPS \
+  .set nomicromips
+
+#define MIPS_NOMIPS16 \
+  .set nomips16
+
+#endif /* !ASSEMBLER */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*_CPU_H_*/
diff --git a/libgloss/mips/include/mips/ctx.S b/libgloss/mips/include/mips/ctx.S
new file mode 100644
index 000000000..74124d6e4
--- /dev/null
+++ b/libgloss/mips/include/mips/ctx.S
@@ -0,0 +1,147 @@ 
+/*
+ * Copyright (C) 2016-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.
+*/
+
+#include <mips/regdef.h>
+#include <mips/asm.h>
+#include <mips/cpu.h>
+#include <mips/hal.h>
+
+/* Save the hard context to a gp_ctx pointed to by k1.
+   Leave the value of C0_STATUS in the return register.
+   Leave the value of k1 unchanged.  */
+
+.macro _gpctx_save
+	/* Save general registers.  */
+	REG_S   $1, CTX_REG(1) (k1)
+	REG_S   $2, CTX_REG(2) (k1)
+	REG_S   $3, CTX_REG(3) (k1)
+	REG_S   $4, CTX_REG(4) (k1)
+	REG_S   $5, CTX_REG(5) (k1)
+	REG_S   $6, CTX_REG(6) (k1)
+	REG_S   $7, CTX_REG(7) (k1)
+	REG_S   $8, CTX_REG(8) (k1)
+	REG_S   $9, CTX_REG(9) (k1)
+	REG_S   $10, CTX_REG(10) (k1)
+	REG_S   $11, CTX_REG(11) (k1)
+	REG_S   $12, CTX_REG(12) (k1)
+	REG_S   $13, CTX_REG(13) (k1)
+	REG_S   $14, CTX_REG(14) (k1)
+	REG_S   $15, CTX_REG(15) (k1)
+	REG_S   $16, CTX_REG(16) (k1)
+	REG_S   $17, CTX_REG(17)(k1)
+	REG_S   $18, CTX_REG(18)(k1)
+	REG_S   $19, CTX_REG(19)(k1)
+	REG_S   $20, CTX_REG(20)(k1)
+	REG_S   $21, CTX_REG(21)(k1)
+	REG_S   $22, CTX_REG(22)(k1)
+	REG_S   $23, CTX_REG(23)(k1)
+	REG_S   $24, CTX_REG(24)(k1)
+	REG_S   $25, CTX_REG(25)(k1)
+	REG_S   $26, CTX_REG(26)(k1)
+	/* $27/k1 must be saved prior to using this macro.  */
+	REG_S   $28, CTX_REG(28)(k1)
+	REG_S   $29, CTX_REG(29)(k1)
+	REG_S   $30, CTX_REG(30)(k1)
+	REG_S   $31, CTX_REG(31)(k1)
+	PTR_S   $0, CTX_LINK(k1) 	/* Clear the link field.  */
+
+	/* Check ISA release and optionally restore HI/LO registers.  */
+#if (__mips_isa_rev < 6)
+	mfhi	$9
+	REG_S	$9, CTX_HI0(k1)
+	mflo	$10
+	REG_S	$10, CTX_LO0(k1)
+#endif
+
+	/* Save CP0 registers.  */
+	PTR_MFC0 $31, C0_EPC
+	REG_S	$31, CTX_EPC(k1)
+	mfc0	va0, C0_STATUS
+	sw	va0, CTX_STATUS(k1)
+.endm
+
+/* Restores a gp_ctx pointed to by a0.  Leaves interrupts disabled and
+   C0_EPC ready to eret.  */
+
+.macro _gpctx_load
+
+	/* Check ISA release and optionally restore HI/LO registers.  */
+#if (__mips_isa_rev < 6)
+	REG_L	$9, CTX_HI0(a0)
+	REG_L	$10, CTX_LO0(a0)
+	mthi	$9
+	mtlo	$10
+#endif
+
+	/* Restore the general registers.  */
+	REG_L	$1, CTX_REG(1)(a0)
+	REG_L	$2, CTX_REG(2)(a0)
+	REG_L	$3, CTX_REG(3)(a0)
+	/* Do not restore $4 until the end.  */
+	REG_L	$5, CTX_REG(5)(a0)
+	REG_L	$6, CTX_REG(6)(a0)
+	REG_L	$7, CTX_REG(7)(a0)
+	REG_L	$8, CTX_REG(8)(a0)
+	REG_L	$9, CTX_REG(9)(a0)
+	REG_L	$10, CTX_REG(10)(a0)
+	REG_L	$11, CTX_REG(11)(a0)
+	REG_L	$12, CTX_REG(12)(a0)
+	REG_L	$13, CTX_REG(13)(a0)
+	REG_L	$14, CTX_REG(14)(a0)
+	REG_L	$15, CTX_REG(15)(a0)
+	REG_L	$16, CTX_REG(16)(a0)
+	REG_L	$17, CTX_REG(17)(a0)
+	REG_L	$18, CTX_REG(18)(a0)
+	REG_L	$19, CTX_REG(19)(a0)
+	REG_L	$20, CTX_REG(20)(a0)
+	REG_L	$21, CTX_REG(21)(a0)
+	REG_L	$22, CTX_REG(22)(a0)
+	REG_L	$23, CTX_REG(23)(a0)
+	REG_L	$24, CTX_REG(24)(a0)
+	REG_L	$25, CTX_REG(25)(a0)
+
+	/* Restore CP0 registers, kernel registers and stack with
+	   interrupts disabled.  */
+	di
+	lw	$27, CTX_STATUS(a0)
+	REG_L	$26, CTX_EPC(a0)
+	mtc0	$27, C0_STATUS
+	PTR_MTC0 $26, C0_EPC
+	ehb
+
+	REG_L	$26, CTX_REG(26)(a0)
+	REG_L	$27, CTX_REG(27)(a0)
+	REG_L	$28, CTX_REG(28)(a0)
+	REG_L	$29, CTX_REG(29)(a0)
+	REG_L	$30, CTX_REG(30)(a0)
+	REG_L	$31, CTX_REG(31)(a0)
+
+	/* Finally restore a0/$4.  */
+	REG_L	$4, CTX_REG(4)(a0)
+
+.endm
diff --git a/libgloss/mips/include/mips/dsp.h b/libgloss/mips/include/mips/dsp.h
new file mode 100644
index 000000000..5d3b56cde
--- /dev/null
+++ b/libgloss/mips/include/mips/dsp.h
@@ -0,0 +1,58 @@ 
+/*
+ * 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 _MIPS_ASE_H_
+#define _MIPS_ASE_H_
+
+/* 32-bit DSP Control register */
+#define DSPCTL_POS_SHIFT	0
+#define DSPCTL_POS_MASK		0x0000007f
+#define DSPCTL_SCOUNT_SHIFT	7
+#define DSPCTL_SCOUNT_MASK	0x00001f80
+#define DSPCTL_C		0x00002000
+#define DSPCTL_OU_SHIFT		16
+#define DSPCTL_OU_MASK		0x00ff0000
+#define  DSPCTL_OU_AC0OVF	 0x00010000
+#define  DSPCTL_OU_AC1OVF	 0x00020000
+#define  DSPCTL_OU_AC2OVF	 0x00040000
+#define  DSPCTL_OU_AC3OVF	 0x00080000
+#define  DSPCTL_OU_ALUOVF	 0x00100000
+#define  DSPCTL_OU_MULOVF	 0x00200000
+#define  DSPCTL_OU_SHFOVF	 0x00400000
+#define  DSPCTL_OU_EXTOVF	 0x00800000
+#define DSPCTL_CCOND_SHIFT	24
+#define DSPCTL_CCOND_MASK	0x0f000000
+
+/* RDDSP/WRDSP instruction mask bits */
+#define RWDSP_POS		0x01
+#define RWDSP_SCOUNT		0x02
+#define RWDSP_C			0x04
+#define RWDSP_OU		0x08
+#define RWDSP_CCOND		0x10
+
+#endif /* _MIPS_DSP_H_ */
diff --git a/libgloss/mips/include/mips/endian.h b/libgloss/mips/include/mips/endian.h
new file mode 100644
index 000000000..bb4421707
--- /dev/null
+++ b/libgloss/mips/include/mips/endian.h
@@ -0,0 +1,91 @@ 
+/*
+ * 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 __MACHINE_ENDIAN_H__
+#error "must be included via <machine/endian.h>"
+#endif /* !__MACHINE_ENDIAN_H__ */
+
+#ifndef __ASSEMBLER__
+#include <stdint.h>	/* get compiler types */
+#include <sys/types.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _BYTE_ORDER
+/*
+ * Definitions for byte order,
+ * according to byte significance from low address to high.
+ */
+#define _LITTLE_ENDIAN   1234    /* least-significant byte first (vax) */
+#define _BIG_ENDIAN      4321    /* most-significant byte first (IBM, net) */
+
+#if defined(__MIPSEB__) || defined(MIPSEB)
+#define _BYTE_ORDER      _BIG_ENDIAN
+#elif defined(__MIPSEL__) || defined(MIPSEL)
+#define _BYTE_ORDER      _LITTLE_ENDIAN
+#else
+#error _BYTE_ORDER
+#endif
+
+#ifndef __ASSEMBLER__
+
+#if __mips_isa_rev >= 2 && ! __mips16
+
+/* MIPS32r2 & MIPS64r2 can use the wsbh and rotate instructions, define
+   MD_SWAP so that <sys/endian.h> will use them. */
+
+#define MD_SWAP
+
+#define __swap16md(x) __extension__({					\
+    uint16_t __swap16md_x = (x);					\
+    uint16_t __swap16md_v;						\
+    __asm__ ("wsbh %0,%1" 						\
+	     : "=d" (__swap16md_v) 					\
+	     : "d" (__swap16md_x)); 					\
+    __swap16md_v; 							\
+})
+
+#define __swap32md(x) __extension__({					\
+    uint32_t __swap32md_x = (x);					\
+    uint32_t __swap32md_v;						\
+    __asm__ ("wsbh %0,%1; rotr %0,16" 					\
+	     : "=d" (__swap32md_v) 					\
+	     : "d" (__swap32md_x)); 					\
+    __swap32md_v; 							\
+})
+
+#endif
+#endif /* __ASSEMBLER__ */
+#endif	/* _BYTE_ORDER */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libgloss/mips/include/mips/fgregdef.h b/libgloss/mips/include/mips/fgregdef.h
new file mode 100644
index 000000000..a03009f8e
--- /dev/null
+++ b/libgloss/mips/include/mips/fgregdef.h
@@ -0,0 +1,126 @@ 
+/*
+ * 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 _MIPS_FPREGDEF_H_
+#define _MIPS_FPREGDEF_H_
+
+/* result registers */
+#define fv0	$f0
+#define fv1	$f2
+
+/* argument registers */
+#define fa0	$f12
+#if  (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
+     || (defined _ABI64 && _MIPS_SIM == _ABI64)
+#define fa1	$f13
+#else
+#define fa1	$f14
+#endif
+
+#if __mips_fpr == 64
+
+/* 64-bit f.p. registers (-mips3 and above) */
+
+/* temporary registers */
+#define ft0	$f4
+#define ft1	$f5
+#define ft2	$f6
+#define ft3	$f7
+#define ft4	$f8
+#define ft5	$f9
+#define ft6	$f10
+#define ft7	$f11
+#define ft8	$f16
+#define ft9	$f17
+#define ft10	$f18
+#define ft11	$f19
+
+# if  (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
+      || (defined _ABI64 && _MIPS_SIM == _ABI64)
+/* saved registers */
+#  define	fs0	$f20
+#  define	fs1	$f21
+#  define	fs2	$f22
+#  define	fs3	$f23
+#  define	fs4	$f24
+#  define	fs5	$f35
+#  define	fs6	$f26
+#  define	fs7	$f27
+#  define	fs8	$f28
+#  define	fs9	$f29
+#  define	fs10	$f30
+#  define	fs11	$f31
+# else
+/* o32 FP64 */
+#  define	ft12	$f21
+#  define	ft13	$f23
+#  define	ft14	$f35
+#  define	ft15	$f27
+#  define	ft16	$f29
+#  define	ft17	$f31
+#  define	fs0	$f20
+#  define	fs1	$f22
+#  define	fs2	$f24
+#  define	fs3	$f26
+#  define	fs4	$f28
+#  define	fs5	$f30
+# endif
+
+#else
+
+/* 32-bit f.p. registers */
+
+/* temporary registers */
+#define ft0	$f4
+#define ft1	$f5
+#define ft2	$f6
+#define ft3	$f7
+#define ft4	$f8
+#define ft5	$f9
+#define ft6	$f10
+#define ft7	$f11
+#define ft8	$f12
+#define ft9	$f13
+#define ft10	$f14
+#define ft11	$f15
+#define ft12	$f16
+#define ft13	$f17
+#define ft14	$f18
+#define ft15	$f19
+
+/* saved registers */
+#define	fs0	$f20
+#define	fs1	$f22
+#define	fs2	$f24
+#define	fs3	$f26
+#define	fs4	$f28
+#define	fs5	$f30
+
+#endif
+
+#endif /*_MIPS_FPREGDEF_H_*/
diff --git a/libgloss/mips/include/mips/fpa.h b/libgloss/mips/include/mips/fpa.h
new file mode 100644
index 000000000..622a88a5c
--- /dev/null
+++ b/libgloss/mips/include/mips/fpa.h
@@ -0,0 +1,31 @@ 
+/*
+ * 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.
+*/
+
+#if __mips == 32 || __mips == 64
+#include <mips/m32c1.h>
+#endif
diff --git a/libgloss/mips/include/mips/hal.h b/libgloss/mips/include/mips/hal.h
new file mode 100644
index 000000000..31f614ee8
--- /dev/null
+++ b/libgloss/mips/include/mips/hal.h
@@ -0,0 +1,454 @@ 
+/*
+ * 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 _HAL_H
+#define _HAL_H
+
+#include <mips/asm.h>
+#include <mips/m32c0.h>
+
+#if _MIPS_SIM == _ABIO32
+#define UHI_ABI 0
+#elif _MIPS_SIM == _ABIN32
+#define UHI_ABI 1
+#elif _MIPS_SIM == _ABI64
+#define UHI_ABI 2
+#else
+#error "UHI context structure is not defined for current ABI"
+#endif
+
+#define CTX_REG(REGNO)	((SZREG)*((REGNO)-1))
+
+#define CTX_AT		(CTX_REG(1))
+#define CTX_V0		(CTX_REG(2))
+#define CTX_V1		(CTX_REG(3))
+#define CTX_A0		(CTX_REG(4))
+#define CTX_A1		(CTX_REG(5))
+#define CTX_A2		(CTX_REG(6))
+#define CTX_A3		(CTX_REG(7))
+#if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI
+# define CTX_A4		(CTX_REG(8))
+# define CTX_A5		(CTX_REG(9))
+# define CTX_A6		(CTX_REG(10))
+# define CTX_A7		(CTX_REG(11))
+# define CTX_T0		(CTX_REG(12))
+# define CTX_T1		(CTX_REG(13))
+# define CTX_T2		(CTX_REG(14))
+# define CTX_T3		(CTX_REG(15))
+#else
+# define CTX_T0		(CTX_REG(8))
+# define CTX_T1		(CTX_REG(9))
+# define CTX_T2		(CTX_REG(10))
+# define CTX_T3		(CTX_REG(11))
+# define CTX_T4		(CTX_REG(12))
+# define CTX_T5		(CTX_REG(13))
+# define CTX_T6		(CTX_REG(14))
+# define CTX_T7		(CTX_REG(15))
+#endif
+#define CTX_S0		(CTX_REG(16))
+#define CTX_S1		(CTX_REG(17))
+#define CTX_S2		(CTX_REG(18))
+#define CTX_S3		(CTX_REG(19))
+#define CTX_S4		(CTX_REG(20))
+#define CTX_S5		(CTX_REG(21))
+#define CTX_S6		(CTX_REG(22))
+#define CTX_S7		(CTX_REG(23))
+#define CTX_T8		(CTX_REG(24))
+#define CTX_T9		(CTX_REG(25))
+#define CTX_K0		(CTX_REG(26))
+#define CTX_K1		(CTX_REG(27))
+#define CTX_GP		(CTX_REG(28))
+#define CTX_SP		(CTX_REG(29))
+#define CTX_FP		(CTX_REG(30))
+#define CTX_RA		(CTX_REG(31))
+#define CTX_EPC		(CTX_REG(32))
+#define CTX_BADVADDR	(CTX_REG(33))
+#define CTX_HI0		(CTX_REG(34))
+#define CTX_LO0		(CTX_REG(35))
+#define CTX_HILO_SIZE	(2*SZREG)
+#define CTX_LINK	(CTX_REG(34)+CTX_HILO_SIZE)
+#define CTX_STATUS	((CTX_REG(34))+CTX_HILO_SIZE+SZPTR)
+#define CTX_CAUSE	((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+4)
+#define CTX_BADINSTR	((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+8)
+#define CTX_BADPINSTR	((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+12)
+#define CTX_SIZE	((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+16)
+
+#define DSPCTX_DSPC ((SZREG)*2)
+#define DSPCTX_HI1  ((SZREG)*3)
+#define DSPCTX_HI2  ((SZREG)*4)
+#define DSPCTX_HI3  ((SZREG)*5)
+#define DSPCTX_LO1  ((SZREG)*6)
+#define DSPCTX_LO2  ((SZREG)*7)
+#define DSPCTX_LO3  ((SZREG)*8)
+#define DSPCTX_SIZE ((SZREG)*9)
+
+#define FP32CTX_CSR	((SZREG)*2)
+#define FP64CTX_CSR	((SZREG)*2)
+#define MSACTX_FCSR	((SZREG)*2)
+#define MSACTX_MSACSR	((SZREG)*3)
+
+#define MSACTX_0	((SZREG)*4)
+#define MSACTX_1	(MSACTX_0 + (1 * 16))
+#define MSACTX_2	(MSACTX_0 + (2 * 16))
+#define MSACTX_3	(MSACTX_0 + (3 * 16))
+#define MSACTX_4	(MSACTX_0 + (4 * 16))
+#define MSACTX_5	(MSACTX_0 + (5 * 16))
+#define MSACTX_6	(MSACTX_0 + (6 * 16))
+#define MSACTX_7	(MSACTX_0 + (7 * 16))
+#define MSACTX_8	(MSACTX_0 + (8 * 16))
+#define MSACTX_9	(MSACTX_0 + (9 * 16))
+#define MSACTX_10	(MSACTX_0 + (10 * 16))
+#define MSACTX_11	(MSACTX_0 + (11 * 16))
+#define MSACTX_12	(MSACTX_0 + (12 * 16))
+#define MSACTX_13	(MSACTX_0 + (13 * 16))
+#define MSACTX_14	(MSACTX_0 + (14 * 16))
+#define MSACTX_15	(MSACTX_0 + (15 * 16))
+#define MSACTX_16	(MSACTX_0 + (16 * 16))
+#define MSACTX_17	(MSACTX_0 + (17 * 16))
+#define MSACTX_18	(MSACTX_0 + (18 * 16))
+#define MSACTX_19	(MSACTX_0 + (19 * 16))
+#define MSACTX_20	(MSACTX_0 + (20 * 16))
+#define MSACTX_21	(MSACTX_0 + (21 * 16))
+#define MSACTX_22	(MSACTX_0 + (22 * 16))
+#define MSACTX_23	(MSACTX_0 + (23 * 16))
+#define MSACTX_24	(MSACTX_0 + (24 * 16))
+#define MSACTX_25	(MSACTX_0 + (25 * 16))
+#define MSACTX_26	(MSACTX_0 + (26 * 16))
+#define MSACTX_27	(MSACTX_0 + (27 * 16))
+#define MSACTX_28	(MSACTX_0 + (28 * 16))
+#define MSACTX_29	(MSACTX_0 + (29 * 16))
+#define MSACTX_30	(MSACTX_0 + (30 * 16))
+#define MSACTX_31	(MSACTX_0 + (31 * 16))
+#define MSACTX_SIZE	(MSACTX_0 + (32 * 16))
+
+#define FP32CTX_0	((SZREG)*4)
+#define FP32CTX_2	(FP32CTX_0 + (1 * 8))
+#define FP32CTX_4	(FP32CTX_0 + (2 * 8))
+#define FP32CTX_6	(FP32CTX_0 + (3 * 8))
+#define FP32CTX_8	(FP32CTX_0 + (4 * 8))
+#define FP32CTX_10	(FP32CTX_0 + (5 * 8))
+#define FP32CTX_12	(FP32CTX_0 + (6 * 8))
+#define FP32CTX_14	(FP32CTX_0 + (7 * 8))
+#define FP32CTX_16	(FP32CTX_0 + (8 * 8))
+#define FP32CTX_18	(FP32CTX_0 + (9 * 8))
+#define FP32CTX_20	(FP32CTX_0 + (10 * 8))
+#define FP32CTX_22	(FP32CTX_0 + (11 * 8))
+#define FP32CTX_24	(FP32CTX_0 + (12 * 8))
+#define FP32CTX_26	(FP32CTX_0 + (13 * 8))
+#define FP32CTX_28	(FP32CTX_0 + (14 * 8))
+#define FP32CTX_30	(FP32CTX_0 + (15 * 8))
+#define FP32CTX_SIZE	(FP32CTX_30 + (17 * 8))
+
+#define FP64CTX_0	((SZREG)*4)
+#define FP64CTX_2	(FP64CTX_0 + (1 * 8))
+#define FP64CTX_4	(FP64CTX_0 + (2 * 8))
+#define FP64CTX_6	(FP64CTX_0 + (3 * 8))
+#define FP64CTX_8	(FP64CTX_0 + (4 * 8))
+#define FP64CTX_10	(FP64CTX_0 + (5 * 8))
+#define FP64CTX_12	(FP64CTX_0 + (6 * 8))
+#define FP64CTX_14	(FP64CTX_0 + (7 * 8))
+#define FP64CTX_16	(FP64CTX_0 + (8 * 8))
+#define FP64CTX_18	(FP64CTX_0 + (9 * 8))
+#define FP64CTX_20	(FP64CTX_0 + (10 * 8))
+#define FP64CTX_22	(FP64CTX_0 + (11 * 8))
+#define FP64CTX_24	(FP64CTX_0 + (12 * 8))
+#define FP64CTX_26	(FP64CTX_0 + (13 * 8))
+#define FP64CTX_28	(FP64CTX_0 + (14 * 8))
+#define FP64CTX_30	(FP64CTX_0 + (15 * 8))
+#define FP64CTX_1	(FP64CTX_30 + (1 * 8))
+#define FP64CTX_3	(FP64CTX_30 + (2 * 8))
+#define FP64CTX_5	(FP64CTX_30 + (3 * 8))
+#define FP64CTX_7	(FP64CTX_30 + (4 * 8))
+#define FP64CTX_9	(FP64CTX_30 + (5 * 8))
+#define FP64CTX_11	(FP64CTX_30 + (6 * 8))
+#define FP64CTX_13	(FP64CTX_30 + (7 * 8))
+#define FP64CTX_15	(FP64CTX_30 + (8 * 8))
+#define FP64CTX_17	(FP64CTX_30 + (9 * 8))
+#define FP64CTX_19	(FP64CTX_30 + (10 * 8))
+#define FP64CTX_21	(FP64CTX_30 + (11 * 8))
+#define FP64CTX_23	(FP64CTX_30 + (12 * 8))
+#define FP64CTX_25	(FP64CTX_30 + (13 * 8))
+#define FP64CTX_27	(FP64CTX_30 + (14 * 8))
+#define FP64CTX_29	(FP64CTX_30 + (15 * 8))
+#define FP64CTX_31	(FP64CTX_30 + (16 * 8))
+#define FP64CTX_SIZE	(FP64CTX_31 + (17 * 8))
+
+#define FPCTX_SIZE()	(mips_getsr() & SR_FR ? FP64CTX_SIZE : FP32CTX_SIZE)
+
+#define XPACTX_BADVADDR	((SZREG)*2)
+
+#define LINKCTX_TYPE_MSA        0x004D5341
+#define LINKCTX_TYPE_FP32       0x46503332
+#define LINKCTX_TYPE_FP64       0x46503634
+#define LINKCTX_TYPE_FMSA       0x463D5341
+#define LINKCTX_TYPE_DSP        0x00445350
+#define LINKCTX_TYPE_STKSWP     0x53574150
+#define LINKCTX_TYPE_XPA	0x00585041
+
+#define LINKCTX_ID      ((SZREG)*0)
+#define LINKCTX_NEXT    ((SZREG)*1)
+
+#define LINKCTX_TYPE(X) (((struct linkctx *)(X))->id)
+
+#define SWAPCTX_OLDSP   ((SZREG)*2)
+#define SWAPCTX_SIZE    ((SZREG)*3)
+
+#if !defined(__ASSEMBLER__)
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct linkctx;
+
+#define C_CTX_REGNO(REGNO) ((REGNO) - 1)
+
+struct gpctx
+{
+  union
+  {
+    struct
+    {
+      reg_t at;
+      reg_t v[2];
+# if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI
+      reg_t a[8];
+      reg_t t[4];
+# else
+      reg_t a[4];
+      reg_t t[8];
+# endif
+      reg_t s[8];
+      reg_t t2[2];
+      reg_t k[2];
+      reg_t gp;
+      reg_t sp;
+      reg_t fp;
+      reg_t ra;
+    };
+    reg_t r[31];
+  };
+
+  reg_t epc;
+  reg_t badvaddr;
+  reg_t hi;
+  reg_t lo;
+  /* This field is for future extension */
+  struct linkctx *link;
+  /* Status at the point of the exception.  This may not be restored
+     on return from exception if running under an RTOS */
+  uint32_t status;
+  /* These fields should be considered read-only */
+  uint32_t cause;
+  uint32_t badinstr;
+  uint32_t badpinstr;
+};
+
+struct linkctx
+{
+  reg_t id;
+  struct linkctx *next;
+};
+
+struct swapctx
+{
+  struct linkctx link;
+  reg_t oldsp;
+};
+
+static inline void
+_linkctx_append (struct gpctx *gp, struct linkctx *nu)
+{
+  struct linkctx **ctx = (struct linkctx **)&gp->link;
+  while (*ctx)
+    ctx = &(*ctx)->next;
+  *ctx = nu;
+}
+
+struct dspctx
+{
+  struct linkctx link;
+  reg_t dspc;
+  reg_t hi[3];
+  reg_t lo[3];
+};
+
+struct fpctx
+{
+  struct linkctx link;
+  reg_t fcsr;
+  reg_t reserved;
+};
+
+typedef char _msareg[16] __attribute__ ((aligned(16)));
+
+struct msactx
+{
+  struct linkctx link;
+  reg_t fcsr;
+  reg_t msacsr;
+  union
+    {
+      _msareg w[32];
+      double d[64];
+      float s[128];
+    };
+};
+
+#define MSAMSACTX_D(CTX, N) (CTX)->w[(N)]
+#define MSACTX_DBL(CTX, N) (CTX)->d[(N) << 1]
+#ifdef __MIPSEL__
+#define MSACTX_SGL(CTX, N) (CTX)->s[(N) << 2]
+#else
+#define MSACTX_SGL(CTX, N) (CTX)->s[((N) << 2) | 1]
+#endif
+
+struct fp32ctx
+{
+  struct fpctx fp;
+  union
+    {
+      double d[16];	/* even doubles */
+      float s[32];	/* even singles, padded */
+    };
+};
+
+#define FP32CTX_DBL(CTX, N) (CTX)->d[(N)]
+#ifdef __MIPSEL__
+#define FP32CTX_SGL(CTX, N) (CTX)->s[(N)]
+#else
+#define FP32CTX_SGL(CTX, N) (CTX)->s[(N) ^ 1]
+#endif
+
+struct fp64ctx
+{
+  struct fpctx fp;
+  union
+    {
+      double d[32];	/* even doubles, followed by odd doubles */
+      float s[64];	/* even singles, followed by odd singles, padded */
+    };
+};
+
+#define FP64CTX_DBL(CTX, N) (CTX)->d[((N) >> 1) + (((N) & 1) << 4)]
+#ifdef __MIPSEL__
+#define FP64CTX_SGL(CTX, N) (CTX)->s[((N) & ~1) + (((N) & 1) << 5)]
+#else
+#define FP64CTX_SGL(CTX, N) (CTX)->s[((N) | 1) + (((N) & 1) << 5)]
+#endif
+
+struct xpactx
+{
+  struct linkctx link;
+  reg64_t badvaddr;
+};
+
+#ifdef __mips16
+# define _MIPS_HAL_NOMIPS16 __attribute__((nomips16))
+#else
+# define _MIPS_HAL_NOMIPS16
+#endif
+
+extern reg_t _MIPS_HAL_NOMIPS16
+  _dspctx_save (struct dspctx *ptr);
+extern reg_t _MIPS_HAL_NOMIPS16
+  _dspctx_load (struct dspctx *ptr);
+
+extern reg_t _MIPS_HAL_NOMIPS16
+  _xpa_save (struct xpactx *ptr);
+
+extern reg_t _MIPS_HAL_NOMIPS16
+  _fpctx_save (struct fpctx *ptr);
+extern reg_t _MIPS_HAL_NOMIPS16
+  _fpctx_load (struct fpctx *ptr);
+extern reg_t _MIPS_HAL_NOMIPS16
+  _msactx_save (struct msactx *ptr);
+extern reg_t _MIPS_HAL_NOMIPS16
+  _msactx_load (struct msactx *ptr);
+
+/* Fall back exception handlers:
+   _mips_handle_exception - May be implemented by a user but is aliased
+			    to __exception_handle by default.
+   __exception_handle	  - Toolchain provided fallback handler.
+*/
+extern void _MIPS_HAL_NOMIPS16
+  _mips_handle_exception (struct gpctx *ctx, int exception);
+extern void _MIPS_HAL_NOMIPS16
+  __exception_handle (struct gpctx *ctx, int exception);
+
+/* Obtain the largest available region of RAM */
+extern void _MIPS_HAL_NOMIPS16
+  _get_ram_range (void **ram_base, void **ram_extent);
+
+/* Invoke a UHI operation via SDBBP using the provided context */
+extern int _MIPS_HAL_NOMIPS16
+  __uhi_indirect (struct gpctx *);
+
+/* Report an unhandled exception */
+extern int32_t _MIPS_HAL_NOMIPS16
+  __uhi_exception (struct gpctx *, int32_t);
+
+/* Print a message to a logger.  Minimal formatting support for one
+   integer argument.  */
+extern int32_t _MIPS_HAL_NOMIPS16
+  __plog (int8_t *, int32_t);
+
+/* Boot context support functions */
+extern int _MIPS_HAL_NOMIPS16
+  __get_startup_BEV (void) __attribute__((weak));
+extern int _MIPS_HAL_NOMIPS16
+  __chain_uhi_excpt (struct gpctx *) __attribute__((weak));
+
+/* Emergency exit, use it when unrecoverable errors occur */
+extern int _MIPS_HAL_NOMIPS16
+  __exit (int);
+
+/* UHI assert support.  This function can return.  */
+extern void _MIPS_HAL_NOMIPS16
+  __uhi_assert (const char *, const char *, int32_t);
+
+/* Forward a breakpoint exception to boot.  */
+extern int _MIPS_HAL_NOMIPS16
+  __uhi_break (struct gpctx *) __attribute__((weak));
+
+#ifdef NDEBUG           /* required by ANSI standard */
+# define uhi_assert(__e) ((void)0)
+#else
+# define uhi_assert(__e) ((__e) ? (void)0 : \
+			   __uhi_assert (#__e, __FILE__, __LINE__))
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _HAL_H
diff --git a/libgloss/mips/include/mips/intctrl.h b/libgloss/mips/include/mips/intctrl.h
new file mode 100644
index 000000000..866e16719
--- /dev/null
+++ b/libgloss/mips/include/mips/intctrl.h
@@ -0,0 +1,69 @@ 
+/*
+ * 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.
+ */
+
+#include <mips/hal.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/*
+ * Use the macros themselves for idempotency to ease replacement at the OS
+ * level.
+ */
+#ifndef _mips_intpatch
+/*
+ * Install a handler into the template vector code by patching the address
+ * calculation instructions.  The INDEX is the interrupt number with SW0
+ * being index 0 and HW5 being index 7, this also applies to EIC vectors
+ * where the INDEX represents the vector number.  K1_TO_KSCRATCH1 should be
+ * set if an instruction should be injected to move K1 to KSCRATCH1 before
+ * clobbering it.
+ */
+_MIPS_HAL_NOMIPS16
+void _mips_intpatch (const reg_t index, const uintptr_t handler,
+		     bool k1_to_kscratch1);
+#endif /* _mips_intpatch */
+
+#ifndef _mips_intmask
+/*
+ * Enable or disable an interrupt at INDEX where INDEX has the same meaning
+ * as in _mips_intpatch.  Returns nonzero if the interrupt was already
+ * enabled.
+ */
+_MIPS_HAL_NOMIPS16
+reg_t _mips_intmask (const reg_t index, const reg_t enable);
+#endif /* _mips_intmask */
+
+#ifndef _mips_intack
+/*
+ * Acknowledge (clear) an interrupt at INDEX where INDEX has the same meaning
+ * as in _mips_intpatch.  Returns nonzero if the interrupt needed
+ * acknowledging.
+ */
+_MIPS_HAL_NOMIPS16
+reg_t _mips_intack (const reg_t index);
+#endif /* _mips_intack */
diff --git a/libgloss/mips/include/mips/m32c0.h b/libgloss/mips/include/mips/m32c0.h
new file mode 100644
index 000000000..6ed831987
--- /dev/null
+++ b/libgloss/mips/include/mips/m32c0.h
@@ -0,0 +1,1605 @@ 
+/*
+ * 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 _M32C0_H_
+#define _M32C0_H_
+
+#ifndef _M64C0_H_
+/* MIPS32-specific MMU interface */
+#include <mips/m32tlb.h>
+#endif
+/*
+ * MIPS32 Exception Codes
+ */
+#define EXC_INTR	0	/* interrupt */
+#define EXC_MOD		1	/* tlb modification */
+#define EXC_TLBL	2	/* tlb miss (load/i-fetch) */
+#define EXC_TLBS	3	/* tlb miss (store) */
+#define EXC_ADEL	4	/* address error (load/i-fetch) */
+#define EXC_ADES	5	/* address error (store) */
+#define EXC_IBE		6	/* bus error (i-fetch) */
+#define EXC_DBE		7	/* data bus error (load/store) */
+#define EXC_SYS		8	/* system call */
+#define EXC_BP		9	/* breakpoint */
+#define EXC_RI		10	/* reserved instruction */
+#define EXC_CPU		11	/* coprocessor unusable */
+#define EXC_OVF		12	/* integer overflow */
+#define EXC_TRAP	13	/* trap exception */
+#define EXC_MSAFPE	14	/* MSA floating point exception */
+#define EXC_FPE		15	/* floating point exception */
+#define EXC_IS1		16	/* implementation-specific 1 */
+#define EXC_IS2		17	/* implementation-specific 2 */
+#define EXC_C2E		18	/* coprocessor 2 exception */
+#define EXC_TLBRI	19	/* TLB read inhibit */
+#define EXC_TLBXI	20	/* TLB execute inhibit */
+#define EXC_MSAU	21	/* MSA unusable exception */
+#define EXC_MDMX	22	/* mdmx unusable */
+#define EXC_WATCH	23	/* watchpoint */
+#define EXC_MCHECK	24	/* machine check */
+#define EXC_THREAD	25	/* thread */
+#define EXC_DSPU	26	/* dsp unusable */
+#define EXC_RES27	27
+#define EXC_RES28	28
+#define EXC_RES29	29
+#define EXC_RES30	30
+#define EXC_RES31	31
+
+
+/*
+ * MIPS32 Cause Register (CP0 Register 13, Select 0)
+ */
+#define CR_BD		0x80000000	/* branch delay */
+#define  CR_BD_SHIFT		31
+#define CR_TI		0x40000000	/* timer interrupt (r2) */
+#define  CR_TI_SHIFT		30
+#define CR_CEMASK	0x30000000      /* coprocessor used */
+#define  CR_CESHIFT		28
+#define  CR_CE_SHIFT		28
+#define  CR_CE_BITS		 2
+#define CR_DC		0x08000000	/* disable count (r2) */
+#define  CR_DC_SHIFT		27
+#define CR_PCI		0x04000000	/* performance counter i/u (r2) */
+#define  CR_PCI_SHIFT		26
+#define CR_IV		0x00800000	/* use special i/u vec */
+#define  CR_IV_SHIFT		23
+#define CR_WP		0x00400000	/* deferred watchpoint */
+#define  CR_WP_SHIFT		22
+#define CR_FDCI		0x00200000	/* fast debug channned i/u (r2) */
+#define  CR_FDCI_SHIFT		21
+
+#define CR_IMASK	0x0000ff00 	/* interrupt pending mask */
+#define CR_IP_MASK	0x0000ff00
+#define  CR_IP_SHIFT		 8
+#define  CR_IP_BITS		 8
+#define CR_RIPL		0x0000fc00
+#define  CR_RIPL_SHIFT		10
+#define  CR_RIPL_BITS		 6
+
+/* interrupt pending bits */
+#define CR_HINT5	0x00008000	/* h/w interrupt 5 */
+#define CR_HINT4	0x00004000	/* h/w interrupt 4 */
+#define CR_HINT3	0x00002000	/* h/w interrupt 3 */
+#define CR_HINT2	0x00001000	/* h/w interrupt 2 */
+#define CR_HINT1	0x00000800	/* h/w interrupt 1 */
+#define CR_HINT0	0x00000400	/* h/w interrupt 0 */
+#define CR_SINT1	0x00000200	/* s/w interrupt 1 */
+#define CR_SINT0	0x00000100 	/* s/w interrupt 0 */
+
+/* alternative interrupt pending bit naming */
+#define CR_IP7		0x00008000
+#define CR_IP6		0x00004000
+#define CR_IP5		0x00002000
+#define CR_IP4		0x00001000
+#define CR_IP3		0x00000800
+#define CR_IP2		0x00000400
+#define CR_IP1		0x00000200
+#define CR_IP0		0x00000100
+
+#define CR_XMASK	0x0000007c 	/* exception code mask */
+#define CR_X_MASK	0x0000007c
+#define  CR_X_SHIFT		 2
+#define  CR_X_BITS		 5
+#define CR_XCPT(x)	((x)<<2)
+
+/*
+ * MIPS32 Status Register  (CP0 Register 12, Select 0)
+ */
+#define SR_CU3		0x80000000	/* coprocessor 3 enable */
+#define  SR_CU3_SHIFT		31
+#define SR_CU2		0x40000000	/* coprocessor 2 enable */
+#define  SR_CU2_SHIFT		30
+#define SR_CU1		0x20000000	/* coprocessor 1 enable */
+#define  SR_CU1_SHIFT		29
+#define SR_CU0		0x10000000	/* coprocessor 0 enable */
+
+#define SR_RP		0x08000000	/* reduce power */
+#define  SR_RP_SHIFT		27
+#define SR_FR		0x04000000	/* 64-bit fpu registers */
+#define  SR_FR_SHIFT		26
+#define SR_RE		0x02000000	/* reverse endian (user mode) */
+#define  SR_RE_SHIFT		25
+#define SR_MX		0x01000000	/* enable MDMX/DSP ASE */
+#define  SR_MX_SHIFT		24
+#define SR_PX		0x00800000	/* user 64-bit reg / 32-bit addr */
+#define  SR_PX_SHIFT		23
+#define SR_BEV		0x00400000	/* boot exception vectors */
+#define  SR_BEV_SHIFT		22
+#define SR_TS		0x00200000	/* TLB shutdown */
+#define  SR_TS_SHIFT		21
+#define SR_SR		0x00100000	/* soft reset occurred */
+#define SR_PE		0x00100000	/* soft reset (clear parity error) */
+#define  SR_SR_SHIFT		20
+#define SR_NMI		0x00080000 	/* NMI occurred */
+#define  SR_NMI_SHIFT		19
+#define SR_MCU		0x00040000 	/* MCU ASE implemented */
+#define  SR_MCU_SHIFT		18
+
+#define SR_IPL_MASK	0x0000fc00
+#define  SR_IPL_SHIFT		10
+#define  SR_IPL_BITS		 6
+#define SR_IMASK	0x0000ff00
+
+/* interrupt mask bits */
+#define SR_HINT5	0x00008000	/* enable h/w interrupt 6 */
+#define SR_HINT4	0x00004000	/* enable h/w interrupt 5 */
+#define SR_HINT3	0x00002000	/* enable h/w interrupt 4 */
+#define SR_HINT2	0x00001000	/* enable h/w interrupt 3 */
+#define SR_HINT1	0x00000800	/* enable h/w interrupt 2 */
+#define SR_HINT0	0x00000400	/* enable h/w interrupt 1 */
+#define SR_SINT1	0x00000200	/* enable s/w interrupt 1 */
+#define SR_SINT0	0x00000100	/* enable s/w interrupt 0 */
+
+/* alternative interrupt mask naming */
+#define SR_IM9		0x00040000      /* 1st MUCON ASE interrupt */
+#define SR_IM8		0x00010000	/* 2nd MUCON ASE interrupt */
+#define SR_IM7		0x00008000
+#define SR_IM6		0x00004000
+#define SR_IM5		0x00002000
+#define SR_IM4		0x00001000
+#define SR_IM3		0x00000800
+#define SR_IM2		0x00000400
+#define SR_IM1		0x00000200
+#define SR_IM0		0x00000100
+
+#define SR_KX		0x00000080	/* 64-bit kernel mode */
+#define SR_KX_SHIFT		 7
+#define SR_SX		0x00000040	/* 64-bit supervisor mode */
+#define SR_SX_SHIFT		 6
+#define SR_UX		0x00000020	/* 64-bit user mode */
+#define SR_UX_SHIFT		 5
+
+#define SR_UM		0x00000010	/* user mode */
+#define SR_KSU_MASK	0x00000018	/* ksu mode mask */
+#define SR_KSU_SHIFT		 3
+#define SR_KSU_BITS		 2
+#define SR_KSU_USER	0x00000010	/* user mode */
+#define SR_KSU_SPVS	0x00000008	/* supervisor mode */
+#define SR_KSU_KERN	0x00000000	/* kernel mode */
+
+#define SR_ERL		0x00000004	/* error level */
+#define  SR_ERL_SHIFT		 2
+#define SR_EXL		0x00000002	/* exception level */
+#define  SR_EXL_SHIFT		 1
+#define SR_IE		0x00000001 	/* interrupt enable */
+#define  SR_IE_SHIFT		 0
+
+/*
+ * MIPS32r6 VPControl (CP0 Register 0, Select 4)
+ */
+#define VPCONTROL_DIS	0x00000001
+#define VPCONTROL_SHIFT		 0
+
+/*
+ * MIPS32r2 HWREna Register  (CP0 Register 7, Select 0)
+ */
+#define HWRENA_ULR	0x20000000
+#define HWRENA_XNP	0x00000020
+#define HWRENA_PERFCNT	0x00000010
+#define HWRENA_CCRES	0x00000008
+#define HWRENA_CC	0x00000004
+#define HWRENA_SYNCSTEP	0x00000002
+#define HWRENA_CPUNUM	0x00000001
+
+/*
+ * MIPS32r2 IntCtl Register  (CP0 Register 12, Select 1)
+ */
+#define INTCTL_IPTI	0xe0000000	/* timer i/u pending bit */
+#define  INTCTL_IPTI_SHIFT	29
+#define  INTCTL_IPTI_BITS	 3
+#define INTCTL_IPPCI	0x1c000000	/* perfctr i/u pending bit */
+#define  INTCTL_IPPCI_SHIFT	26
+#define  INTCTL_IPPCI_BITS	 3
+#define INTCTL_IPFDC	0x03800000	/* fast debug chan i/u pending bit */
+#define  INTCTL_IPFDC_SHIFT	23
+#define  INTCTL_IPFDC_BITS	 3
+#define INTCTL_VS	0x000003e0	/* vector spacing */
+#define  INTCTL_VS_SHIFT	 5
+#define  INTCTL_VS_BITS		 5
+#define  INTCTL_VS_0	(0x00 << INTCTL_VS_SHIFT)
+#define  INTCTL_VS_32	(0x01 << INTCTL_VS_SHIFT)
+#define  INTCTL_VS_64	(0x02 << INTCTL_VS_SHIFT)
+#define  INTCTL_VS_128	(0x04 << INTCTL_VS_SHIFT)
+#define  INTCTL_VS_256	(0x08 << INTCTL_VS_SHIFT)
+#define  INTCTL_VS_512	(0x10 << INTCTL_VS_SHIFT)
+
+/*
+ * MIPS32r2 SRSCtl Register  (CP0 Register 12, Select 2)
+ */
+#define SRSCTL_HSS	0x3c000000	/* highest shadow set */
+#define SRSCTL_HSS_SHIFT	26
+#define SRSCTL_EICSS	0x003c0000	/* EIC shadow set */
+#define SRSCTL_EICSS_SHIFT	18
+#define SRSCTL_ESS	0x0000f000	/* exception shadow set */
+#define SRSCTL_ESS_SHIFT	12
+#define SRSCTL_PSS	0x000003c0	/* previous shadow set */
+#define SRSCTL_PSS_SHIFT	 6
+#define SRSCTL_CSS	0x0000000f	/* current shadow set */
+#define SRSCTL_CSS_SHIFT	 0
+
+/*
+ * MIPS32 BEVVA Register (CP0 Register 15, Select 4)
+ */
+#define BEVVA_BASE_MASK	0xfffff000
+#define BEVVA_BASE_SHIFT	12
+#define BEVVA_MASK_MASK	0x00000fff
+#define BEVVA_MASK_SHIFT	 0
+
+/*
+ * MIPS32 Config0 Register  (CP0 Register 16, Select 0)
+ */
+#define CFG0_M		0x80000000	/* Config1 implemented */
+#define  CFG0_M_SHIFT		31
+#define CFG0_K23_MASK	0x70000000	/* Fixed MMU kseg2/3 CCA */
+#define  CFG0_K23_SHIFT		28
+#define CFG0_KU_MASK	0x0e000000	/* Fixed MMU kuseg CCA */
+#define  CFG0_KU_SHIFT		25
+#define CFG0_BE		0x00008000	/* Big Endian */
+#define  CFG0_BE_SHIFT		15
+#define CFG0_AT_MASK	0x00006000	/* Architecture type: */
+#define CFG0_ATMASK	0x00006000
+#define  CFG0_AT_SHIFT		13
+#define  CFG0_AT_BITS		 2
+#define  CFG0_AT_M32	 (0 << CFG0_AT_SHIFT) /* MIPS32 */
+#define  CFG0_AT_M64_A32 (1 << CFG0_AT_SHIFT) /* MIPS64, 32-bit addresses */
+#define  CFG0_AT_M64_A64 (2 << CFG0_AT_SHIFT) /* MIPS64, 64-bit addresses */
+#define  CFG0_AT_RES	 (3 << CFG0_AT_SHIFT)
+#define CFG0_AR_MASK	0x00001c00
+#define CFG0_ARMASK	0x00001c00
+#define  CFG0_AR_SHIFT		10
+#define  CFG0_ARSHIFT		10
+#define  CFG0_AR_BITS		 3
+#define  CFG0_AR_R1	 (0 << CFG0_AR_SHIFT) /* Release 1 */
+#define  CFG0_AR_R2	 (1 << CFG0_AR_SHIFT) /* Release 2,3,5 */
+#define  CFG0_AR_R6	 (2 << CFG0_AR_SHIFT) /* Release 6 */
+#define CFG0_MT_MASK	0x00000380	/* MMU Type: */
+#define CFG0_MTMASK	0x00000380
+#define  CFG0_MT_SHIFT		 7
+#define  CFG0_MT_BITS		 3
+#define  CFG0_MT_NONE	 (0 << CFG0_MT_SHIFT) /* No MMU */
+#define  CFG0_MT_TLB	 (1 << CFG0_MT_SHIFT) /* Standard TLB */
+#define  CFG0_MT_BAT	 (2 << CFG0_MT_SHIFT) /* BAT */
+#define  CFG0_MT_FIXED	 (3 << CFG0_MT_SHIFT) /* Fixed mapping */
+#define  CFG0_MT_NONSTD	 (3 << CFG0_MT_SHIFT) /* Legacy */
+#define  CFG0_MT_DUAL	 (4 << CFG0_MT_SHIFT) /* Dual VTLB and FTLB */
+#define CFG0_VI		0x00000008	/* Icache is virtual */
+#define  CFG0_VI_SHIFT		 3
+#define CFG0_K0_MASK	0x00000007	/* KSEG0 coherency algorithm */
+#define CFG0_K0MASK	0x00000007
+#define  CFG0_K0_SHIFT		 0
+#define  CFG0_K0_BITS		 3
+
+/*
+ * MIPS32 Config1 Register (CP0 Register 16, Select 1)
+ */
+#define CFG1_M		0x80000000	/* Config2 implemented */
+#define CFG1_M_SHIFT		31
+#define CFG1_MMUS_MASK	0x7e000000	/* mmu size - 1 */
+#define CFG1_MMUSMASK	0x7e000000
+#define  CFG1_MMUS_SHIFT	25
+#define  CFG1_MMUSSHIFT		25
+#define  CFG1_MMUS_BITS		 6
+#define CFG1_IS_MASK	0x01c00000	/* icache lines 64<<n */
+#define CFG1_ISMASK	0x01c00000
+#define  CFG1_IS_SHIFT		22	/* Unless n==7, then 32 */
+#define  CFG1_ISSHIFT		22
+#define  CFG1_IS_BITS		 3
+#define CFG1_IL_MASK	0x00380000	/* icache line size 2<<n */
+#define CFG1_ILMASK	0x00380000
+#define  CFG1_IL_SHIFT		19
+#define  CFG1_ILSHIFT		19
+#define  CFG1_IL_BITS		 3
+#define CFG1_IA_MASK	0x00070000	/* icache ways - 1 */
+#define CFG1_IAMASK	0x00070000
+#define  CFG1_IA_SHIFT		16
+#define  CFG1_IASHIFT		16
+#define  CFG1_IA_BITS		 3
+#define CFG1_DS_MASK	0x0000e000	/* dcache lines 64<<n */
+#define CFG1_DSMASK	0x0000e000
+#define  CFG1_DS_SHIFT		13
+#define  CFG1_DSSHIFT		13
+#define  CFG1_DS_BITS		 3
+#define CFG1_DL_MASK	0x00001c00	/* dcache line size 2<<n */
+#define CFG1_DLMASK	0x00001c00
+#define  CFG1_DL_SHIFT		10
+#define  CFG1_DLSHIFT		10
+#define  CFG1_DL_BITS		 3
+#define CFG1_DA_MASK	0x00000380	/* dcache ways - 1 */
+#define CFG1_DAMASK	0x00000380
+#define  CFG1_DA_SHIFT		 7
+#define  CFG1_DASHIFT		 7
+#define  CFG1_DA_BITS		 3
+#define CFG1_C2		0x00000040	/* Coprocessor 2 present */
+#define  CFG1_C2_SHIFT		 6
+#define CFG1_MD		0x00000020	/* MDMX implemented */
+#define  CFG1_MD_SHIFT		 5
+#define CFG1_PC		0x00000010	/* performance counters implemented */
+#define  CFG1_PC_SHIFT		 4
+#define CFG1_WR		0x00000008	/* watch registers implemented */
+#define  CFG1_WR_SHIFT		 3
+#define CFG1_CA		0x00000004	/* compression (mips16) implemented */
+#define  CFG1_CA_SHIFT		 2
+#define CFG1_EP		0x00000002	/* ejtag implemented */
+#define  CFG1_EP_SHIFT		 1
+#define CFG1_FP		0x00000001	/* fpu implemented */
+#define  CFG1_FP_SHIFT		 0
+
+
+/*
+ * MIPS32r2 Config2 Register (CP0 Register 16, Select 2)
+ */
+#define CFG2_M		0x80000000	/* Config3 implemented */
+#define  CFG1_M_SHIFT		31
+#define CFG2_TU_MASK	0x70000000	/* tertiary cache control */
+#define CFG2_TUMASK	0x70000000
+#define  CFG2_TU_SHIFT		28
+#define  CFG2_TUSHIFT		28
+#define  CFG2_TU_BITS		 3
+#define CFG2_TS_MASK	0x0f000000	/* tcache sets per wway 64<<n */
+#define CFG2_TSMASK	0x0f000000
+#define  CFG2_TS_SHIFT		24
+#define  CFG2_TSSHIFT		24
+#define  CFG2_TS_BITS		 4
+#define CFG2_TL_MASK	0x00f00000	/* tcache line size 2<<n */
+#define CFG2_TLMASK	0x00f00000
+#define  CFG2_TL_SHIFT		20
+#define  CFG2_TLSHIFT		20
+#define  CFG2_TL_BITS		 4
+#define CFG2_TA_MASK	0x000f0000	/* tcache ways - 1 */
+#define CFG2_TAMASK	0x000f0000
+#define  CFG2_TA_SHIFT		16
+#define  CFG2_TASHIFT		16
+#define  CFG2_TA_BITS		 4
+#define CFG2_SU_MASK	0x0000f000	/* secondary cache control */
+#define CFG2_SUMASK	0x0000f000
+#define  CFG2_SU_SHIFT		12
+#define  CFG2_SUSHIFT		12
+#define  CFG2_SU_BITS		 4
+#define CFG2_SS_MASK	0x00000f00	/* scache sets per wway 64<<n */
+#define CFG2_SSMASK	0x00000f00
+#define  CFG2_SS_SHIFT		 8
+#define  CFG2_SSSHIFT		 8
+#define  CFG2_SS_BITS		 4
+#define CFG2_SL_MASK	0x000000f0	/* scache line size 2<<n */
+#define CFG2_SLMASK	0x000000f0
+#define  CFG2_SL_SHIFT		 4
+#define  CFG2_SLSHIFT		 4
+#define  CFG2_SL_BITS		 4
+#define CFG2_SA_MASK	0x0000000f	/* scache ways - 1 */
+#define CFG2_SAMASK	0x0000000f
+#define  CFG2_SA_SHIFT		 0
+#define  CFG2_SASHIFT		 0
+#define  CFG2_SA_BITS		 4
+
+/*
+ * MIPS32r2 Config3 Register (CP0 Register 16, Select 3)
+ */
+#define CFG3_M		0x80000000	/* Config4 implemented */
+#define  CFG3_M_SHIFT		31
+#define CFG3_BPG	0x40000000	/* Big pages implemented */
+#define  CFG3_BPG_SHIFT		30
+#define CFG3_CMGCR	0x20000000	/* Coherency manager implemented */
+#define  CFG3_CMGCR_SHIFT	29
+#define CFG3_MSAP	0x10000000	/* MSA implemented */
+#define  CFG3_MSAP_SHIFT	28
+#define CFG3_BP		0x08000000	/* BadInstrP implemented */
+#define  CFG3_BP_SHIFT		27
+#define CFG3_BI		0x04000000	/* BadInstr implemented */
+#define  CFG3_BI_SHIFT		26
+#define CFG3_SC		0x02000000	/* Segment control implemented */
+#define  CFG3_SC_SHIFT		25
+#define CFG3_PW		0x01000000	/* HW page table walk implemented */
+#define  CFG3_PW_SHIFT		24
+#define CFG3_VZ		0x00800000	/* Virtualization module implemented */
+#define  CFG3_VZ_SHIFT		23
+#define CFG3_IPLW_MASK	0x00600000	/* IPL field width */
+#define  CFG3_IPLW_SHIFT	21
+#define  CFG3_IPLW_BITS		 2
+#define  CFG3_IPLW_6BIT	(0 << CFG3_IPLW_SHIFT) /* IPL/RIPL are 6-bits wide */
+#define  CFG3_IPLW_8BIT	(1 << CFG3_IPLW_SHIFT) /* IPL/RIPL are 8-bits wide */
+#define CFG3_MMAR_MASK	0x001c0000	/* MicroMIPS64 architecture revision */
+#define  CFG3_MMAR_SHIFT	18
+#define  CFG3_MMAR_BITS		 3
+#define  CFG3_MMAR_R3	(0 << CFG3_MMAR_SHIFT) /* MicroMIPS64 Release 3 */
+#define CFG3_MCU	0x00020000	/* MCU ASE is implemented */
+#define  CFG3_MCU_SHIFT		17
+#define CFG3_IOE	0x00010000	/* MicroMIPS exception entry points */
+#define  CFG3_IOE_SHIFT		16
+#define CFG3_ISA_MASK	0x0000c000	/* ISA availability */
+#define  CFG3_ISA_SHIFT		14
+#define  CFG3_ISA_BITS		 2
+#define  CFG3_ISA_MIPS	(0 << CFG3_ISA_SHIFT)  /* MIPS only */
+#define  CFG3_ISA_UMIPS (1 << CFG3_ISA_SHIFT)  /* MicroMIPS only */
+#define  CFG3_ISA_BOTH	(2 << CFG3_ISA_SHIFT)  /* MIPS (boot) and MicroMIPS */
+#define  CFG3_ISA_UBOTH	(3 << CFG3_ISA_SHIFT)  /* MIPS and MicroMIPS (boot) */
+#define CFG3_ULRI	0x00002000	/* UserLocal register is available */
+#define  CFG3_ULRI_SHIFT	13
+#define CFG3_RXI	0x00001000	/* RIE and XIE exist in pagegrain */
+#define  CFG3_RXI_SHIFT		12
+#define CFG3_DSP2P	0x00000800	/* DSPR2 ASE present */
+#define  CFG3_DSP2P_SHIFT	11
+#define CFG3_DSPP	0x00000400	/* DSP ASE present */
+#define  CFG3_DSPP_SHIFT	10
+#define CFG3_CTXTC	0x00000200	/* Context Config regs are present */
+#define  CFG3_CTXTC_SHIFT	 9
+#define CFG3_ITL	0x00000100	/* IFlowtrace mechanism implemented */
+#define  CFG3_ITL_SHIFT		 8
+#define CFG3_LPA	0x00000080	/* Large physical addresses */
+#define  CFG3_LPA_SHIFT		 7
+#define CFG3_VEIC	0x00000040	/* Vectored external i/u controller */
+#define  CFG3_VEIC_SHIFT      	 6
+#define CFG3_VI		0x00000020	/* Vectored i/us */
+#define  CFG3_VI_SHIFT		 5
+#define CFG3_SP		0x00000010	/* Small page support */
+#define  CFG3_SP_SHIFT		 4
+#define CFG3_CDMM	0x00000008	/* Common Device Memory Map support */
+#define  CFG3_CDMM_SHIFT	 3
+#define CFG3_MT		0x00000004	/* MT ASE present */
+#define  CFG3_MT_SHIFT		 2
+#define CFG3_SM		0x00000002	/* SmartMIPS ASE */
+#define  CFG3_SM_SHIFT		 1
+#define CFG3_TL		0x00000001	/* Trace Logic */
+#define  CFG3_TL_SHIFT		 0
+
+/*
+ * MIPS32r2 Config4 Register (CP0 Register 16, Select 4)
+ */
+#define CFG4_M		0x80000000	/* Config5 implemented */
+#define  CFG4_M_SHIFT		31
+#define CFG4_IE_MASK	0x60000000	/* TLB invalidate insn support */
+#define  CFG4_IE_SHIFT		29
+#define  CFG4_IE_BITS		 2
+#define  CFG4_IE_NONE	(0 << CFG4_IE_SHIFT) /* TLB invalidate not available */
+#define  CFG4_IE_EHINV	(1 << CFG4_IE_SHIFT) /* TLB invalidate with EHINV */
+#define  CFG4_IE_INV	(2 << CFG4_IE_SHIFT) /* TLB invalidate per entry */
+#define  CFG4_IE_INVALL	(3 << CFG4_IE_SHIFT) /* TLB invalidate entire MMU */
+#define CFG4_AE		0x10000000	/* EntryHI.ASID is 10-bits */
+#define  CFG4_AE_SHIFT		28
+#define CFG4_VTLBSEXT_MASK   0x0f000000	/* VTLB size extension field */
+#define  CFG4_VTLBSEXT_SHIFT	     24
+#define  CFG4_VTLBSEXT_BITS	      4
+#define CFG4_KSCREXIST_MASK  0x00ff0000	/* Indicates presence of KScratch */
+#define  CFG4_KSCREXIST_SHIFT	     16
+#define  CFG4_KSCREXIST_BITS	      8
+#define CFG4_MMUED	     0x0000c000	/* MMU Extension definition */
+#define  CFG4_MMUED_SHIFT	     14
+#define  CFG4_MMUED_BITS	      2
+#define  CFG4_MMUED_SIZEEXT  (1 << CFG4_MMUED_SHIFT) /* MMUSizeExt */
+#define  CFG4_MMUED_FTLB     (2 << CFG4_MMUED_SHIFT) /* FTLB fields */
+#define  CFG4_MMUED_FTLBVEXT (3 << CFG4_MMUED_SHIFT) /* FTLB and Vext */
+#define CFG4_FTLBPS_MASK     0x00001f00	/* FTLB Page Size */
+#define  CFG4_FTLBPS_SHIFT	      8
+#define  CFG4_FTLBPS_BITS	      5
+#define CFG4_FTLBW_MASK	     0x000000f0	/* FTLB Ways mask */
+#define  CFG4_FTLBW_SHIFT	      4
+#define  CFG4_FTLBW_BITS	      4
+#define CFG4_FTLBS_MASK	     0x0000000f	/* FTLB Sets mask */
+#define  CFG4_FTLBS_SHIFT	      0
+#define  CFG4_FTLBS_BITS	      4
+#define CFG4_MMUSE_MASK	     0x000000ff	/* MMU size extension */
+#define  CFG4_MMUSE_SHIFT	      0
+#define  CFG4_MMUSE_BITS	      8
+
+/*
+ * MIPS32r2 Config5 Register (CP0 Register 16, Select 5)
+ */
+#define CFG5_M		0x80000000	/* Undefined extension */
+#define  CFG5_M_SHIFT		31
+#define CFG5_K		0x40000000	/* Disable CCA control */
+#define  CFG5_K_SHIFT		30
+#define CFG5_CV		0x20000000	/* Disable CacheException in KSEG1 */
+#define  CFG5_CV_SHIFT		29
+#define CFG5_EVA	0x10000000	/* EVA is implemented */
+#define  CFG5_EVA_SHIFT		28
+#define CFG5_MSAEN	0x08000000	/* Enable MSA ASE */
+#define  CFG5_MSAEN_SHIFT	27
+#define CFG_XNP		0x00002000
+#define CFG_XNP_SHIFT		13
+#define CFG5_CES	0x00001000	/* Current endian state */
+#define  CFG5_CES_SHIFT		12
+#define CFG5_DEC	0x00000800	/* Dual endian control */
+#define  CFG5_DEC_SHIFT		11
+#define CFG5_L2C	0x00000400	/* Config 2 is memory mapped */
+#define  CFG5_L2C_SHIFT		10
+#define CFG5_UFE	0x00000200	/* Usermode FRE control */
+#define  CFG5_LUFE_SHIFT	 9
+#define CFG5_FRE	0x00000100	/* Emulation support for FR=0 */
+#define  CFG5_FRE_SHIFT		 8
+#define CFG5_VP		0x00000080	/* Multiple virtual processors */
+#define  CFG5_VP_SHIFT		 7
+#define CFG5_SBRI	0x00000040	/* Force RI on SDBBP */
+#define  CFG5_SBRI_SHIFT	 6
+#define CFG5_MVH	0x00000020	/* XPA instruction support */
+#define  CFG5_MVH_SHIFT		 5
+#define CFG5_LLB	0x00000010	/* Load-Linked Bit present */
+#define  CFG5_LLB_SHIFT		 4
+#define CFG5_MRP	0x00000008	/* MAAR and MAARI are present */
+#define  CFG5_MRP_SHIFT		 3
+#define CFG5_UFR	0x00000004	/* Usermode FR control */
+#define  CFG5_UFR_SHIFT		 2
+#define CFG5_NF		0x00000001	/* Nested fault support */
+#define  CFG5_NF_SHIFT		 0
+
+/*
+ * Primary cache mode
+ */
+#define CFG_CBITS		3
+#define CFG_C_UNCACHED		2
+#define CFG_C_WBACK		3
+#define CFG_C_NONCOHERENT	3
+
+#if 0
+/* These cache modes are CPU specific */
+#define CFG_C_WTHRU_NOALLOC	0
+#define CFG_C_WTHRU_ALLOC	1
+#define CFG_C_COHERENTXCL	4
+#define CFG_C_COHERENTXCLW	5
+#define CFG_C_COHERENTUPD	6
+#define CFG_C_UNCACHED_ACCEL	7
+#endif
+
+
+/*
+ * Primary Cache TagLo (CP0 Register 28, Select 0/2)
+ */
+#define TAG_PTAG_MASK           0xffffff00      /* Primary Tag */
+#define TAG_PTAG_SHIFT          8
+#define TAG_PSTATE_MASK         0x000000c0      /* Primary Cache State */
+#define TAG_PSTATE_SHIFT        6
+#define TAG_PSTATE_LOCK		0x00000020
+#define TAG_PARITY_MASK         0x00000001      /* Primary Tag Parity */
+#define TAG_PARITY_SHIFT        0
+
+/* primary cache state (XXX actually implementation specific) */
+#define PSTATE_INVAL		0
+#define PSTATE_SHARED		1
+#define PSTATE_CLEAN_EXCL	2
+#define PSTATE_DIRTY_EXCL	3
+
+
+/*
+ * Cache operations
+ */
+#define Index_Invalidate_I               0x00        /* 0       0 */
+#define Index_Writeback_Inv_D            0x01        /* 0       1 */
+#define Index_Writeback_Inv_T            0x02        /* 0       2 */
+#define Index_Writeback_Inv_S            0x03        /* 0       3 */
+#define Index_Load_Tag_I                 0x04        /* 1       0 */
+#define Index_Load_Tag_D                 0x05        /* 1       1 */
+#define Index_Load_Tag_T                 0x06        /* 1       2 */
+#define Index_Load_Tag_S                 0x07        /* 1       3 */
+#define Index_Store_Tag_I                0x08        /* 2       0 */
+#define Index_Store_Tag_D                0x09        /* 2       1 */
+#define Index_Store_Tag_T                0x0A        /* 2       2 */
+#define Index_Store_Tag_S                0x0B        /* 2       3 */
+#define Hit_Invalidate_I                 0x10        /* 4       0 */
+#define Hit_Invalidate_D                 0x11        /* 4       1 */
+#define Hit_Invalidate_T                 0x12        /* 4       2 */
+#define Hit_Invalidate_S                 0x13        /* 4       3 */
+#define Fill_I                           0x14        /* 5       0 */
+#define Hit_Writeback_Inv_D              0x15        /* 5       1 */
+#define Hit_Writeback_Inv_T              0x16        /* 5       2 */
+#define Hit_Writeback_Inv_S              0x17        /* 5       3 */
+#define Hit_Writeback_D                  0x19        /* 6       1 */
+#define Hit_Writeback_T                  0x1A        /* 6       2 */
+#define Hit_Writeback_S                  0x1B        /* 6       3 */
+#define Fetch_Lock_I                 	 0x1C        /* 7       0 */
+#define Fetch_Lock_D                 	 0x1D        /* 7       1 */
+#define Fetch_Lock_S                     0x1F        /* 7       3 */
+
+/* MIPS32 WatchLo Register (CP0 Register 18) */
+#define WATCHLO_VA		0xfffffff8
+#define WATCHLO_I		0x00000004
+#define WATCHLO_R		0x00000002
+#define WATCHLO_W		0x00000001
+
+/* MIPS32 WatchHi Register (CP0 Register 19) */
+#define WATCHHI_M		0x80000000
+#define  WATCHHI_M_SHIFT		31
+#define WATCHHI_G		0x40000000
+#define  WATCHHI_G_SHIFT		30
+#define WATCHHI_ASID_MASK	0x00ff0000
+#define WATCHHI_ASIDMASK	0x00ff0000
+#define  WATCHHI_ASID_SHIFT		16
+#define  WATCHHI_ASIDSHIFT		16
+#define  WATCHHI_ASID_BITS		 8
+#define WATCHHI_MASK		0x00000ffc
+#define WATCHHI_I		0x00000004
+#define WATCHHI_R		0x00000002
+#define WATCHHI_W		0x00000001
+
+/* MIPS32 PerfCnt Register (CP0 Register 25) */
+#define PERFCNT_M		0x80000000
+#define PERFCNT_EVENT_MASK	0x000007e0
+#define PERFCNT_EVENTMASK	0x000007e0
+#define PERFCNT_EVENT_SHIFT		 5
+#define PERFCNT_EVENTSHIFT		 5
+#define PERFCNT_EVENT_BITS		 6
+#define PERFCNT_IE		0x00000010
+#define PERFCNT_U		0x00000008
+#define PERFCNT_S		0x00000004
+#define PERFCNT_K		0x00000002
+#define PERFCNT_EXL		0x00000001
+
+/* MIPS32r2 PageGrain  Register (CP0 Register 5, Select 1) */
+#define PAGEGRAIN_ELPA	0x20000000	/* Enable large physical addresses */
+#define PAGEGRAIN_ELPA_SHIFT	29
+#define PAGEGRAIN_ELPA_BITS	1
+
+#define PAGEGRAIN_ESP	0x10000000	/* Enable small (1KB) page support */
+
+/* MIPS32r2 EBase  Register (CP0 Register 15, Select 1) */
+#define EBASE_BASE	0xfffff000	/* Exception base */
+#define EBASE_WG	0x00000800	/* Write Gate */
+#define  EBASE_WG_SHIFT		11
+#define EBASE_CPU	0x000003ff	/* CPU number */
+#define  EBASE_CPU_SHIFT	 0
+#define  EBASE_CPU_BITS		10
+
+/* MIPS32r2 EntryHi register (CP0 Register 10, Select 0) */
+#define C0_ENTRYHI64_R_MASK	0xC000000000000000
+#define C0_ENTRYHI64_R_BITS	2
+#define C0_ENTRYHI64_R_SHIFT	61
+#define C0_ENTRYHI64_VPN2_MASK	0xFFFFFFE000
+#define C0_ENTRYHI64_VPN2_BITS	27
+#define C0_ENTRYHI64_VPN2_SHIFT	13
+#define C0_ENTRYHI_VPN2_MASK	0xFFFFE000
+#define C0_ENTRYHI_VPN2_BITS	19
+#define C0_ENTRYHI_VPN2_SHIFT	13
+#define C0_ENTRYHI_VPN2X_MASK	0x3
+#define C0_ENTRYHI_VPN2X_BITS	2
+#define C0_ENTRYHI_VPN2X_SHIFT	11
+#define C0_ENTRYHI_EHINV_MASK	0x400
+#define C0_ENTRYHI_EHINV_BITS	1
+#define C0_ENTRYHI_EHINV_SHIFT	10
+#define C0_ENTRYHI_ASIDX_MASK	0x300
+#define C0_ENTRYHI_ASIDX_BITS	2
+#define C0_ENTRYHI_ASIDX_SHIFT	8
+#define C0_ENTRYHI_ASID_MASK	0xFF
+#define C0_ENTRYHI_ASID_BITS	8
+#define C0_ENTRYHI_ASID_SHIFT	0
+
+/* MIPS32 EntryLo0 register (CP0 Register 2, select 0) */
+#define ENTRYLO064_RI_MASK	0x8000000000000000
+#define ENTRYLO064_RI_BITS	1
+#define ENTRYLO064_RI_SHIFT	63
+#define ENTRYLO064_XI_MASK	0x4000000000000000
+#define ENTRYLO064_XI_BITS	1
+#define ENTRYLO064_XI_SHIFT	62
+#define ENTRYLO064_PFN_MASK	0x3FFFFFFFFFFFFFE0
+#define ENTRYLO064_PFN_BITS	56
+#define ENTRYLO064_PFN_SHIFT	6
+#define ENTRYLO064_RI_SHIFT	63
+#define ENTRYLO064_RI_BITS	1
+#define ENTRYLO064_RI_SHIFT	63
+#define ENTRYLO0_PFNX_MASK	0x7FFFFF
+#define ENTRYLO0_PFNX_BITS	23
+#define ENTRYLO0_PFNX_SHIFT	0
+#define ENTRYLO0_RI_MASK	0x80000000
+#define ENTRYLO0_RI_BITS	1
+#define ENTRYLO0_RI_SHIFT	31
+#define ENTRYLO0_XI_MASK	0x40000000
+#define ENTRYLO0_XI_BITS	1
+#define ENTRYLO0_XI_SHIFT	30
+#define ENTRYLO0_PFN_MASK	0x3FFFFFE0
+#define ENTRYLO0_PFN_BITS	23
+#define ENTRYLO0_PFN_SHIFT	6
+#define ENTRYLO0_C_MASK		0x38
+#define ENTRYLO0_C_BITS		3
+#define ENTRYLO0_C_SHIFT	3
+#define ENTRYLO0_D_MASK		0x4
+#define ENTRYLO0_D_BITS		1
+#define ENTRYLO0_D_SHIFT	2
+#define ENTRYLO0_V_MASK		0x2
+#define ENTRYLO0_V_BITS		1
+#define ENTRYLO0_V_SHIFT	1
+#define ENTRYLO0_G_MASK		0x1
+#define ENTRYLO0_G_BITS		1
+#define ENTRYLO0_G_SHIFT	0
+
+/* MIPS32 EntryLo1 register (CP0 Register 3, select 0) */
+#define ENTRYLO164_RI_MASK	ENTRYLO064_RI_MASK
+#define ENTRYLO164_RI_BITS	ENTRYLO064_RI_BITS
+#define ENTRYLO164_RI_SHIFT	ENTRYLO064_RI_SHIFT
+#define ENTRYLO164_XI_MASK	ENTRYLO064_XI_MASK
+#define ENTRYLO164_XI_BITS	ENTRYLO064_XI_BITS
+#define ENTRYLO164_XI_SHIFT	ENTRYLO064_XI_SHIFT
+#define ENTRYLO164_PFN_MASK	ENTRYLO064_PFN_MASK
+#define ENTRYLO164_PFN_BITS	ENTRYLO064_PFN_BITS
+#define ENTRYLO164_PFN_SHIFT	ENTRYLO064_PFN_SHIFT
+#define ENTRYLO164_RI_SHIFT	ENTRYLO064_RI_SHIFT
+#define ENTRYLO164_RI_BITS	ENTRYLO064_RI_BITS
+#define ENTRYLO164_RI_SHIFT	ENTRYLO064_RI_SHIFT
+#define ENTRYLO1_PFNX_MASK	ENTRYLO0_PFNX_MASK
+#define ENTRYLO1_PFNX_BITS	ENTRYLO0_PFNX_BITS
+#define ENTRYLO1_PFNX_SHIFT	ENTRYLO0_PFNX_SHIFT
+#define ENTRYLO1_RI_MASK	ENTRYLO0_RI_MASK
+#define ENTRYLO1_RI_BITS	ENTRYLO0_RI_BITS
+#define ENTRYLO1_RI_SHIFT	ENTRYLO0_RI_SHIFT
+#define ENTRYLO1_XI_MASK	ENTRYLO0_XI_MASK
+#define ENTRYLO1_XI_BITS	ENTRYLO0_XI_BITS
+#define ENTRYLO1_XI_SHIFT	ENTRYLO0_XI_SHIFT
+#define ENTRYLO1_PFN_MASK	ENTRYLO0_PFN_MASK
+#define ENTRYLO1_PFN_BITS	ENTRYLO0_PFN_BITS
+#define ENTRYLO1_PFN_SHIFT	ENTRYLO0_PFN_SHIFT
+#define ENTRYLO1_C_MASK		ENTRYLO0_C_MASK
+#define ENTRYLO1_C_BITS		ENTRYLO0_C_BITS
+#define ENTRYLO1_C_SHIFT	ENTRYLO0_C_SHIFT
+#define ENTRYLO1_D_MASK		ENTRYLO0_D_MASK
+#define ENTRYLO1_D_BITS		ENTRYLO0_D_BITS
+#define ENTRYLO1_D_SHIFT	ENTRYLO0_D_SHIFT
+#define ENTRYLO1_V_MASK		ENTRYLO0_V_MASK
+#define ENTRYLO1_V_BITS		ENTRYLO0_V_BITS
+#define ENTRYLO1_V_SHIFT	ENTRYLO0_V_SHIFT
+#define ENTRYLO1_G_MASK		ENTRYLO0_G_MASK
+#define ENTRYLO1_G_BITS		ENTRYLO0_G_BITS
+#define ENTRYLO1_G_SHIFT	ENTRYLO0_G_SHIFT
+
+/* MIPS32 TraceControl register (CP0 Register 23, select 1) */
+#define TRACECONTROL_TS_MASK	  0x80000000
+#define  TRACECONTROL_TS_SHIFT		  31
+#define TRACECONTROL_TB_MASK	  0x08000000
+#define  TRACECONTROL_TB_SHIFT		  27
+#define TRACECONTROL_IO_MASK	  0x04000000
+#define  TRACECONTROL_IO_SHIFT		  26
+#define TRACECONTROL_D_MASK	  0x02000000
+#define  TRACECONTROL_D_SHIFT		  25
+#define TRACECONTROL_E_MASK	  0x01000000
+#define  TRACECONTROL_E_SHIFT		  24
+#define TRACECONTROL_K_MASK	  0x00800000
+#define  TRACECONTROL_K_SHIFT		  23
+#define TRACECONTROL_S_MASK	  0x00400000
+#define  TRACECONTROL_S_SHIFT		  22
+#define TRACECONTROL_U_MASK	  0x00200000
+#define  TRACECONTROL_U_SHIFT		  21
+#define TRACECONTROL_ASID_M_MASK  0x001fe000
+#define  TRACECONTROL_ASID_M_SHIFT	  13
+#define  TRACECONTROL_ASID_M_BITS	   8
+#define TRACECONTROL_ASID_MASK	  0x00001fe0
+#define  TRACECONTROL_ASID_SHIFT	   5
+#define  TRACECONTROL_ASID_BITS		   8
+#define TRACECONTROL_G_MASK	  0x00000010
+#define  TRACECONTROL_G_SHIFT		   4
+#define TRACECONTROL_TFCR_MASK	  0x00000008
+#define  TRACECONTROL_TFCR_SHIFT	   3
+#define TRACECONTROL_TLSM_MASK	  0x00000004
+#define  TRACECONTROL_TLSM_SHIFT	   2
+#define TRACECONTROL_TIM_MASK	  0x00000002
+#define  TRACECONTROL_TIM_SHIFT		   1
+#define TRACECONTROL_ON_MASK	  0x00000001
+#define  TRACECONTROL_ON_SHIFT		   0
+
+/* MIPS32 TraceControl2 register (CP0 Register 23, select 2) */
+#define TRACECONTROL2_SYPEXT_MASK   0xc0000000
+#define  TRACECONTROL2_SYPEXT_SHIFT	    30
+#define  TRACECONTROL2_SYPEXT_BITS	     2
+#define TRACECONTROL2_CPUIDV_MASK   0x20000000
+#define  TRACECONTROL2_CPUIDV_SHIFT	    29
+#define TRACECONTROL2_CPUID_MASK    0x1fe00000
+#define  TRACECONTROL2_CPUID_SHIFT	    21
+#define  TRACECONTROL2_CPUID_BITS	     8
+#define TRACECONTROL2_TCV_MASK	    0x00100000
+#define  TRACECONTROL2_TCV_SHIFT	    20
+#define TRACECONTROL2_TCNUM_MASK    0x000ff000
+#define  TRACECONTROL2_TCNUM_SHIFT	    12
+#define  TRACECONTROL2_TCNUM_BITS	     8
+#define TRACECONTROL2_MODE_MASK	    0x00000f80
+#define  TRACECONTROL2_MODE_SHIFT	     7
+#define  TRACECONTROL2_MODE_BITS	     5
+#define TRACECONTROL2_VMODE_MASK    0x00000060
+#define  TRACECONTROL2_VMODE_SHIFT	     5
+#define  TRACECONTROL2_VMODE_BITS	     2
+#define  TRACECONTROL2_VMODE_PC	    (0x0 << TRACECONTROL2_VMODE_SHIFT)
+#define  TRACECONTROL2_VMODE_PCLSA  (0x1 << TRACECONTROL2_VMODE_SHIFT)
+#define  TRACECONTROL2_VMODE_PCLSAD (0x2 << TRACECONTROL2_VMODE_SHIFT)
+#define TRACECONTROL2_TBI_MASK	    0x00000010
+#define  TRACECONTROL2_TBI_SHIFT	     4
+#define TRACECONTROL2_TBU_MASK	    0x00000008
+#define  TRACECONTROL2_TBU_SHIFT	     3
+#define TRACECONTROL2_SYP_MASK	    0x00000007
+#define  TRACECONTROL2_SYP_SHIFT	     0
+#define  TRACECONTROL2_SYP_BITS		     3
+
+/* MIPS32 TraceControl3 register (CP0 Register 24, select 2) */
+#define TRACECONTROL3_TNUD_MASK	    0x20000000
+#define  TRACECONTROL3_TNUD_SHIFT	    29
+#define TRACECONTROL3_MSA_EN_MASK   0x10000000
+#define  TRACECONTROL3_MSA_EN_SHIFT	    28
+#define TRACECONTROL3_MSA_MASK	    0x08000000
+#define  TRACECONTROL3_MSA_SHIFT	    27
+#define TRACECONTROL3_EASID_M_MASK  0x06000000
+#define  TRACECONTROL3_EASID_M_SHIFT	    25
+#define  TRACECONTROL3_EASID_M_BITS	     2
+#define TRACECONTROL3_EASID_MASK    0x01800000
+#define  TRACECONTROL3_EASID_SHIFT	    23
+#define  TRACECONTROL3_EASID_BITS	     2
+#define TRACECONTROL3_GV_MASK	    0x00400000
+#define  TRACECONTROL3_GV_SHIFT		    22
+#define TRACECONTROL3_GUESTID_MASK  0x003fc000
+#define  TRACECONTROL3_GUESTID_SHIFT	    14
+#define  TRACECONTROL3_GUESTID_BITS	     8
+#define TRACECONTROL3_PECOVF_MASK   0x00000200
+#define  TRACECONTROL3_PECOVF_SHIFT	    13
+#define TRACECONTROL3_PECFCR_MASK   0x00000100
+#define  TRACECONTROL3_PECFCR_SHIFT	    12
+#define TRACECONTROL3_PECBP_MASK    0x00000080
+#define  TRACECONTROL3_PECBP_SHIFT	    11
+#define TRACECONTROL3_PECSYNC_MASK  0x00000040
+#define  TRACECONTROL3_PECSYNC_SHIFT	    10
+#define TRACECONTROL3_PECE_MASK	    0x00000020
+#define  TRACECONTROL3_PECE_SHIFT	     9
+#define TRACECONTROL3_PEC_MASK	    0x00000010
+#define  TRACECONTROL3_PEC_SHIFT	     8
+#define TRACECONTROL3_TRIDLE_MASK   0x00000004
+#define  TRACECONTROL3_TRIDLE_SHIFT	     2
+#define TRACECONTROL3_TRPAD_MASK    0x00000002
+#define  TRACECONTROL3_TRPAD_SHIFT	     1
+#define TRACECONTROL3_FDT_MASK	    0x00000001
+#define  TRACECONTROL3_FDT_SHIFT	     0
+
+#ifdef __ASSEMBLER__
+
+/*
+ * MIPS32 Coprocessor 0 register numbers
+ */
+#define C0_INDEX	$0
+#define C0_INX		$0
+#define C0_RANDOM	$1
+#define C0_RAND		$1
+#define C0_ENTRYLO0	$2
+#define C0_TLBLO0	$2
+#define C0_ENTRYLO1	$3
+#define C0_TLBLO1	$3
+#define C0_GLOBAL	$3,1
+#define C0_CONTEXT	$4
+#define C0_CTXT		$4
+#define C0_CONTEXTCONF	$4,1
+#define C0_USERLOCAL	$4,2
+#define C0_XCONTEXTCONF	$4,3
+#define C0_DEBUGCTXTID	$4,4
+#define C0_PAGEMASK	$5
+#define C0_PAGEGRAIN	$5,1
+#define C0_SEGCTL0	$5,2
+#define C0_SEGCTL1	$5,3
+#define C0_SEGCTL2	$5,4
+#define C0_PWBASE	$5,5
+#define C0_PWFIELD	$5,6
+#define C0_PWSIZE	$5,7
+#define C0_WIRED	$6
+#define C0_PWCTL	$6,6
+#define C0_HWRENA	$7
+#define C0_BADVADDR 	$8
+#define C0_VADDR 	$8
+#define C0_BADINSTR 	$8,1
+#define C0_BADPINSTR 	$8,2
+#define C0_COUNT 	$9
+#define C0_ENTRYHI	$10
+#define C0_TLBHI	$10
+#define C0_COMPARE	$11
+#define C0_STATUS	$12
+#define C0_SR		$12
+#define C0_INTCTL	$12,1
+#define C0_SRSCTL	$12,2
+#define C0_SRSMAP	$12,3
+#define C0_CAUSE	$13
+#define C0_CR		$13
+#define C0_NESTEDEXC	$13,5
+#define C0_EPC 		$14
+#define C0_NEPC		$14,2
+#define C0_PRID		$15
+#define C0_EBASE	$15,1
+#define C0_CDMMBASE	$15,2
+#define C0_CMGCRBASE	$15,3
+#define C0_BEVVA	$15,4
+#define C0_CONFIG	$16
+#define C0_CONFIG0	$16,0
+#define C0_CONFIG1	$16,1
+#define C0_CONFIG2	$16,2
+#define C0_CONFIG3	$16,3
+#define C0_CONFIG4	$16,4
+#define C0_CONFIG5	$16,5
+#define C0_LLADDR	$17
+#define C0_MAAR		$17,1
+#define C0_MAARI	$17,2
+#define C0_WATCHLO	$18
+#define C0_WATCHHI	$19
+#define C0_XCONTEXT	$20
+#define C0_DEBUG	$23
+#define C0_TRACECONTROL	  $23,1
+#define C0_TRACECONTROL2  $23,2
+#define C0_USERTRACEDATA1 $23,3
+#define C0_TRACEIBPC      $23,4
+#define C0_TRACEDBPC      $23,5
+#define C0_DEBUG2	  $23,6
+#define C0_DEPC		  $24
+#define C0_TRACECONTROL3  $24,2
+#define C0_USERTRACEDATA2 $24,3
+#define C0_PERFCNT	$25
+#define C0_ERRCTL	$26
+#define C0_CACHEERR	$27
+#define C0_TAGLO	$28
+#define C0_ITAGLO	$28
+#define C0_DTAGLO	$28,2
+#define C0_TAGLO2	$28,4
+#define C0_DATALO	$28,1
+#define C0_IDATALO	$28,1
+#define C0_DDATALO	$28,3
+#define C0_DATALO2	$28,5
+#define C0_TAGHI	$29
+#define C0_ITAGHI	$29
+#define C0_DTAGHI	$29,2
+#define C0_DATAHI	$29,1
+#define C0_IDATAHI	$29,1
+#define C0_DDATAHI	$29,3
+#define C0_ERRPC	$30
+#define C0_DESAVE	$31
+#define C0_KSCRATCH1	$31,2
+#define C0_KSCRATCH2	$31,3
+#define C0_KSCRATCH3	$31,4
+#define C0_KSCRATCH4	$31,5
+#define C0_KSCRATCH5	$31,6
+#define C0_KSCRATCH6	$31,7
+
+$index		=	$0
+$random		=	$1
+$entrylo0	=	$2
+$entrylo1	=	$3
+$context	=	$4
+$pagemask	=	$5
+$wired		=	$6
+$hwrena		=	$7
+$vaddr 		=	$8
+$badvaddr	=	$8
+$count 		=	$9
+$entryhi	=	$10
+$compare	=	$11
+$sr		=	$12
+$cr		=	$13
+$epc 		=	$14
+$prid		=	$15
+$config		=	$16
+$lladdr		=	$17
+$watchlo	=	$18
+$watchhi	=	$19
+$debug		= 	$23
+$depc		= 	$24
+$perfcnt	= 	$25
+$errctl		=	$26
+$cacheerr	=	$27
+$taglo		=	$28
+$taghi		=	$29
+$errpc		=	$30
+$desave		=	$31
+
+
+#else /* !__ASSEMBLER__ */
+
+/*
+ * Standard types
+ */
+typedef unsigned int		reg32_t;	/* a 32-bit register */
+typedef unsigned long long	reg64_t;	/* a 64-bit register */
+#if _MIPS_SIM==_ABIO32
+typedef unsigned int		reg_t;
+typedef signed int		sreg_t;
+#else
+typedef unsigned long long	reg_t;
+typedef signed long long	sreg_t;
+#endif
+
+/*
+ * MIPS32 Coprocessor 0 register encodings for C use.
+ * These encodings are implementation specific.
+ */
+#define C0_INDEX	0
+#define C0_INX		0
+#define C0_RANDOM	1
+#define C0_RAND		1
+#define C0_ENTRYLO0	2
+#define C0_TLBLO0	2
+#define C0_ENTRYLO1	3
+#define C0_TLBLO1	3
+#define C0_GLOBAL	0x103
+#define C0_CONTEXT	4
+#define C0_CTXT		4
+#define C0_CONTEXTCONF	0x104
+#define C0_USERLOCAL	0x204
+#define C0_XCONTEXTCONF	0x304
+#define C0_DEBUGCTXTID	0x404
+#define C0_PAGEMASK	5
+#define C0_PAGEGRAIN	0x105
+#define C0_SEGCTL0	0x205
+#define C0_SEGCTL1	0x305
+#define C0_SEGCTL2	0x405
+#define C0_PWBASE	0x505
+#define C0_PWFIELD	0x605
+#define C0_PWSIZE	0x705
+#define C0_WIRED	6
+#define C0_PWCTL	0x606
+#define C0_HWRENA	7
+#define C0_BADVADDR 	8
+#define C0_VADDR 	8
+#define C0_BADINSTR 	0x108
+#define C0_BADINSTRP 	0x208
+#define C0_COUNT 	9
+#define C0_ENTRYHI	10
+#define C0_TLBHI	10
+#define C0_COMPARE	11
+#define C0_STATUS	12
+#define C0_SR		12
+#define C0_INTCTL	0x10C
+#define C0_SRSCTL	0x20C
+#define C0_SRSMAP	0x30C
+#define C0_CAUSE	13
+#define C0_CR		13
+#define C0_NESTEDEXC	0x50D
+#define C0_EPC 		14
+#define C0_NEPC		0x20E
+#define C0_PRID		15
+#define C0_EBASE	0x10F
+#define C0_CDMMBASE	0x20F
+#define C0_CMGCRBASE	0x30F
+#define C0_BEVVA	0x40F
+#define C0_CONFIG	16
+#define C0_CONFIG0	16
+#define C0_CONFIG1	0x110
+#define C0_CONFIG2	0x210
+#define C0_CONFIG3	0x310
+#define C0_CONFIG4	0x410
+#define C0_CONFIG5	0x510
+#define C0_LLADDR	17
+#define C0_MAAR		0x111
+#define C0_MAARI	0x111
+#define C0_WATCHLO	18
+#define C0_WATCHHI	19
+#define C0_XCONTEXT	20
+#define C0_DEBUG	23
+#define C0_TRACECONTROL	  0x117
+#define C0_TRACECONTROL2  0x217
+#define C0_USERTRACEDATA1 0x317
+#define C0_TRACEIBPC      0x417
+#define C0_TRACEDBPC      0x517
+#define C0_DEBUG2	  0x617
+#define C0_DEPC		  24
+#define C0_TRACECONTROL3  0x218
+#define C0_USERTRACEDATA2 0x318
+#define C0_PERFCNT	25
+#define C0_ERRCTL	26
+#define C0_CACHEERR	27
+#define C0_TAGLO	28
+#define C0_ITAGLO	28
+#define C0_DTAGLO	0x21C
+#define C0_TAGLO2	0x41C
+#define C0_DATALO	0x11C
+#define C0_IDATALO	0x11C
+#define C0_DDATALO	0x31C
+#define C0_DATALO2	0x51C
+#define C0_TAGHI	29
+#define C0_ITAGHI	29
+#define C0_DTAGHI	0x21D
+#define C0_DATAHI	0x11D
+#define C0_IDATAHI	0x11D
+#define C0_DDATAHI	0x31D
+#define C0_ERRPC	30
+#define C0_DESAVE	31
+#define C0_KSCRATCH1	0x21F
+#define C0_KSCRATCH2	0x31F
+#define C0_KSCRATCH3	0x41F
+#define C0_KSCRATCH4	0x51F
+#define C0_KSCRATCH5	0x61F
+#define C0_KSCRATCH6	0x71F
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _mips_sync() __asm__ __volatile__ ("sync" : : : "memory")
+
+/* wait for unmasked interrupt */
+#define _mips_wait() \
+  __asm__ __volatile ("wait")
+
+/*
+ * Define macros for accessing the MIPS32 coprocessor 0 registers. Most apart
+ * from "set" return the original register value. These macros take an encoded
+ * (register, select) combination, so they can use the textual names above.
+ */
+
+#define MIPS_C0_REGNAME(regno, sel) ((sel << 8) + regno)
+
+#define mips32_get_c0(selreg) \
+__extension__ ({ \
+  register unsigned long __r; \
+  __asm__ __volatile ("mfc0 %0,$%1,%2" \
+		      : "=d" (__r) \
+		      : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \
+  __r; \
+})
+
+#undef EHB
+#if defined (__MIPS_NO_IMPLICIT_EHB)
+#define EHB	""
+#else
+#define EHB	"ehb\n"
+#endif
+
+#define mips32_set_c0(selreg, val) \
+do { \
+    __asm__ __volatile (".set push \n"\
+			".set noreorder\n"\
+			"mtc0 %z0,$%1,%2\n"\
+			EHB \
+			".set pop" \
+			: \
+			: "dJ" ((reg32_t)(val)), "JK" (selreg & 0x1F),\
+			  "JK" (selreg >> 8) \
+			: "memory"); \
+} while (0)
+
+#define mips32_xch_c0(selreg, val) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = mips32_get_c0 (selreg); \
+    mips32_set_c0 (selreg, val); \
+    __o; \
+})
+
+#define mips32_bc_c0(selreg, clr) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = mips32_get_c0 (selreg); \
+    mips32_set_c0 (selreg, __o & ~(clr)); \
+    __o; \
+})
+
+#define mips32_bs_c0(selreg, set) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = mips32_get_c0 (selreg); \
+    mips32_set_c0 (selreg, __o | (set)); \
+    __o; \
+})
+
+#define mips32_bcs_c0(selreg, clr, set) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = mips32_get_c0 (selreg); \
+    mips32_set_c0 (selreg, (__o & ~(clr)) | (set)); \
+    __o; \
+})
+
+/* MIPS instructions */
+#define mips_sync()		\
+  ({__asm__ volatile ("\t sync \n");})
+
+#define mips_synci(ADDR)		\
+  ({__asm__ volatile ("\t synci 0(%0) \n" :: "r" (ADDR));})
+
+#define mips_synci_step()			\
+({						\
+    int _step;					\
+    __asm__ volatile (				\
+      "\t rdhwr %0,$1 \n" : "=r" (_step));	\
+    _step;					\
+})
+
+#define mips_ehb()		\
+  ({__asm__ volatile ("\t ehb \n");})
+
+#define mips_tlbwi()	\
+  ({__asm__ volatile ("\t tlbwi \n");})
+
+#define mips_tlbwr()	\
+  ({__asm__ volatile ("\t tlbwr \n");})
+
+#define mips_tlbp()	\
+  ({__asm__ volatile ("\t tlbp \n");})
+
+#define mips_tlbr()	\
+  ({__asm__ volatile ("\t tlbr \n");})
+
+#define mips_eva_tlbinvf()	\
+({__asm__ volatile (		\
+    "\t .set  push \n"		\
+    "\t .set  eva \n"		\
+    "\t tlbinvf \n"		\
+    "\t .set  pop \n"		\
+    );				\
+})
+
+/* Set upper half of EntryHI */
+#define mips32_sethientryhi(VAL)	\
+({__asm__ volatile (		\
+    "\t .set  push \n"		\
+    "\t .set  xpa \n"		\
+    "\t mthc0 %0,$10,0 \n"	\
+    "\t .set  pop \n"		\
+    : :"r" (VAL)		\
+    );				\
+})
+
+#define mips_cache(OP,ADDR)	\
+  ({__asm__ volatile ("\t cache %0,0(%1) \n" :: "JK" (OP), "r" (ADDR));})
+
+/* generic equivalents for mips/cpu.h */
+#define _mips_mfc0(r)		mips32_get_c0(r)
+#define _mips_mtc0(r,v)		mips32_set_c0(r,v)
+
+/* MIPS32 Entry*, Index, PageMask registers */
+#define mips32_getentryhi()	mips32_get_c0(C0_ENTRYHI)
+#define mips32_setentryhi(v)	mips32_set_c0(C0_ENTRYHI,v)
+#define mips32_getentrylo0()	mips32_get_c0(C0_ENTRYLO0)
+#define mips32_setentrylo0(v)	mips32_set_c0(C0_ENTRYLO0,v)
+#define mips32_getentrylo1()	mips32_get_c0(C0_ENTRYLO1)
+#define mips32_setentrylo1(v)	mips32_set_c0(C0_ENTRYLO1,v)
+#define mips32_getpagemask()	mips32_get_c0(C0_PAGEMASK)
+#define mips32_setpagemask(v)	mips32_set_c0(C0_PAGEMASK,v)
+#define mips32_getindex()	mips32_get_c0(C0_INDEX)
+#define mips32_setindex(v)	mips32_set_c0(C0_INDEX,v)
+
+/* MIPS32 Config0 register */
+#define mips32_getconfig0()	mips32_get_c0(C0_CONFIG0)
+#define mips32_setconfig0(v)	mips32_set_c0(C0_CONFIG0,v)
+#define mips32_xchconfig0(v)	mips32_xch_c0(C0_CONFIG0,v)
+#define mips32_bicconfig0(clr)	mips32_bc_c0(C0_CONFIG0,clr)
+#define mips32_bisconfig0(set)	mips32_bs_c0(C0_CONFIG0,set)
+#define mips32_bcsconfig0(c,s)	mips32_bcs_c0(C0_CONFIG0,c,s)
+
+/* MIPS32 Config1, 2, 3, 4, 5 register */
+#define mips32_getconfig1()	mips32_get_c0(C0_CONFIG1)
+#define mips32_setconfig1(v)	mips32_set_c0(C0_CONFIG1,v)
+#define mips32_xchconfig1(v)	mips32_xch_c0(C0_CONFIG1,v)
+#define mips32_bicconfig1(clr)	mips32_bc_c0(C0_CONFIG1,clr)
+#define mips32_bisconfig1(set)	mips32_bs_c0(C0_CONFIG1,set)
+#define mips32_bcsconfig1(c,s)	mips32_bcs_c0(C0_CONFIG1,c,s)
+
+#define mips32_getconfig2()	mips32_get_c0(C0_CONFIG2)
+#define mips32_setconfig2(v)	mips32_set_c0(C0_CONFIG2,v)
+#define mips32_xchconfig2(v)	mips32_xch_c0(C0_CONFIG2,v)
+#define mips32_bicconfig2(clr)	mips32_bc_c0(C0_CONFIG2,clr)
+#define mips32_bisconfig2(set)	mips32_bs_c0(C0_CONFIG2,set)
+#define mips32_bcsconfig2(c,s)	mips32_bcs_c0(C0_CONFIG2,c,s)
+
+#define mips32_getconfig3()	mips32_get_c0(C0_CONFIG3)
+#define mips32_setconfig3(v)	mips32_set_c0(C0_CONFIG3,v)
+#define mips32_xchconfig3(v)	mips32_xch_c0(C0_CONFIG3,v)
+#define mips32_bicconfig3(clr)	mips32_bc_c0(C0_CONFIG3,clr)
+#define mips32_bisconfig3(set)	mips32_bs_c0(C0_CONFIG3,set)
+#define mips32_bcsconfig3(c,s)	mips32_bcs_c0(C0_CONFIG3,c,s)
+
+#define mips32_getconfig4()	mips32_get_c0(C0_CONFIG4)
+#define mips32_setconfig4(v)	mips32_set_c0(C0_CONFIG4,v)
+#define mips32_xchconfig4(v)	mips32_xch_c0(C0_CONFIG4,v)
+#define mips32_bicconfig4(clr)	mips32_bc_c0(C0_CONFIG4,clr)
+#define mips32_bisconfig4(set)	mips32_bs_c0(C0_CONFIG4,set)
+#define mips32_bcsconfig4(c,s)	mips32_bcs_c0(C0_CONFIG4,c,s)
+
+#define mips32_getconfig5()	mips32_get_c0(C0_CONFIG5)
+#define mips32_setconfig5(v)	mips32_set_c0(C0_CONFIG5,v)
+#define mips32_xchconfig5(v)	mips32_xch_c0(C0_CONFIG5,v)
+#define mips32_bicconfig5(clr)	mips32_bc_c0(C0_CONFIG5,clr)
+#define mips32_bisconfig5(set)	mips32_bs_c0(C0_CONFIG5,set)
+#define mips32_bcsconfig5(c,s)	mips32_bcs_c0(C0_CONFIG5,c,s)
+
+/* MIPS32 Debug register */
+#define mips32_getdebug()	mips32_get_c0(C0_DEBUG)
+#define mips32_setdebug(v)	mips32_set_c0(C0_DEBUG,v)
+#define mips32_xchdebug(v)	mips32_xch_c0(C0_DEBUG,v)
+#define mips32_bicdebug(clr)	mips32_bc_c0(C0_DEBUG,clr)
+#define mips32_bisdebug(set)	mips32_bs_c0(C0_DEBUG,set)
+#define mips32_bcsdebug(c,s)	mips32_bcs_c0(C0_DEBUG,c,s)
+
+/* MIPS32 ErrCtl register */
+#define mips32_geterrctl()	mips32_get_c0(C0_ERRCTL)
+#define mips32_seterrctl(x)	mips32_set_c0(C0_ERRCTL,x)
+#define mips32_xcherrctl(x)	mips32_xch_c0(C0_ERRCTL,x)
+#define mips32_bicerrctl(clr)	mips32_bc_c0(C0_ERRCTL,clr)
+#define mips32_biserrctl(set)	mips32_bs_c0(C0_ERRCTL,set)
+#define mips32_bcserrctl(c,s)	mips32_bcs_c0(C0_ERRCTL,c,s)
+
+/* MIPS32 TagLo register */
+#define mips32_getitaglo()	mips32_get_c0(C0_TAGLO)		/* alias define */
+#define mips32_setitaglo(x)	mips32_set_c0(C0_TAGLO,x)	/* alias define */
+#define mips32_xchitaglo(x)	mips32_xch_c0(C0_TAGLO,x)	/* alias define */
+#define mips32_getdtaglo()	mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 2))
+#define mips32_setdtaglo(x)	mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 2),x)
+#define mips32_xchdtaglo(x)	mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 2),x)
+#define mips32_gettaglo2()	mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 4))
+#define mips32_settaglo2(x)	mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 4),x)
+#define mips32_xchtaglo2(x)	mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 4),x)
+
+/* MIPS32 DataLo register */
+#define mips32_getdatalo()	mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 1))
+#define mips32_setdatalo(x)	mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 1),x)
+#define mips32_xchdatalo(x)	mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 1),x)
+#define mips32_getidatalo()	mips32_getdatalo()	/* alias define */
+#define mips32_setidatalo(x)	mips32_setdatalo(x)	/* alias define */
+#define mips32_xchidatalo(x)	mips32_xchdatalo(x)	/* alias define */
+#define mips32_getddatalo()	mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 3))
+#define mips32_setddatalo(x)	mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 3),x)
+#define mips32_xchddatalo(x)	mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 3),x)
+#define mips32_getdatalo2()	mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 5))
+#define mips32_setdatalo2(x)	mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 5),x)
+#define mips32_xchdatalo2(x)	mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 5),x)
+
+/* MIPS32r2 IntCtl register */
+#define mips32_getintctl()	mips32_get_c0(C0_INTCTL)
+#define mips32_setintctl(x)	mips32_set_c0(C0_INTCTL,x)
+#define mips32_xchintctl(x)	mips32_xch_c0(C0_INTCTL,x)
+
+/* MIPS32r2 SRSCtl register */
+#define mips32_getsrsctl()	mips32_get_c0(C0_SRSCTL)
+#define mips32_setsrsctl(x)	mips32_set_c0(C0_SRSCTL,x)
+#define mips32_xchsrsctl(x)	mips32_xch_c0(C0_SRSCTL,x)
+
+/* MIPS32r2 SRSMap register */
+#define mips32_getsrsmapl()	mips32_get_c0(C0_SRSMAP)
+#define mips32_setsrsmap(x)	mips32_set_c0(C0_SRSMAP,x)
+#define mips32_xchsrsmap(x)	mips32_xch_c0(C0_SRSMAP,x)
+
+/* MIPS32r2/SmartMIPS PageGrain register */
+#define mips32_getpagegrain()	mips32_get_c0(C0_PAGEGRAIN)
+#define mips32_setpagegrain(x)	mips32_set_c0(C0_PAGEGRAIN,x)
+#define mips32_xchpagegrain(x)	mips32_xch_c0(C0_PAGEGRAIN,x)
+
+/* MIPS32r2 HWREna register */
+#define mips32_gethwrena()	mips32_get_c0(C0_HWRENA)
+#define mips32_sethwrena(v)	mips32_set_c0(C0_HWRENA,v)
+#define mips32_xchhwrena(v)	mips32_xch_c0(C0_HWRENA,v)
+#define mips32_bichwrena(clr)	mips32_bc_c0(C0_HWRENA,clr)
+#define mips32_bishwrena(set)	mips32_bs_c0(C0_HWRENA,set)
+#define mips32_bcshwrena(c,s)	mips32_bcs_c0(C0_HWRENA,c,s)
+
+/* MIPS32r2 EBase register */
+#define mips32_getebase()	mips32_get_c0(C0_EBASE)
+#define mips32_setebase(x)	mips32_set_c0(C0_EBASE,x)
+#define mips32_xchebase(x)	mips32_xch_c0(C0_EBASE,x)
+
+/* CP0 Status register (NOTE: not atomic operations) */
+#define mips32_getsr()		mips32_get_c0(C0_SR)
+#define mips32_setsr(v)		mips32_set_c0(C0_SR,v)
+#define mips32_xchsr(v)		mips32_xch_c0(C0_SR,v)
+#define mips32_bicsr(clr)	mips32_bc_c0(C0_SR,clr)
+#define mips32_bissr(set)	mips32_bs_c0(C0_SR,set)
+#define mips32_bcssr(c,s)	mips32_bcs_c0(C0_SR,c,s)
+
+/* CP0 Cause register (NOTE: not atomic operations) */
+#define mips32_getcr()		mips32_get_c0(C0_CR)
+#define mips32_setcr(v)		mips32_set_c0(C0_CR,v)
+#define mips32_xchcr(v)		mips32_xch_c0(C0_CR,v)
+#define mips32_biccr(clr)	mips32_bc_c0(C0_CR,clr)
+#define mips32_biscr(set)	mips32_bs_c0(C0_CR,set)
+#define mips32_bcscr(c,s)	mips32_bcs_c0(C0_CR,c,s)
+
+/* CP0 PrID register */
+#define mips32_getprid()	mips32_get_c0(C0_PRID)
+
+#ifdef C0_COUNT
+/* CP0 Count register */
+#define mips32_getcount()	mips32_get_c0(C0_COUNT)
+#define mips32_setcount(v)	mips32_set_c0(C0_COUNT,v)
+#define mips32_xchcount(v)	mips32_xch_c0(C0_COUNT,v)
+#endif
+
+#ifdef C0_COMPARE
+/* CP0 Compare register*/
+#define mips32_getcompare()	mips32_get_c0(C0_COMPARE)
+#define mips32_setcompare(v)	mips32_set_c0(C0_COMPARE,v)
+#define mips32_xchcompare(v)	mips32_xch_c0(C0_COMPARE,v)
+#endif
+
+#ifdef C0_CONFIG
+/* CP0 Config register */
+#define mips32_getconfig()	mips32_get_c0(C0_CONFIG)
+#define mips32_setconfig(v)	mips32_set_c0(C0_CONFIG,v)
+#define mips32_xchconfig(v)	mips32_xch_c0(C0_CONFIG,v)
+#define mips32_bicconfig(c)	mips32_bc_c0(C0_CONFIG,c)
+#define mips32_bisconfig(s)	mips32_bs_c0(C0_CONFIG,s)
+#define mips32_bcsconfig(c,s)	mips32_bcs_c0(C0_CONFIG,c,s)
+#endif
+
+#ifdef C0_ECC
+/* CP0 ECC register */
+#define mips32_getecc()		mips32_get_c0(C0_ECC)
+#define mips32_setecc(x)	mips32_set_c0(C0_ECC, x)
+#define mips32_xchecc(x)	mips32_xch_c0(C0_ECC, x)
+#endif
+
+#ifdef C0_TAGHI
+/* CP0 TagHi register */
+#define mips32_gettaghi()	mips32_get_c0(C0_TAGHI)
+#define mips32_settaghi(x)	mips32_set_c0(C0_TAGHI, x)
+#define mips32_xchtaghi(x)	mips32_xch_c0(C0_TAGHI, x)
+#endif
+
+#ifdef C0_WATCHLO
+/* CP0 WatchLo register */
+#define mips32_getwatchlo()	mips32_get_c0(C0_WATCHLO)
+#define mips32_setwatchlo(x)	mips32_set_c0(C0_WATCHLO, x)
+#define mips32_xchwatchlo(x)	mips32_xch_c0(C0_WATCHLO, x)
+#endif
+
+#ifdef C0_WATCHHI
+/* CP0 WatchHi register */
+#define mips32_getwatchhi()	mips32_get_c0(C0_WATCHHI)
+#define mips32_setwatchhi(x)	mips32_set_c0(C0_WATCHHI, x)
+#define mips32_xchwatchhi(x)	mips32_xch_c0(C0_WATCHHI, x)
+#endif
+
+#ifdef C0_USERTRACE1
+/* PDTRACE usertrace registers */
+#define mips32_usertrace1(x)	mips32_set_c0(C0_USERTRACE1, x)
+#define mips32_usertrace2(x)	mips32_set_c0(C0_USERTRACE2, x)
+#endif
+
+/*
+ * Define macros for accessing the MIPS32 coprocessor 0 registers.  Most
+ * apart from "set" return the original register value.  These particular
+ * macros take (reg, sel) as separate paramters, so they can't be used with
+ * the coprocessor 0 register names above.
+ */
+#define _m32c0_mfc0(reg, sel) \
+__extension__ ({ \
+  register unsigned long __r; \
+  __asm__ __volatile ("mfc0 %0,$%1,%2" \
+		      : "=d" (__r) \
+      		      : "JK" (reg), "JK" (sel)); \
+  __r; \
+})
+
+#define _m32c0_mtc0(reg, sel, val) \
+do { \
+    __asm__ __volatile (".set push \n"\
+			".set noreorder\n"\
+			"mtc0 %z0,$%1,%2\n"\
+			"ehb\n" \
+			".set pop" \
+			: \
+			: "dJ" ((reg32_t)(val)), "JK" (reg), "JK" (sel) \
+			: "memory"); \
+} while (0)
+
+#define _m32c0_mxc0(reg, sel, val) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _m32c0_mfc0 (reg, sel); \
+    _m32c0_mtc0 (reg, sel, val); \
+    __o; \
+})
+
+#define _m32c0_bcc0(reg, sel, clr) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _m32c0_mfc0 (reg, sel); \
+    _m32c0_mtc0 (reg, sel, __o & ~(clr)); \
+    __o; \
+})
+
+#define _m32c0_bsc0(reg, sel, set) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _m32c0_mfc0 (reg, sel); \
+    _m32c0_mtc0 (reg, sel, __o | (set)); \
+    __o; \
+})
+
+#define _m32c0_bcsc0(reg, sel, clr, set) \
+__extension__ ({ \
+    register reg32_t __o; \
+    __o = _m32c0_mfc0 (reg, sel); \
+    _m32c0_mtc0 (reg, sel, (__o & ~(clr)) | (set)); \
+    __o; \
+})
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Define MIPS32 user-level intrinsics */
+#include <mips/mips32.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CP0 intrinsics */
+
+/* MIPS32r2 atomic interrupt disable */
+#define _mips_intdisable() __extension__({ \
+    unsigned int __v; \
+    __asm__ __volatile__ ("di %0; ehb" : "=d" (__v)); \
+    __v; \
+})
+
+/* MIPS32r2 atomic interrupt disable */
+#define _mips_intenable() __extension__({ \
+    unsigned int __v; \
+    __asm__ __volatile__ ("ei %0; ehb" : "=d" (__v)); \
+    __v; \
+})
+
+/* MIPS32r2 atomic interrupt restore */
+#define _mips_intrestore(x) \
+    mips_setsr (x)
+
+/* MIPS32r2 set SRSCtl.PSS (previous shadow set), returning old value */
+extern unsigned int _mips32r2_xchsrspss (unsigned int);
+
+/* MIPS32r2 write previous gpr */
+#define _mips32r2_wrpgpr(regno, val) \
+do { \
+    __asm __volatile ("wrpgpr $%0,%z1" \
+        	      : /* no outputs */ \
+ 		      : "JK" (regno), "dJ" (val)); \
+} while (0)
+
+/* MIPS32r2 read previous gpr */
+#define _mips32r2_rdpgpr(regno) \
+__extension__({ \
+    reg_t __val; \
+    __asm __volatile ("rdpgpr %0,$%1" \
+        	      : "=d" (__val) \
+ 		      : "JK" (regno)); \
+    __val; \
+})
+
+#endif /* __ASSEMBLER__ */
+
+/* MIPS32 PREF instruction hint codes */
+#define PREF_LOAD		0
+#define PREF_STORE		1
+#define PREF_LOAD_STREAMED	4
+#define PREF_STORE_STREAMED	5
+#define PREF_LOAD_RETAINED	6
+#define PREF_STORE_RETAINED	7
+#define PREF_WRITEBACK_INVAL	25
+#define PREF_PREPAREFORSTORE	30
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _M32C0_H_ */
diff --git a/libgloss/mips/include/mips/m32c1.h b/libgloss/mips/include/mips/m32c1.h
new file mode 100644
index 000000000..a4524ec2d
--- /dev/null
+++ b/libgloss/mips/include/mips/m32c1.h
@@ -0,0 +1,274 @@ 
+/*
+ * 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 _M32C1_H_
+#define _M32C1_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ASSEMBLER__
+
+unsigned fpa_getrid(void);	/* get fpa revision id */
+unsigned fpa_getsr(void);	/* get fpa status register */
+void	 fpa_setsr(unsigned);
+unsigned fpa_xchsr(unsigned);
+unsigned fpa_bicsr(unsigned);
+unsigned fpa_bissr(unsigned);
+
+unsigned msa_getmir(void);	/* get msa revision id */
+unsigned msa_getsr(void);	/* get msa status register */
+void	 msa_setsr(unsigned);
+unsigned msa_xchsr(unsigned);
+unsigned msa_bicsr(unsigned);
+unsigned msa_bissr(unsigned);
+
+/*
+ * Define macros to accessing the Coprocessor 1 control registers.
+ * Most apart from "set" return the original register value.
+ */
+
+#define fpa_getrid() \
+__extension__({ \
+  register unsigned __r; \
+  __asm__ __volatile ("cfc1 %0,$0" : "=d" (__r)); \
+  __r; \
+})
+
+#define fpa_getfir() fpa_getrid()
+
+#define fpa_getsr() \
+__extension__({ \
+  register unsigned __r; \
+  __asm__ __volatile ("cfc1 %0,$31" : "=d" (__r)); \
+  __r; \
+})
+
+#define fpa_setsr(val) \
+__extension__({ \
+    register unsigned __r = (val); \
+    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__r)); \
+    __r; \
+})
+
+#define fpa_xchsr(val) \
+__extension__({ \
+    register unsigned __o, __n = (val); \
+    __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \
+    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \
+    __o; \
+})
+
+#define fpa_bissr(val) \
+__extension__({ \
+    register unsigned __o, __n; \
+    __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \
+    __n = __o | (val); \
+    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \
+    __o; \
+})
+
+#define fpa_bicsr(val) \
+__extension__({ \
+    register unsigned __o, __n; \
+    __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \
+    __n = __o &~ (val); \
+    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \
+    __o; \
+})
+
+
+#define msa_getmir() \
+__extension__({ \
+  register unsigned __r; \
+  __asm__ __volatile (".set push\n" \
+		      ".set fp=64\n" \
+		      ".set msa\n" \
+		      "cfcmsa %0,$0\n" \
+		      ".set pop": "=d" (__r)); \
+  __r; \
+})
+
+#define msa_getsr() \
+__extension__({ \
+  register unsigned __r; \
+  __asm__ __volatile (".set push\n" \
+		      ".set fp=64\n" \
+		      ".set msa\n" \
+		      "cfcmsa %0,$1\n" \
+		      ".set pop": "=d" (__r)); \
+  __r; \
+})
+
+#define msa_setsr(val) \
+__extension__({ \
+    register unsigned __r = (val); \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"ctcmsa $1,%0\n" \
+			".set pop": : "d" (__r)); \
+    __r; \
+})
+
+#define msa_xchsr(val) \
+__extension__({ \
+    register unsigned __o, __n = (val); \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"cfcmsa %0,$1\n" \
+			".set pop": "=d" (__o)); \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"ctcmsa $1,%0\n" \
+			".set pop": : "d" (__n)); \
+    __o; \
+})
+
+#define msa_bissr(val) \
+__extension__({ \
+    register unsigned __o, __n; \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"cfcmsa %0,$1\n" \
+			".set pop": "=d" (__o)); \
+    __n = __o | (val); \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"ctcmsa $1,%0\n" \
+			".set pop": : "d" (__n)); \
+    __o; \
+})
+
+#define msa_bicsr(val) \
+__extension__({ \
+    register unsigned __o, __n; \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"cfcmsa %0,$1\n" \
+			".set pop": "=d" (__o)); \
+    __n = __o &~ (val); \
+    __asm__ __volatile (".set push\n" \
+			".set fp=64\n" \
+			".set msa\n" \
+			"ctcmsa $1,%0\n" \
+			".set pop": : "d" (__n)); \
+    __o; \
+})
+
+#endif /* !ASSEMBLER */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * FCSR - FPU Control & Status Register
+ */
+#define FPA_CSR_MD0	0x00200000	/* machine dependent */
+#define FPA_CSR_MD1	0x00400000	/* machine dependent */
+#define FPA_CSR_COND	0x00800000	/* $fcc0 */
+#define FPA_CSR_COND0	0x00800000	/* $fcc0 */
+#define FPA_CSR_FLUSH	0x01000000	/* flush to 0 */
+#define FPA_CSR_FS	0x01000000	/* flush to 0 */
+#define FPA_CSR_COND1	0x02000000	/* $fcc1 */
+#define FPA_CSR_COND2	0x04000000	/* $fcc2 */
+#define FPA_CSR_COND3	0x08000000	/* $fcc3 */
+#define FPA_CSR_COND4	0x10000000	/* $fcc4 */
+#define FPA_CSR_COND5	0x20000000	/* $fcc5 */
+#define FPA_CSR_COND6	0x40000000	/* $fcc6 */
+#define FPA_CSR_COND7	0x80000000	/* $fcc7 */
+
+/*
+ * X the exception cause indicator
+ * E the exception enable
+ * S the sticky/flag bit
+*/
+#define FPA_CSR_ALL_X 0x0003f000
+#define FPA_CSR_UNI_X	0x00020000
+#define FPA_CSR_INV_X	0x00010000
+#define FPA_CSR_DIV_X	0x00008000
+#define FPA_CSR_OVF_X	0x00004000
+#define FPA_CSR_UDF_X	0x00002000
+#define FPA_CSR_INE_X	0x00001000
+
+#define FPA_CSR_ALL_E	0x00000f80
+#define FPA_CSR_INV_E	0x00000800
+#define FPA_CSR_DIV_E	0x00000400
+#define FPA_CSR_OVF_E	0x00000200
+#define FPA_CSR_UDF_E	0x00000100
+#define FPA_CSR_INE_E	0x00000080
+
+#define FPA_CSR_ALL_S	0x0000007c
+#define FPA_CSR_INV_S	0x00000040
+#define FPA_CSR_DIV_S	0x00000020
+#define FPA_CSR_OVF_S	0x00000010
+#define FPA_CSR_UDF_S	0x00000008
+#define FPA_CSR_INE_S	0x00000004
+
+/* rounding mode */
+#define FPA_CSR_RN	0x0	/* nearest */
+#define FPA_CSR_RZ	0x1	/* towards zero */
+#define FPA_CSR_RU	0x2	/* towards +Infinity */
+#define FPA_CSR_RD	0x3	/* towards -Infinity */
+
+/* FPU Implementation Register */
+#define FPA_FIR_F64	0x00400000	/* implements 64-bits registers */
+#define FPA_FIR_L	0x00200000	/* implements long fixed point */
+#define FPA_FIR_W	0x00100000	/* implements word fixed point */
+#define FPA_FIR_3D	0x00080000	/* implements MIPS-3D ASE */
+#define FPA_FIR_PS	0x00040000	/* implements paired-single format */
+#define FPA_FIR_D	0x00020000	/* implements double format */
+#define FPA_FIR_S	0x00010000	/* implements single format */
+#define FPA_FIR_PRID	0x0000ff00	/* ProcessorID */
+#define FPA_FIR_REV	0x000000ff	/* Revision */
+
+#ifdef __ASSEMBLER__
+
+	.previous
+
+/* control regs */
+	$fir =		$0
+	$fccr =		$25
+	$fexr =		$26
+	$fenr =		$28
+	$fcsr  =	$31
+
+/* backwards compat */
+	$fpa_rid =	$0
+	$fpa_sr  =	$31
+#endif
+
+
+#endif /*_M32C1_H_*/
diff --git a/libgloss/mips/include/mips/m32tlb.h b/libgloss/mips/include/mips/m32tlb.h
new file mode 100644
index 000000000..83d781e27
--- /dev/null
+++ b/libgloss/mips/include/mips/m32tlb.h
@@ -0,0 +1,101 @@ 
+/*
+ * 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.
+*/
+
+ /*
+  * m32tlb.h: MIPS32 TLB support functions
+  */
+
+#ifndef _M32TLB_H_
+#define _M32TLB_H_
+
+#if __mips != 32 && __mips != 64
+#error use -mips32 or -mips64 option with this file
+#endif
+
+#include <mips/notlb.h>
+#ifndef __ASSEMBLER__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __mips16
+# define _MIPS_M32TLB_NOMIPS16 __attribute__((nomips16))
+#else
+# define _MIPS_M32TLB_NOMIPS16
+#endif
+
+typedef unsigned int tlbhi_t;
+typedef unsigned int tlblo_t;
+
+// Returns the size of the TLB.
+_MIPS_M32TLB_NOMIPS16
+int mips_tlb_size (void);
+ // Probes the TLB for an entry matching hi, and if present invalidates it.
+_MIPS_M32TLB_NOMIPS16
+void mips_tlbinval (tlbhi_t hi);
+
+// Invalidate the whole TLB.
+_MIPS_M32TLB_NOMIPS16
+void mips_tlbinvalall (void);
+
+// Reads the TLB entry with specified by index, and returns the EntryHi,
+// EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmsk
+// respectively.
+_MIPS_M32TLB_NOMIPS16
+void mips_tlbri2 (tlbhi_t *phi, tlblo_t *plo0, tlblo_t *plo1, unsigned *pmsk,
+		  int index);
+
+// Writes hi, lo0, lo1 and msk into the TLB entry specified by index.
+_MIPS_M32TLB_NOMIPS16
+void mips_tlbwi2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk,
+		  int index);
+
+// Writes hi, lo0, lo1 and msk into the TLB entry specified by the
+// Random register.
+_MIPS_M32TLB_NOMIPS16
+void mips_tlbwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk);
+
+// Probes the TLB for an entry matching hi and returns its index, or -1 if
+// not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of the
+// entry are also returned in *plo0, *plo1 and *pmsk respectively
+_MIPS_M32TLB_NOMIPS16
+int mips_tlbprobe2 (tlbhi_t hi, tlblo_t *plo0, tlblo_t *plo1, unsigned *pmsk);
+
+// Probes the TLB for an entry matching hi and if present rewrites that entry,
+// otherwise updates a random entry. A safe way to update the TLB.
+_MIPS_M32TLB_NOMIPS16
+int mips_tlbrwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _M32TLB_H_ */
diff --git a/libgloss/mips/include/mips/m64c0.h b/libgloss/mips/include/mips/m64c0.h
new file mode 100644
index 000000000..2f4a34043
--- /dev/null
+++ b/libgloss/mips/include/mips/m64c0.h
@@ -0,0 +1,266 @@ 
+/*
+ * 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 _M64C0_H_
+#define _M64C0_H_
+
+/* Superset of MIPS32 */
+#include <mips/m32c0.h>
+
+#ifndef __ASSEMBLER__
+typedef union {
+  unsigned long long ll;
+  struct {
+#if defined(_MIPSEB) || defined(MIPSEB)
+    unsigned int hi;
+    unsigned int lo;
+#else
+    unsigned int lo;
+    unsigned int hi;
+#endif
+  } s;
+} __ll_shape_type;
+#endif
+
+/*
+ * Define macros for accessing the MIPS coprocessor 0 registers which are
+ * 64 bits wide.
+ * Most apart from "set" return the original register value.
+ */
+
+#if (_MIPS_SIM == _ABIO32)
+#define mips64_get_c0(selreg) \
+__extension__ ({ \
+  __ll_shape_type __r; \
+  __asm__ __volatile ("mfc0 %0,$%2,%3\n" \
+		      ".set  push\n"\
+		      ".set  xpa\n"\
+		      "mfhc0 %1,$%2,%3\n" \
+		      ".set  pop\n" \
+		      : "=r" (__r.s.lo), \
+		        "=r" (__r.s.hi) \
+		      : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \
+  __r.ll; \
+})
+#else	/* _MIPS_SIM==N32 || _MIPS_SIM==N64 */
+#define mips64_get_c0(selreg) \
+__extension__ ({ \
+  register unsigned long __r; \
+  __asm__ __volatile ("dmfc0 %0,$%1,%2" \
+		      : "=d" (__r) \
+		      : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \
+  __r; \
+})
+#endif
+
+#undef EHB
+#if defined (__MIPS_NO_IMPLICIT_EHB)
+#define EHB	""
+#else
+#define EHB	"ehb\n"
+#endif
+
+#if (_MIPS_SIM == _ABIO32)
+#define mips64_set_c0(selreg, val) \
+do { \
+    __ll_shape_type __ll; \
+    __ll.ll = (val); \
+    __asm__ __volatile (".set push \n"\
+			".set noreorder\n"\
+			"mtc0 %z0,$%2,%3\n"\
+			".set  xpa\n"\
+			"mthc0 %z1,$%2,%3\n"\
+			EHB \
+			".set pop" \
+			: \
+			: "dJ" ((reg32_t)(__ll.s.lo)),\
+			  "dJ" ((reg32_t)(__ll.s.hi)),\
+			  "JK" (selreg & 0x1F),\
+			  "JK" (selreg >> 8)\
+			: "memory"); \
+} while (0)
+#else	/* _MIPS_SIM==N32 || _MIPS_SIM==N64 */
+#define mips64_set_c0(selreg, val) \
+do { \
+    __asm__ __volatile (".set push \n"\
+			".set noreorder\n"\
+			"dmtc0 %z0,$%1,%2\n"\
+			EHB \
+			".set pop" \
+			: \
+			: "dJ" ((reg64_t)(val)), "JK" (selreg & 0x1F),\
+			  "JK" (selreg >> 8) \
+			: "memory"); \
+} while (0)
+#endif
+
+#define mips64_xch_c0(selreg, val) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = mips64_get_c0 (selreg); \
+    mips64_set_c0 (selreg, val); \
+    __o; \
+})
+
+#define mips64_bc_c0(selreg, clr) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = mips64_get_c0 (selreg); \
+    mips64_set_c0 (selreg, __o & ~(clr)); \
+    __o; \
+})
+
+#define mips64_bs_c0(selreg, set) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = mips64_get_c0 (selreg); \
+    mips64_set_c0 (selreg, __o | (set)); \
+    __o; \
+})
+
+#define mips64_bcs_c0(selreg, clr, set) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = mips64_get_c0 (selreg); \
+    mips64_set_c0 (selreg, (__o & ~(clr)) | (set)); \
+    __o; \
+})
+
+/* MIPS64 Entry*, Index, PageMask registers */
+#define mips64_setentryhi(x)	mips64_set_c0(C0_ENTRYHI,x)
+#define mips64_getentryhi()	mips64_get_c0(C0_ENTRYHI)
+#define mips64_setentrylo0(x)	mips64_set_c0(C0_ENTRYLO0,x)
+#define mips64_getentrylo0()	mips64_get_c0(C0_ENTRYLO0)
+#define mips64_setentrylo1(x)	mips64_set_c0(C0_ENTRYLO1,x)
+#define mips64_getentrylo1()	mips64_get_c0(C0_ENTRYLO1)
+#define mips64_setpagemask(x)	mips64_set_c0(C0_PAGEMASK,x)
+#define mips64_getpagemask()	mips64_get_c0(C0_PAGEMASK)
+#define mips64_setindex(x)	mips32_set_c0(C0_INDEX,x)
+#define mips64_getindex(x)	mips32_get_c0(C0_INDEX)
+
+/* MIPS64 Config3 and Config4 registers */
+#define mips64_getconfig3()	mips32_get_c0(C0_CONFIG3)
+#define mips64_setconfig3(x)	mips32_set_c0(C0_CONFIG3,x)
+#define mips64_getconfig4()	mips32_get_c0(C0_CONFIG4)
+#define mips64_setconfig4(x)	mips32_set_c0(C0_CONFIG4,x)
+
+/* MIPS64 TagLo register */
+#define mips64_getitaglo()	mips64_get_c0(C0_TAGLO)		/* alias define */
+#define mips64_setitaglo(x)	mips64_set_c0(C0_TAGLO,x)	/* alias define */
+#define mips64_xchitaglo(x)	mips64_xch_c0(C0_TAGLO,x)	/* alias define */
+#define mips64_getdtaglo()	mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 2))
+#define mips64_setdtaglo(x)	mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 2),x)
+#define mips64_xchdtaglo(x)	mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 2),x)
+#define mips64_gettaglo2()	mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 4))
+#define mips64_settaglo2(x)	mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 4),x)
+#define mips64_xchtaglo2(x)	mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 4),x)
+
+/* MIPS64 DataLo register */
+#define mips64_getdatalo()	mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 1))
+#define mips64_setdatalo(x)	mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 1),x)
+#define mips64_xchdatalo(x)	mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 1),x)
+#define mips64_getidatalo()	mips64_getdatalo()	/* alias define */
+#define mips64_setidatalo(x)	mips64_setdatalo(x)	/* alias define */
+#define mips64_xchidatalo(x)	mips64_xchdatalo(x)	/* alias define */
+#define mips64_getddatalo()	mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 3))
+#define mips64_setddatalo(x)	mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 3),x)
+#define mips64_xchddatalo(x)	mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 3),x)
+#define mips64_getdatalo2()	mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 5))
+#define mips64_setdatalo2(x)	mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, 5),x)
+#define mips64_xchdatalo2(x)	mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, 5),x)
+
+/* CP0 TagHi register */
+#define mips64_gettaghi()	mips64_get_c0(C0_TAGHI)
+#define mips64_settaghi(x)	mips64_set_c0(C0_TAGHI, x)
+#define mips64_xchtaghi(x)	mips64_xch_c0(C0_TAGHI, x)
+
+/* CP0 WatchLo register */
+#define mips64_getwatchlo()	mips64_get_c0(C0_WATCHLO)
+#define mips64_setwatchlo(x)	mips64_set_c0(C0_WATCHLO, x)
+#define mips64_xchwatchlo(x)	mips64_xch_c0(C0_WATCHLO, x)
+
+#define _m64c0_mfc0(reg, sel) \
+__extension__ ({ \
+  register unsigned long __r; \
+  __asm__ __volatile ("dmfc0 %0,$%1,%2" \
+		      : "=d" (__r) \
+      		      : "JK" (reg), "JK" (sel)); \
+  __r; \
+})
+
+#define _m64c0_mtc0(reg, sel, val) \
+do { \
+    __asm__ __volatile (".set push \n"\
+			".set noreorder\n"\
+			"dmtc0 %z0,$%1,%2\n"\
+			"ehb\n" \
+			".set pop" \
+			: \
+			: "dJ" ((reg64_t)(val)), "JK" (reg), "JK" (sel) \
+			: "memory"); \
+} while (0)
+
+#define _m64c0_mxc0(reg, sel, val) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = _m64c0_mfc0 (reg, sel); \
+    _m64c0_mtc0 (reg, sel, val); \
+    __o; \
+})
+
+#define _m64c0_bcc0(reg, sel, clr) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = _m64c0_mfc0 (reg, sel); \
+    _m64c0_mtc0 (reg, sel, __o & ~(clr)); \
+    __o; \
+})
+
+#define _m64c0_bsc0(reg, sel, set) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = _m64c0_mfc0 (reg, sel); \
+    _m64c0_mtc0 (reg, sel, __o | (set)); \
+    __o; \
+})
+
+#define _m64c0_bcsc0(reg, sel, clr, set) \
+__extension__ ({ \
+    register reg64_t __o; \
+    __o = _m64c0_mfc0 (reg, sel); \
+    _m64c0_mtc0 (reg, sel, (__o & ~(clr)) | (set)); \
+    __o; \
+})
+
+/* Define MIPS64 user-level intrinsics */
+#include <mips/mips64.h>
+
+/* MIPS64-specific MMU interface */
+#include <mips/m64tlb.h>
+
+#endif /* _M64C0_H_ */
diff --git a/libgloss/mips/include/mips/m64tlb.h b/libgloss/mips/include/mips/m64tlb.h
new file mode 100644
index 000000000..4894d256a
--- /dev/null
+++ b/libgloss/mips/include/mips/m64tlb.h
@@ -0,0 +1,104 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * m64tlb.h: MIPS64 / XPA TLB support functions
+*/
+#ifndef _M64TLB_H_
+#define _M64TLB_H_
+
+#if __mips != 32 && __mips != 64
+#error use -mips32 or -mips64 option with this file
+#endif
+
+#include <mips/notlb.h>
+
+#ifndef __ASSEMBLER__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __mips16
+# define _MIPS_M64TLB_NOMIPS16 __attribute__((nomips16))
+#else
+# define _MIPS_M64TLB_NOMIPS16
+#endif
+
+typedef unsigned long long tlbhi64_t;
+typedef unsigned long long tlblo64_t;
+// Returns the size of the TLB.
+_MIPS_M64TLB_NOMIPS16
+int m64_tlb_size (void);
+
+// Probes the TLB for an entry matching hi, and if present invalidates it.
+_MIPS_M64TLB_NOMIPS16
+void m64_tlbinval (tlbhi64_t hi);
+
+// Invalidate the whole TLB.
+_MIPS_M64TLB_NOMIPS16
+void m64_tlbinvalall (void);
+
+// Reads the TLB entry with specified by index, and returns the EntryHi,
+// EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmsk
+// respectively.
+_MIPS_M64TLB_NOMIPS16
+void m64_tlbri2 (tlbhi64_t *phi, tlblo64_t *plo0, tlblo64_t *plo1,
+		 unsigned long long *pmsk, int index);
+
+// Writes hi, lo0, lo1 and msk into the TLB entry specified by index.
+_MIPS_M64TLB_NOMIPS16
+void m64_tlbwi2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
+		 unsigned long long msk, int index);
+
+// Writes hi, lo0, lo1 and msk into the TLB entry specified by the
+// Random register.
+_MIPS_M64TLB_NOMIPS16
+void m64_tlbwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
+		 unsigned long long msk);
+
+// Probes the TLB for an entry matching hi and returns its index, or -1 if
+// not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of the
+// entry are also returned in *plo0, *plo1 and *pmsk respectively
+_MIPS_M64TLB_NOMIPS16
+int m64_tlbprobe2 (tlbhi64_t hi, tlblo64_t *plo0, tlblo64_t *plo1,
+		   unsigned long long *pmsk);
+
+// Probes the TLB for an entry matching hi and if present rewrites that entry,
+// otherwise updates a random entry. A safe way to update the TLB.
+_MIPS_M64TLB_NOMIPS16
+int m64_tlbrwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
+		 unsigned long long  msk);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _M64TLB_H_ */
diff --git a/libgloss/mips/include/mips/mips32.h b/libgloss/mips/include/mips/mips32.h
new file mode 100644
index 000000000..ccd94829a
--- /dev/null
+++ b/libgloss/mips/include/mips/mips32.h
@@ -0,0 +1,175 @@ 
+/*
+ * 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 _MIPS32_H_
+#define _MIPS32_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ASSEMBLER__
+
+#if ! __mips16
+
+/* C interface to clz/clo instructions */
+
+/* count leading zeros */
+# define mips_clz(x) __builtin_clz (x)
+
+/* count trailing zeros */
+# define mips_ctz(x) __builtin_ctz (x)
+
+#define mips_clo(x) __extension__({ \
+    unsigned int __x = (x); \
+    unsigned int __v; \
+    __asm__ ("clo %0,%1" : "=d" (__v) : "d" (__x)); \
+    __v; \
+})
+
+#ifndef __mips64
+
+/* Simulate 64-bit count leading zeroes */
+#if !defined(mips_dclz)
+#define mips_dclz(x) __extension__({ \
+    unsigned long long __x = (x); \
+    unsigned int __hx = (__x >> 32); \
+    __hx ? mips_clz(__hx) : 32 + mips_clz(__x); \
+})
+#endif
+
+/* Simulate 64-bit count leading ones */
+#if !defined(mips_dclo)
+#define mips_dclo(x) __extension__({ \
+    unsigned long long __x = (x); \
+    unsigned int __hx = (__x >> 32); \
+    (~__hx) ? mips_clo(__hx) : 32 + mips_clo(__x); \
+})
+#endif
+
+/* Simulate 64-bit count trailing zeroes */
+#if !defined(mips_dctz)
+#define mips_dctz(x) __extension__({ \
+    unsigned long long __dx = (x); \
+    unsigned int __ldx = __dx; \
+    unsigned int __hdx = __dx >> 32; \
+    __ldx ? mips_ctz(__ldx) : (63 ^ mips_clz(__hdx & -__hdx)); \
+   })
+#endif
+
+#endif
+
+/* MIPS32r2 wsbh opcode */
+#define _mips32r2_wsbh(x) __extension__({ \
+    unsigned int __x = (x), __v; \
+    __asm__ ("wsbh %0,%1" \
+	     : "=d" (__v) \
+	     : "d" (__x)); \
+    __v; \
+})
+
+/* MIPS32r2 byte-swap word */
+#define _mips32r2_bswapw(x) __extension__({ \
+    unsigned int __x = (x), __v; \
+    __asm__ ("wsbh %0,%1; rotr %0,16" \
+	     : "=d" (__v) \
+	     : "d" (__x)); \
+    __v; \
+})
+
+/* MIPS32r2 insert bits */
+#define _mips32r2_ins(tgt,val,pos,sz) __extension__({ \
+    unsigned int __t = (tgt), __v = (val); \
+    __asm__ ("ins %0,%z1,%2,%3" \
+	     : "+d" (__t) \
+	     : "dJ" (__v), "I" (pos), "I" (sz)); \
+    __t; \
+})
+
+/* MIPS32r2 extract bits */
+#define _mips32r2_ext(x,pos,sz) __extension__({ \
+    unsigned int __x = (x), __v; \
+    __asm__ ("ext %0,%z1,%2,%3" \
+	     : "=d" (__v) \
+	     : "dJ" (__x), "I" (pos), "I" (sz)); \
+    __v; \
+})
+
+#if __mips_isa_rev < 6
+
+/* MIPS32r2 jr.hb */
+#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
+#define mips32_jr_hb() __asm__ __volatile__(	\
+       "bltzal	$0,0f\n"			\
+"0:     addiu	$31,1f-0b\n"			\
+"       jr.hb	$31\n"				\
+"1:"						\
+	: : : "$31")
+#elif _MIPS_SIM == _ABI64
+#define mips32_jr_hb() __asm__ __volatile__(	\
+       "bltzal	$0,0f\n"			\
+"0:     daddiu	$31,1f-0b\n"			\
+"       jr.hb	$31\n"				\
+"1:"						\
+	: : : "$31")
+#else
+#error Unknown ABI
+#endif
+
+#else /*  __mips_isa_rev < 6  */
+
+/* MIP32r6 jr.hb */
+#if _MIPS_SIM == _ABIO32 ||  _MIPS_SIM == _ABIN32
+#define mips32_jr_hb() __asm__ __volatile__(	\
+       "auipc	$24,%pcrel_hi(1f)\n"		\
+       "addiu	$24,%pcrel_lo(1f + 4)\n"	\
+       "jr.hb	$24\n"				\
+"1:"						\
+       : : : "$24")
+#elif _MIPS_SIM == _ABI64
+#define mips32_jr_hb() __asm__ __volatile__(	\
+       "auipc	$24,%pcrel_hi(1f)\n"		\
+       "daddiu	$24,%pcrel_lo(1f + 4)\n"	\
+       "jr.hb	$24\n"				\
+"1:"						\
+       : : : "$24")
+#else
+#error Unknown ABI
+#endif
+
+#endif /* __mips_isa_rev < 6 */
+
+#endif /* ! __mips16 */
+
+#endif /* __ASSEMBLER__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MIPS32_H_ */
diff --git a/libgloss/mips/include/mips/mips64.h b/libgloss/mips/include/mips/mips64.h
new file mode 100644
index 000000000..2602a354d
--- /dev/null
+++ b/libgloss/mips/include/mips/mips64.h
@@ -0,0 +1,114 @@ 
+/*
+ * 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 _MIPS64_H_
+#define _MIPS64_H_
+
+#include <mips/mips32.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __ASSEMBLER__
+
+#if __mips == 64 && ! __mips16
+
+/* 64-bit count leading zeroes */
+#if !defined(mips_dclz)
+# define mips_dclz(x) __builtin_clzll (x)
+#endif
+
+/* 64-bit count trailing zeroes */
+#if !defined(mips_dctz)
+# define mips_dctz(x) __builtin_ctzll (x)
+#endif
+
+#if !defined(mips_dclo)
+#define mips_dclo(x) __extension__({ \
+    unsigned long long __x = (x); \
+    unsigned int __v; \
+    __asm__ ("dclo %0,%1" : "=d" (__v) : "d" (__x)); \
+    __v; \
+})
+#endif
+
+/* MIPS64r2 dshd opcode */
+#define _mips64r2_dshd(x) __extension__({ \
+    unsigned long long __x = (x), __v; \
+    __asm__ ("dshd %0,%1" \
+	     : "=d" (__v) \
+	     : "d" (__x)); \
+    __v; \
+})
+
+/* MIPS64r2 dsbh opcode */
+#define _mips64r2_dsbh(x) __extension__({ \
+    unsigned long long __x = (x), __v; \
+    __asm__ ("dsbh %0,%1" \
+	     : "=d" (__v) \
+	     : "d" (__x)); \
+    __v; \
+})
+
+/* MIPS64r2 byte-swap doubleword */
+#define _mips64r2_bswapd(x) __extension__({ \
+    unsigned long long __x = (x), __v; \
+    __asm__ ("dsbh %0,%1; dshd %0,%0" \
+	     : "=d" (__v) \
+	     : "d" (__x)); \
+    __v; \
+})
+
+/* MIPS64r2 insert bits */
+#define _mips64r2_dins(tgt,val,pos,sz) __extension__({ \
+    unsigned long long __t = (tgt), __v = (val); \
+    __asm__ ("dins %0,%z1,%2,%3" \
+	     : "+d" (__t) \
+	     : "dJ" (__v), "I" (pos), "I" (sz)); \
+    __t; \
+})
+
+/* MIPS64r2 extract bits */
+#define _mips64r2_dext(x,pos,sz) __extension__({ \
+    unsigned long long __x = (x), __v; \
+    __asm__ ("dext %0,%z1,%2,%3" \
+	     : "=d" (__v) \
+	     : "dJ" (__x), "I" (pos), "I" (sz)); \
+    __v; \
+})
+
+#endif /* __mips == 64 && ! __mips16 */
+
+#endif /* !__ASSEMBLER__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MIPS64_H_ */
diff --git a/libgloss/mips/include/mips/mt.h b/libgloss/mips/include/mips/mt.h
new file mode 100644
index 000000000..10bed4cff
--- /dev/null
+++ b/libgloss/mips/include/mips/mt.h
@@ -0,0 +1,519 @@ 
+/*
+ * 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 _MIPS_MT_H_
+#define _MIPS_MT_H_
+
+#include <mips/m32c0.h>
+#include <mips/mips32.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * MIPS32 MVPControl Register (CP0 Register 0, Select 1)
+ */
+#define MVPCONTROL_EVP		0x00000001  /* Enable Virtual Processors */
+#define MVPCONTROL_VPC		0x00000002  /* VPE Configuration State */
+#define MVPCONTROL_STLB		0x00000004  /* Share TLBS */
+#define MVPCONTROL_CPA		0x00000008  /* Cache Partitioning Active */
+
+/*
+ * MIPS32 MVPConf0 Register (CP0 Register 0, Select 2)
+ */
+#define MVPCONF0_PTC		0x000000ff
+#define  MVPCONF0_PTC_SHIFT		 0
+#define MVPCONF0_PVPE		0x00003c00
+#define  MVPCONF0_PVPE_SHIFT		10
+#define MVPCONF0_TCA		0x00008000
+#define MVPCONF0_PTLBE		0x03ff0000
+#define  MVPCONF0_PTLBE_SHIFT		16
+#define MVPCONF0_TLBS		0x20000000
+#define MVPCONF0_M		0x80000000
+
+/*
+ * MIPS32 MVPConf1 Register (CP0 Register 0, Select 3)
+ */
+#define MVPCONF1_PCP1		0x000000ff
+#define  MVPCONF1_PCP1_SHIFT		 0
+#define MVPCONF1_PCP2		0x0003fc00
+#define  MVPCONF1_PCP2_SHIFT		10
+#define MVPCONF1_PCX		0x0ff00000
+#define  MVPCONF1_PCX_SHIFT		20
+#define MVPCONF1_C1F		0x40000000
+#define MVPCONF1_C1M		0x80000000
+
+/*
+ * MIPS32 VPEControl Register (CP0 Register 1, Select 1)
+ */
+#define VPECONTROL_TARGTC	0x000000ff
+#define  VPECONTROL_TARGTC_SHIFT	 0
+#define VPECONTROL_TARGVPE	0x00003c00
+#define  VPECONTROL_TARGVPE_SHIFT	10
+#define VPECONTROL_TE		0x00008000
+#define VPECONTROL_EXCPT	0x00070000
+#define  VPECONTROL_EXCPT_SHIFT	        16
+#define VPECONTROL_GSI		0x00100000
+#define VPECONTROL_YSI		0x00200000
+
+/*
+ * MIPS32 VPEConf0 Register (CP0 Register 1, Select 2)
+ */
+#define VPECONF0_VPA		0x00000001
+#define VPECONF0_MVP		0x00000002
+#define VPECONF0_XTC		0x1fe00000
+#define VPECONF0_XTC_SHIFT		21
+#define VPECONF0_M		0x80000000
+
+/*
+ * MIPS32 VPEConf1 Register (CP0 Register 1, Select 3)
+ */
+#define VPECONF1_NCP1		0x000000ff
+#define  VPECONF1_NCP1_SHIFT		 0
+#define VPECONF1_NCP2		0x0003fc00
+#define  VPECONF1_NCP2_SHIFT		10
+#define VPECONF1_NCX		0x0ff00000
+#define  VPECONF1_NCX_SHIFT		20
+
+/*
+ * MIPS32 YQMask Register (CP0 Register 1, Select 4)
+ */
+#define YQMASK_MASK		0x7fffffff
+#define  YQMASK_MASK_SHIFT		 0
+
+/*
+ * MIPS32 VPEOpt Register (CP0 Register 1, Select 7)
+ */
+#define VPEOPT_DWX0		0x00000001
+#define VPEOPT_DWX1		0x00000002
+#define VPEOPT_DWX2		0x00000004
+#define VPEOPT_DWX3		0x00000008
+#define VPEOPT_DWX4		0x00000010
+#define VPEOPT_DWX5		0x00000020
+#define VPEOPT_DWX6		0x00000040
+#define VPEOPT_DWX7		0x00000080
+#define VPEOPT_DWX		0x000000ff
+#define  VPEOPT_DWX_SHIFT	 0
+#define VPEOPT_IWX0		0x00000100
+#define VPEOPT_IWX1		0x00000200
+#define VPEOPT_IWX2		0x00000400
+#define VPEOPT_IWX3		0x00000800
+#define VPEOPT_IWX4		0x00001000
+#define VPEOPT_IWX5		0x00002000
+#define VPEOPT_IWX6		0x00004000
+#define VPEOPT_IWX7		0x00008000
+#define VPEOPT_IWX		0x0000ff00
+#define  VPEOPT_IWX_SHIFT	 8
+
+/*
+ * MIPS32 TCStatus Register (CP0 Register 2, Select 1)
+ */
+#define TCSTATUS_TASID		0x000000ff
+#define  TCSTATUS_TASID_SHIFT	         0
+#define TCSTATUS_IXMT		0x00000400
+#define TCSTATUS_TKSU		0x00001800
+#define  TCSTATUS_TKSU_SHIFT		11
+#define TCSTATUS_A		0x00002000
+#define TCSTATUS_DA		0x00008000
+#define TCSTATUS_IMPL		0x000f0000
+#define  TCSTATUS_IMPL_SHIFT		16
+#define TCSTATUS_DT		0x00100000
+#define TCSTATUS_TDS		0x00200000
+#define TCSTATUS_TSST		0x00400000
+#define TCSTATUS_RNST		0x01800000
+#define  TCSTATUS_RNST_SHIFT		23
+#define TCSTATUS_TCU0		0x10000000
+#define TCSTATUS_TCU1		0x20000000
+#define TCSTATUS_TCU2		0x40000000
+#define TCSTATUS_TCU3		0x80000000
+
+/*
+ * MIPS32 TCBind Register (CP0 Register 2, Select 2)
+ */
+#define TCBIND_CURVPE		0x0000000f
+#define  TCBIND_CURVPE_SHIFT		 0
+#define TCBIND_CURTC		0x1fe00000
+#define  TCBIND_CURTC_SHIFT		21
+
+/*
+ * MIPS32 TCHalt Register (CP0 Register 2, Select 4)
+ */
+#define TCHALT_H		0x00000001
+
+/*
+ * MIPS32 SRSConf0 Register (CP0 Register 6, Select 1)
+ */
+#define SRSCONF0_SRS1		0x000003ff
+#define  SRSCONF0_SRS1_SHIFT		 0
+#define SRSCONF0_SRS2		0x000ffc00
+#define  SRSCONF0_SRS2_SHIFT		10
+#define SRSCONF0_SRS3		0x3ff00000
+#define  SRSCONF0_SRS3_SHIFT		20
+#define SRSCONF0_M		0x80000000
+
+/*
+ * MIPS32 SRSConf1 Register (CP0 Register 6, Select 2)
+ */
+#define SRSCONF1_SRS4		0x000003ff
+#define  SRSCONF1_SRS4_SHIFT		 0
+#define SRSCONF1_SRS5		0x000ffc00
+#define  SRSCONF1_SRS5_SHIFT		10
+#define SRSCONF1_SRS6		0x3ff00000
+#define  SRSCONF1_SRS6_SHIFT		20
+#define SRSCONF1_M		0x80000000
+
+/*
+ * MIPS32 SRSConf2 Register (CP0 Register 6, Select 3)
+ */
+#define SRSCONF2_SRS7		0x000003ff
+#define  SRSCONF2_SRS7_SHIFT		 0
+#define SRSCONF2_SRS8		0x000ffc00
+#define  SRSCONF2_SRS8_SHIFT		10
+#define SRSCONF2_SRS9		0x3ff00000
+#define  SRSCONF2_SRS9_SHIFT		20
+#define SRSCONF2_M		0x80000000
+
+/*
+ * MIPS32 SRSConf3 Register (CP0 Register 6, Select 4)
+ */
+#define SRSCONF3_SRS10		0x000003ff
+#define  SRSCONF3_SRS10_SHIFT		 0
+#define SRSCONF3_SRS11		0x000ffc00
+#define  SRSCONF3_SRS11_SHIFT		10
+#define SRSCONF3_SRS12		0x3ff00000
+#define  SRSCONF3_SRS12_SHIFT		20
+#define SRSCONF3_M		0x80000000
+
+/*
+ * MIPS32 SRSConf4 Register (CP0 Register 6, Select 5)
+ */
+#define SRSCONF4_SRS13		0x000003ff
+#define  SRSCONF4_SRS13_SHIFT		 0
+#define SRSCONF4_SRS14		0x000ffc00
+#define  SRSCONF4_SRS14_SHIFT		10
+#define SRSCONF4_SRS15		0x3ff00000
+#define  SRSCONF4_SRS15_SHIFT		20
+
+/*
+ * MIPS32 Config3 Register (CP0 Register 16, Select 3)
+ * New fields for MT
+ */
+#define CFG3_MT			0x00000004
+
+#ifdef __ASSEMBLER__
+
+/*
+ * MT Coprocessor 0 register numbers
+ */
+#define C0_MVPCONTROL         $0,1
+#define C0_MVPCONF0           $0,2
+#define C0_MVPCONF1           $0,3
+#define C0_VPECONTROL         $1,1
+#define C0_VPECONF0           $1,2
+#define C0_VPECONF1           $1,3
+#define C0_YQMASK             $1,4
+#define C0_VPESCHEDULE        $1,5
+#define C0_VPESCHEFBACK       $1,6
+#define C0_VPEOPT	      $1,7
+#define C0_TCSTATUS           $2,1
+#define C0_TCBIND             $2,2
+#define C0_TCRESTART          $2,3
+#define C0_TCHALT             $2,4
+#define C0_TCCONTEXT          $2,5
+#define C0_TCSCHEDULE         $2,6
+#define C0_TCSCHEFBACK        $2,7
+#define C0_SRSCONF0           $6,1
+#define C0_SRSCONF1           $6,2
+#define C0_SRSCONF2           $6,3
+#define C0_SRSCONF3           $6,4
+#define C0_SRSCONF4           $6,5
+
+#else
+
+#define mips32_getmvpcontrol()	        _m32c0_mfc0(0,1)
+#define mips32_setmvpcontrol(x)	        _m32c0_mtc0(0,1,x)
+#define mips32_xchmvpcontrol(x)	        _m32c0_mxc0(0,1,x)
+
+#define mips32_getmvpconf0()	        _m32c0_mfc0(0,2)
+#define mips32_setmvpconf0(x)	        _m32c0_mtc0(0,2,x)
+#define mips32_xchmvpconf0(x)	        _m32c0_mxc0(0,2,x)
+
+#define mips32_getmvpconf1()	        _m32c0_mfc0(0,3)
+#define mips32_setmvpconf1(x)	        _m32c0_mtc0(0,3,x)
+#define mips32_xchmvpconf1(x)	        _m32c0_mxc0(0,3,x)
+
+#define mips32_getvpecontrol()	        _m32c0_mfc0(1,1)
+#define mips32_setvpecontrol(x)	        _m32c0_mtc0(1,1,x)
+#define mips32_xchvpecontrol(x)	        _m32c0_mxc0(1,1,x)
+
+#define mips32_getvpeconf0()	        _m32c0_mfc0(1,2)
+#define mips32_setvpeconf0(x)	        _m32c0_mtc0(1,2,x)
+#define mips32_xchvpeconf0(x)	        _m32c0_mxc0(1,2,x)
+
+#define mips32_getvpeconf1()	        _m32c0_mfc0(1,3)
+#define mips32_setvpeconf1(x)	        _m32c0_mtc0(1,3,x)
+#define mips32_xchvpeconf1(x)	        _m32c0_mxc0(1,3,x)
+
+#define mips32_getyqmask()	        _m32c0_mfc0(1,4)
+#define mips32_setyqmask(x)	        _m32c0_mtc0(1,4,x)
+#define mips32_xchyqmask(x)	        _m32c0_mxc0(1,4,x)
+
+#define mips32_getvpeschedule()	        _m32c0_mfc0(1,5)
+#define mips32_setvpeschedule(x)	_m32c0_mtc0(1,5,x)
+#define mips32_xchvpeschedule(x)	_m32c0_mxc0(1,5,x)
+
+#define mips32_getvpeschefback()        _m32c0_mfc0(1,6)
+#define mips32_setvpeschefback(x)       _m32c0_mtc0(1,6,x)
+#define mips32_xchvpeschefback(x)       _m32c0_mxc0(1,6,x)
+
+#define mips32_getvpeopt()        	_m32c0_mfc0(1,7)
+#define mips32_setvpeopt(x)       	_m32c0_mtc0(1,7,x)
+#define mips32_xchvpeopt(x) 		_m32c0_mxc0(1,7,x)
+
+#define mips32_gettcstatus()	        _m32c0_mfc0(2,1)
+#define mips32_settcstatus(x)	        _m32c0_mtc0(2,1,x)
+#define mips32_xchtcstatus(x)	        _m32c0_mxc0(2,1,x)
+
+#define mips32_gettcbind()	        _m32c0_mfc0(2,2)
+#define mips32_settcbind(x)	        _m32c0_mtc0(2,2,x)
+#define mips32_xchtcbind(x)	        _m32c0_mxc0(2,2,x)
+
+#define mips32_gettcrestart()	        _m32c0_mfc0(2,3)
+#define mips32_settcrestart(x)	        _m32c0_mtc0(2,3,x)
+#define mips32_xchtcrestart(x)	        _m32c0_mxc0(2,3,x)
+
+#define mips32_gettchalt()	        _m32c0_mfc0(2,4)
+#define mips32_settchalt(x)	        _m32c0_mtc0(2,4,x)
+#define mips32_xchtchalt(x)	        _m32c0_mxc0(2,4,x)
+
+#define mips32_gettccontext()	        _m32c0_mfc0(2,5)
+#define mips32_settccontext(x)	        _m32c0_mtc0(2,5,x)
+#define mips32_xchtccontext(x)	        _m32c0_mxc0(2,5,x)
+
+#define mips32_gettcschedule()	        _m32c0_mfc0(2,6)
+#define mips32_settcschedule(x)	        _m32c0_mtc0(2,6,x)
+#define mips32_xchtcschedule(x)	        _m32c0_mxc0(2,6,x)
+
+#define mips32_gettcschefback()	        _m32c0_mfc0(2,7)
+#define mips32_settcschefback(x)        _m32c0_mtc0(2,7,x)
+#define mips32_xchtcschefback(x)        _m32c0_mxc0(2,7,x)
+
+#define mips32_getsrsconf0()	        _m32c0_mfc0(6,1)
+#define mips32_setsrsconf0(x)	        _m32c0_mtc0(6,1,x)
+#define mips32_xchsrsconf0(x)	        _m32c0_mxc0(6,1,x)
+
+#define mips32_getsrsconf1()	        _m32c0_mfc0(6,2)
+#define mips32_setsrsconf1(x)	        _m32c0_mtc0(6,2,x)
+#define mips32_xchsrsconf1(x)	        _m32c0_mxc0(6,2,x)
+
+#define mips32_getsrsconf2()	        _m32c0_mfc0(6,3)
+#define mips32_setsrsconf2(x)	        _m32c0_mtc0(6,3,x)
+#define mips32_xchsrsconf2(x)	        _m32c0_mxc0(6,3,x)
+
+#define mips32_getsrsconf3()	        _m32c0_mfc0(6,4)
+#define mips32_setsrsconf3(x)	        _m32c0_mtc0(6,4,x)
+#define mips32_xchsrsconf3(x)	        _m32c0_mxc0(6,4,x)
+
+#define mips32_getsrsconf4()	        _m32c0_mfc0(6,5)
+#define mips32_setsrsconf4(x)	        _m32c0_mtc0(6,5,x)
+#define mips32_xchsrsconf4(x)	        _m32c0_mxc0(6,5,x)
+
+#if !__mips16
+/* Access to other VPE/TC registers */
+
+/* move from gpr */
+#define _m32c0_mftgpr(rt) \
+__extension__ ({ \
+	unsigned long __res; \
+	__asm__ __volatile__( \
+		".set push\n" \
+		".set noat\n" \
+		"mftgpr\t%0,$" #rt "\n" \
+		".set pop\n" \
+		: "=d" (__res)); \
+	__res; \
+})
+
+/* move to gpr */
+#define _m32c0_mttgpr(rd,v) \
+do { \
+	__asm__ __volatile__( \
+		".set push\n" \
+		".set noat\n" \
+		"mttgpr\t%z0,$" #rd "\n" \
+		".set pop\n" \
+		: : "dJ" (v)); \
+} while (0)
+
+/* move from cp0 */
+#define _m32c0_mftc0(rt,sel) \
+__extension__ ({ \
+	unsigned long  __res; \
+	__asm__ __volatile__( \
+		"mftc0\t%0,$" #rt "," #sel \
+		: "=d" (__res)); \
+	__res; \
+})
+
+/* move to cp0 */
+#define _m32c0_mttc0(rd,sel,v) \
+do { \
+	__asm__ __volatile__( \
+		"%(mttc0\t %z0,$" #rd "," #sel "; ehb%)" \
+		: : "dJ" (v)); \
+} while (0)
+#endif /* ! __mips16 */
+
+/*
+ * targeted VPE register macros
+ */
+#define mips32_mt_settarget(tc) \
+	mips32_setvpecontrol ( \
+		(mips32_getvpecontrol () & ~(VPECONTROL_TARGTC)) \
+		| ((tc) << VPECONTROL_TARGTC_SHIFT))
+
+#define mips32_mt_gettarget() \
+	((mips32_getvpecontrol () & (VPECONTROL_TARGTC)) \
+	 >> VPECONTROL_TARGTC_SHIFT)
+
+/*
+ * Before using any mips32_mt_ macros you should ensure the
+ * destination VPE and TC are set with a call to mips32_mt_settarget()
+ */
+
+/*
+ * Non-MT CP0 registers
+ */
+#define mips32_mt_getc0status()		_m32c0_mftc0(12, 0)
+#define mips32_mt_setc0status(val)	_m32c0_mttc0(12, 0, val)
+#define mips32_mt_getc0cause()		_m32c0_mftc0(13, 0)
+#define mips32_mt_setc0cause(val)	_m32c0_mttc0(13, 0, val)
+#define mips32_mt_getc0config()		_m32c0_mftc0(16, 0)
+#define mips32_mt_setc0config(val)	_m32c0_mttc0(16, 0, val)
+#define mips32_mt_getc0config1()	_m32c0_mftc0(16, 1)
+#define mips32_mt_setc0config1(val) 	_m32c0_mttc0(16, 1, val)
+#define mips32_mt_getc0ebase()		_m32c0_mftc0(15, 1)
+#define mips32_mt_setc0ebase(val)	_m32c0_mttc0(15, 1, val)
+
+/*
+ * Non-MT GPR registers
+ */
+#define mips32_mt_getsp()		_m32c0_mftgpr(29)
+#define mips32_mt_setsp(val)		_m32c0_mttgpr(29, val)
+#define mips32_mt_getgp()		_m32c0_mftgpr(28)
+#define mips32_mt_setgp(val)		_m32c0_mttgpr(28, val)
+
+/*
+ * VPE
+ */
+#define mips32_mt_getvpecontrol()	_m32c0_mftc0(1, 1)
+#define mips32_mt_setvpecontrol(val)	_m32c0_mttc0(1, 1, val)
+#define mips32_mt_getvpeconf0()		_m32c0_mftc0(1, 2)
+#define mips32_mt_setvpeconf0(val)	_m32c0_mttc0(1, 2, val)
+
+/*
+ * TC
+ */
+#define mips32_mt_gettcstatus() 	_m32c0_mftc0(2, 1)
+#define mips32_mt_settcstatus(val)	_m32c0_mttc0(2, 1, val)
+#define mips32_mt_gettcbind()		_m32c0_mftc0(2, 2)
+#define mips32_mt_settcbind(val)	_m32c0_mttc0(2, 2, val)
+#define mips32_mt_gettcrestart()	_m32c0_mftc0(2, 3)
+#define mips32_mt_settcrestart(val)	_m32c0_mttc0(2, 3, val)
+#define mips32_mt_gettchalt()		_m32c0_mftc0(2, 4)
+#define mips32_mt_settchalt(val)	_m32c0_mttc0(2, 4, val)
+#define mips32_mt_gettccontext()	_m32c0_mftc0(2, 5)
+#define mips32_mt_settccontext(val)	_m32c0_mttc0(2, 5, val)
+
+
+/*
+ * MT Intrinsics
+ */
+#define mips_mt_fork(a, pv, cv)					\
+__extension__ ({						\
+    void * __a = (a);						\
+    unsigned int __cv = (cv);					\
+    unsigned int __res = (pv); 					\
+    __asm__ __volatile (".set push; .set mt; fork %0,%1,%z2; .set pop" \
+			: "+d" (__res)				\
+			: "d" (__a), "dJ" (__cv));		\
+    __res; 							\
+})
+
+#define mips_mt_yield(yq)					\
+__extension__ ({						\
+    unsigned int __yq = (yq);					\
+    unsigned int __res; 					\
+    __asm__ __volatile (".set push; .set mt; yield %0,%z1; .set pop" \
+			: "=d" (__res)				\
+			: "dJ" (__yq));				\
+    __res; 							\
+})
+
+#define mips_mt_dmt() 						\
+__extension__ ({						\
+    unsigned int __res; 					\
+    __asm__ __volatile (".set push; .set mt; dmt %0; .set pop"	\
+			: "=d" (__res));			\
+    mips32_jr_hb();						\
+    __res & VPECONTROL_TE;					\
+})
+
+#define mips_mt_emt() 						\
+__extension__ ({						\
+    unsigned int __res; 					\
+    __asm__ __volatile (".set push; .set mt; emt %0; ehb; .set pop" \
+			: "=d" (__res));			\
+    __res & VPECONTROL_TE;					\
+})
+
+#define mips_mt_dvpe() 						\
+__extension__ ({						\
+    unsigned int __res; 					\
+    __asm__ __volatile (".set push; .set mt; dvpe %0; .set pop"	\
+			: "=d" (__res));			\
+    mips32_jr_hb();						\
+    __res & MVPCONTROL_EVP;					\
+})
+
+#define mips_mt_evpe() 						\
+__extension__ ({						\
+    unsigned int __res; 					\
+    __asm__ __volatile (".set push; .set mt; evpe %0; ehb; .set pop" \
+			: "=d" (__res));			\
+    __res & MVPCONTROL_EVP;					\
+})
+
+#endif /* __ASSEMBLER__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MIPS_MT_H_ */
diff --git a/libgloss/mips/include/mips/notlb.h b/libgloss/mips/include/mips/notlb.h
new file mode 100644
index 000000000..53565a1d8
--- /dev/null
+++ b/libgloss/mips/include/mips/notlb.h
@@ -0,0 +1,113 @@ 
+/*
+ * 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 _NOTLB_H_
+#define _NOTLB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ROM_BASE
+#define ROM_BASE	0xbfc00000	/* standard ROM base address */
+#endif
+
+#ifdef __ASSEMBLER__
+
+/*
+ * Stub 32-bit memory regions
+ */
+#define	KSEG0_BASE	0x80000000
+#define	KSEG1_BASE	0xa0000000
+#define KSEG0_SIZE	0x20000000
+#define KSEG1_SIZE	0x20000000
+#define RVEC_BASE	ROM_BASE
+
+/*
+ * Translate a kernel address in KSEG0 or KSEG1 to a real
+ * physical address and back.
+ */
+#define KVA_TO_PA(v) 	((v) & 0x1fffffff)
+#define PA_TO_KVA0(pa)	((pa) | 0x80000000)
+#define PA_TO_KVA1(pa)	((pa) | 0xa0000000)
+
+/* translate between KSEG0 and KSEG1 addresses */
+#define KVA0_TO_KVA1(v)	((v) | 0x20000000)
+#define KVA1_TO_KVA0(v)	((v) & ~0x20000000)
+
+#else /* __ASSEMBLER__ */
+/*
+ * Standard address types
+ */
+#ifndef _PADDR_T_DEFINED_
+typedef unsigned long		paddr_t;	/* a physical address */
+#define _PADDR_T_DEFINED_
+#endif
+#ifndef _VADDR_T_DEFINED_
+typedef unsigned long		vaddr_t;	/* a virtual address */
+#define _VADDR_T_DEFINED_
+#endif
+
+/*
+ * Stub 32-bit memory regions
+ */
+#define KSEG0_BASE	((void  *)0x80000000)
+#define KSEG1_BASE	((void  *)0xa0000000)
+#define KSEG0_SIZE	0x20000000u
+#define KSEG1_SIZE	0x20000000u
+
+#define RVEC_BASE	((void *)ROM_BASE)	/* reset vector base */
+
+/*
+ * Translate a kernel virtual address in KSEG0 or KSEG1 to a real
+ * physical address and back.
+ */
+#define KVA_TO_PA(v) 	((paddr_t)(v) & 0x1fffffff)
+#define PA_TO_KVA0(pa)	((void *) ((pa) | 0x80000000))
+#define PA_TO_KVA1(pa)	((void *) ((pa) | 0xa0000000))
+
+/* translate between KSEG0 and KSEG1 virtual addresses */
+#define KVA0_TO_KVA1(v)	((void *) ((unsigned)(v) | 0x20000000))
+#define KVA1_TO_KVA0(v)	((void *) ((unsigned)(v) & ~0x20000000))
+
+/* Test for KSEGS */
+#define IS_KVA(v)	((int)(v) < 0)
+#define IS_KVA0(v)	(((unsigned)(v) >> 29) == 0x4)
+#define IS_KVA1(v)	(((unsigned)(v) >> 29) == 0x5)
+#define IS_KVA01(v)	(((unsigned)(v) >> 30) == 0x2)
+
+/* convert register type to address and back */
+#define VA_TO_REG(v)	((long)(v))		/* sign-extend 32->64 */
+#define REG_TO_VA(v)	((void *)(long)(v))	/* truncate 64->32 */
+
+#endif /* __ASSEMBLER__ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _NOTLB_H_*/
diff --git a/libgloss/mips/include/mips/prid.h b/libgloss/mips/include/mips/prid.h
new file mode 100644
index 000000000..96ae39734
--- /dev/null
+++ b/libgloss/mips/include/mips/prid.h
@@ -0,0 +1,128 @@ 
+/*
+ * 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 _MIPS_PRID_H_
+#define _MIPS_PRID_H_
+
+/*
+ * MIPS CPU types
+ */
+#define	PRID_R2000	0x01	/* MIPS R2000 CPU		ISA I   */
+#define	PRID_R3000	0x02	/* MIPS R3000 CPU		ISA I   */
+#define	PRID_R6000	0x03	/* MIPS R6000 CPU		ISA II	*/
+#define	PRID_R4000	0x04	/* MIPS R4000/4400 CPU		ISA III	*/
+#define PRID_LR33K	0x05	/* LSI Logic R3000 derivate	ISA I	*/
+#define	PRID_R6000A	0x06	/* MIPS R6000A CPU		ISA II	*/
+#define	PRID_R3IDT	0x07	/* IDT R3000 derivates		ISA I	*/
+#define	 PRID_R3IDT_R3041  0x07	  /* R3041 (cp_rev field) */
+#define	 PRID_R3IDT_R36100 0x10	  /* R36100 (cp_rev field) */
+#define	PRID_R10000	0x09	/* MIPS R10000/T5 CPU		ISA IV  */
+#define	PRID_R4200	0x0a	/* MIPS R4200 CPU (ICE)		ISA III */
+#define PRID_R4300	0x0b	/* NEC VR4300 CPU		ISA III */
+#define PRID_R4100	0x0c	/* NEC VR4100 CPU		ISA III */
+#define	PRID_R8000	0x10	/* MIPS R8000 Blackbird/TFP	ISA IV  */
+#define	PRID_RC6457X	0x15	/* IDT RC6457X CPU		ISA IV  */
+#define	PRID_RC3233X	0x18	/* IDT RC3233X CPU		ISA MIPS32 */
+#define	PRID_R4600	0x20	/* QED R4600 Orion		ISA III */
+#define	PRID_R4700	0x21	/* QED R4700 Orion		ISA III */
+#define	PRID_R3900	0x22	/* Toshiba/Philips R3900 CPU	ISA I	*/
+#define	PRID_R4650	0x22	/* QED R4650/R4640 CPU		ISA III */
+#define	PRID_R5000	0x23	/* MIPS R5000 CPU		ISA IV  */
+#define	PRID_RC3236X	0x26	/* IDT RC3236X CPU		ISA MIPS32 */
+#define	PRID_RM7000	0x27	/* QED RM7000 CPU		ISA IV  */
+#define	PRID_RM52XX	0x28	/* QED RM52XX CPU		ISA IV  */
+#define	PRID_RC6447X	0x30	/* IDT RC6447X CPU		ISA III */
+#define	PRID_R5400	0x54	/* NEC Vr5400 CPU		ISA IV  */
+#define	PRID_R5500	0x55	/* NEC Vr5500 CPU		ISA IV  */
+#define PRID_JADE	0x80	/* MIPS Jade (obsolete name)	ISA MIPS32 */
+#define PRID_4KC	0x80	/* MIPS 4Kc (TLB)		ISA MIPS32 */
+#define PRID_5KC	0x81	/* MIPS 5Kc			ISA MIPS64 */
+#define PRID_20KC	0x82	/* MIPS 20Kc			ISA MIPS64 */
+#define PRID_4KMP	0x83	/* MIPS 4Kp/4Km (FM)		ISA MIPS32 */
+#define PRID_4KEC	0x84	/* MIPS 4KEc (TLB)		ISA MIPS32 */
+#define PRID_4KEMP	0x85	/* MIPS 4KEm/4KEp (FM)		ISA MIPS32 */
+#define PRID_4KSC	0x86	/* MIPS 4KSc 			ISA MIPS32 */
+#define PRID_M4K	0x87	/* MIPS M4K			ISA MIPS32r2 */
+#define PRID_25KF	0x88	/* MIPS 25Kf			ISA MIPS64 */
+#define PRID_5KE	0x89	/* MIPS 5KE			ISA MIPS64r2 */
+#define PRID_4KEC_R2	0x90	/* MIPS 4KEc (TLB)		ISA MIPS32r2 */
+#define PRID_4KEMP_R2	0x91	/* MIPS 4KEm/4KEp (FM)		ISA MIPS32r2 */
+#define PRID_4KSD	0x92	/* MIPS 4KSd			ISA MIPS32r2 */
+#define PRID_24K	0x93	/* MIPS 24K			ISA MIPS32r2 */
+#define PRID_34K	0x95	/* MIPS 34K			ISA MIPS32r2 */
+#define PRID_24KE	0x96	/* MIPS 24KE			ISA MIPS32r2 */
+#define PRID_74K	0x97	/* MIPS 74K			ISA MIPS32r2 */
+#define PRID_1004K	0x99	/* MIPS 1004K			ISA MIPS32r2 */
+#define PRID_1074K      0x9A    /* MIPS 1074K                   ISA MIPS32r2 */
+#define PRID_M14K       0x9B    /* MIPS M14K                    ISA MIPS32r2 */
+#define PRID_M14KC      0x9C    /* MIPS M14KC                   ISA MIPS32r2 */
+#define PRID_M14KE      0x9D    /* MIPS M14KE                   ISA MIPS32r2 */
+#define PRID_M14KEC     0x9E    /* MIPS M14KEC                  ISA MIPS32r2 */
+#define PRID_INTERAPTIV_UP 0xA0    /* MIPS INTERAPTIV UP        ISA MIPS32r2 */
+#define PRID_INTERAPTIV_MP 0xA1    /* MIPS INTERAPTIV MP        ISA MIPS32r2 */
+#define PRID_PROAPTIV_UP   0xA2    /* MIPS PROAPTIV UP          ISA MIPS32r2 */
+#define PRID_PROAPTIV_MP   0xA3    /* MIPS PROAPTIV MP          ISA MIPS32r2 */
+#define PRID_M5100      0xA6    /* MIPS WARRIOR M5100           ISA MIPS32r2 */
+#define PRID_M5150      0xA7    /* MIPS WARRIOR M5150           ISA MIPS32r2 */
+#define PRID_P5600      0xA8    /* MIPS WARRIOR P5600           ISA MIPS32r2 */
+#define PRID_I6400      0xA9    /* MIPS I6400                   ISA MIPS64r6 */
+
+/*
+ * MIPS FPU types
+ */
+#define	PRID_SOFT	0x00	/* Software emulation		ISA I   */
+#define	PRID_R2360	0x01	/* MIPS R2360 FPC		ISA I   */
+#define	PRID_R2010	0x02	/* MIPS R2010 FPC		ISA I   */
+#define	PRID_R3010	0x03	/* MIPS R3010 FPC		ISA I   */
+#define	PRID_R6010	0x04	/* MIPS R6010 FPC		ISA II  */
+#define	PRID_R4010	0x05	/* MIPS R4000/R4400 FPC		ISA II  */
+#define PRID_LR33010	0x06	/* LSI Logic derivate		ISA I	*/
+#define	PRID_R10010	0x09	/* MIPS R10000/T5 FPU		ISA IV  */
+#define	PRID_R4210	0x0a	/* MIPS R4200 FPC (ICE)		ISA III */
+#define PRID_UNKF1	0x0b	/* unnanounced product cpu	ISA III */
+#define	PRID_R8010	0x10	/* MIPS R8000 Blackbird/TFP	ISA IV  */
+#define	PRID_RC6457XF	0x15	/* IDT RC6457X FPU		ISA IV  */
+#define	PRID_R4610	0x20	/* QED R4600 Orion		ISA III */
+#define	PRID_R3SONY	0x21	/* Sony R3000 based FPU		ISA I   */
+#define	PRID_R3910	0x22	/* Toshiba/Philips R3900 FPU	ISA I	*/
+#define	PRID_R5010	0x23	/* MIPS R5000 FPU		ISA IV  */
+#define	PRID_RM7000F	0x27	/* QED RM7000 FPU		ISA IV  */
+#define	PRID_RM52XXF	0x28	/* QED RM52X FPU		ISA IV  */
+#define	PRID_RC6447XF	0x30	/* IDT RC6447X FPU		ISA III */
+#define	PRID_R5400F	0x54	/* NEC Vr5400 FPU		ISA IV  */
+#define	PRID_R5500F	0x55	/* NEC Vr5500 FPU		ISA IV  */
+#define PRID_20KCF	0x82	/* MIPS 20Kc FPU		ISA MIPS64 */
+#define PRID_5KF	0x81	/* MIPS 5Kf FPU			ISA MIPS64 */
+#define PRID_25KFF	0x88	/* MIPS 25Kf FPU		ISA MIPS64 */
+#define PRID_5KEF	0x89	/* MIPS 5KEf FPU		ISA MIPS64r2 */
+#define PRID_24KF	0x93	/* MIPS 24Kf FPU		ISA MIPS32r2 */
+#define PRID_34KF	0x95	/* MIPS 34K FPU			ISA MIPS32r2 */
+#define PRID_24KEF	0x96	/* MIPS 24KE FPU		ISA MIPS32r2 */
+#define PRID_74KF	0x97	/* MIPS 74K FPU			ISA MIPS32r2 */
+
+#endif /*  _MIPS_PRID_H_ */
diff --git a/libgloss/mips/include/mips/regdef.h b/libgloss/mips/include/mips/regdef.h
new file mode 100644
index 000000000..4e4f00413
--- /dev/null
+++ b/libgloss/mips/include/mips/regdef.h
@@ -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.
+*/
+
+#ifndef _MIPS_REGDEF_H_
+#define _MIPS_REGDEF_H_
+
+#define zero	$0
+
+#define AT	$1
+
+#define v0	$2
+#define v1	$3
+#define va0	$2
+#define va1	$3
+
+#define vt0	$2
+#define vt1	$3
+
+#define a0	$4
+#define a1	$5
+#define a2	$6
+#define	a3	$7
+
+#if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI
+#define a4	$8
+#define a5	$9
+#define a6	$10
+#define	a7	$11
+#define t0	$12
+#define t1	$13
+#define t2	$14
+#define t3	$15
+#define ta0	$8	/* alias for $a4 */
+#define ta1	$9	/* alias for $a5 */
+#define ta2	$10	/* alias for $a6 */
+#define ta3	$11	/* alias for $a7 */
+#else
+#define t0	$8
+#define t1	$9
+#define t2	$10
+#define t3	$11
+#define t4	$12
+#define t5	$13
+#define t6	$14
+#define t7	$15
+#define ta0	$12	/* alias for $t4 */
+#define ta1	$13	/* alias for $t5 */
+#define ta2	$14	/* alias for $t6 */
+#define ta3	$15	/* alias for $t7 */
+#endif
+
+#define s0	$16
+#define s1	$17
+#define s2	$18
+#define s3	$19
+#define s4	$20
+#define s5	$21
+#define s6	$22
+#define s7	$23
+#define s8	$30		/* == fp */
+
+#define t8	$24
+#define t9	$25
+#define k0	$26
+#define k1	$27
+
+#define gp	$28
+
+#define sp	$29
+#define fp	$30
+#define ra	$31
+
+#define r0	$0
+#define r1	$1
+#define r2	$2
+#define r3	$3
+#define r4	$4
+#define r5	$5
+#define r6	$6
+#define r7	$7
+#define r8	$8
+#define r9	$9
+#define r10	$10
+#define r11	$11
+#define r12	$12
+#define r13	$13
+#define r14	$14
+#define r15	$15
+#define r16	$16
+#define r17	$17
+#define r18	$18
+#define r19	$19
+#define r20	$20
+#define r21	$21
+#define r22	$22
+#define r23	$23
+#define r24	$24
+#define r25	$25
+#define r26	$26
+#define r27	$27
+#define r28	$28
+#define r29	$29
+#define r30	$30
+#define r31	$31
+
+#endif /*_MIPS_REGDEF_H_*/
diff --git a/libgloss/mips/include/mips/uhi_syscalls.h b/libgloss/mips/include/mips/uhi_syscalls.h
new file mode 100644
index 000000000..e4bb6cc21
--- /dev/null
+++ b/libgloss/mips/include/mips/uhi_syscalls.h
@@ -0,0 +1,68 @@ 
+/*
+ * 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 _UHI_SYSCALLS_
+#define _UHI_SYSCALLS_
+
+#define __MIPS_UHI_EXIT        1
+#define __MIPS_UHI_OPEN        2
+#define __MIPS_UHI_CLOSE       3
+#define __MIPS_UHI_READ        4
+#define __MIPS_UHI_WRITE       5
+#define __MIPS_UHI_LSEEK       6
+#define __MIPS_UHI_UNLINK      7
+#define __MIPS_UHI_FSTAT       8
+#define __MIPS_UHI_ARGC        9
+#define __MIPS_UHI_ARGLEN      10
+#define __MIPS_UHI_ARGN        11
+#define __MIPS_UHI_RAMRANGE    12
+#define __MIPS_UHI_LOG         13
+#define __MIPS_UHI_ASSERT      14
+#define __MIPS_UHI_EXCEPTION   15
+#define __MIPS_UHI_PREAD       19
+#define __MIPS_UHI_PWRITE      20
+#define __MIPS_UHI_LINK        22
+#define __MIPS_UHI_BOOTFAIL    23
+#define __MIPS_UHI_BREAK       24
+
+#define __MIPS_UHI_BF_CACHE    1
+
+#define __xstr(s) __str(s)
+#define __str(s) #s
+#define __MIPS_UHI_SYSCALL_NUM 1
+
+#ifdef __MIPS_SDBBP__
+	#define SYSCALL(NUM) "\tsdbbp " __xstr (NUM)
+	#define ASM_SYSCALL(NUM) sdbbp NUM
+#else
+	#define SYSCALL(NUM) "\tsyscall " __xstr (NUM)
+	#define ASM_SYSCALL(NUM) syscall NUM
+#endif
+
+#endif // _UHI_SYSCALLS_
diff --git a/libgloss/mips/include/mips/version.h b/libgloss/mips/include/mips/version.h
new file mode 100644
index 000000000..d2ca5679d
--- /dev/null
+++ b/libgloss/mips/include/mips/version.h
@@ -0,0 +1,4 @@ 
+/* This file just defines the current version number of MIPS HAL library.  */
+
+#define __MIPS_HAL_VERSION__ "3.0.0"
+
diff --git a/libgloss/mips/malta32-yamon.ld b/libgloss/mips/malta32-yamon.ld
new file mode 100644
index 000000000..31e077894
--- /dev/null
+++ b/libgloss/mips/malta32-yamon.ld
@@ -0,0 +1,316 @@ 
+/*
+ * A malta based target independent link script to produce UHI
+ * compliant binaries with varying levels of system initialization
+ * support.
+ */
+
+__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start;
+ENTRY(__entry)
+OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips")
+GROUP(-lc -lyamon -luhi -lgcc -lhal)
+SEARCH_DIR(.)
+
+/* Define where the yamon entry point table is */
+__yamon_functions = 0x9fc00500;
+
+__DYNAMIC  =  0;
+STARTUP(crt0.o)
+/* Force the exception handler to be registered */
+EXTERN(__register_excpt_handler)
+/* Force the exception handler to be included in the link */
+EXTERN(__exception_entry)
+/*
+ * Require verbose exceptions. This can be changed to pull in
+ * __exception_handle_quiet to reduce code size but be less
+ * informative
+ */
+EXTERN(__exception_handle_verbose)
+/* Force ISRs 0-7 to be included in the link */
+EXTERN(_isr_vec_7)
+/* Require the UHI getargs support */
+EXTERN(__getargs)
+/* Include the breakpoint exception handler.  */
+EXTERN (__uhi_break);
+
+/*
+ * Set the location of the top of the stack.  A value of 0 means
+ * that it will be automatically placed at the highest address
+ * available as described by the __memory_* setttings
+ */
+PROVIDE (__stack = 0);
+
+/* Size of the memory returned by _get_ram_range */
+PROVIDE (__memory_size = 3M);
+
+/* Base of the memory returned by _get_ram_range */
+PROVIDE (__memory_base = 0x80000000);
+
+/* Stride length for tlb software invalidate for tlbinvf
+ * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
+ * differently in the index register. Either sets LSB or ways LSB.
+ *
+ * By setting this to 1 we presume that sets come first. The default boot
+ * code will decrement this value from the Number of TLB entries.
+ */
+PROVIDE (__tlb_stride_length = 1);
+
+/* By default, XPA is not used even if available. To enable XPA,
+ * __enable_xpa should be 1.
+ */
+PROVIDE (__enable_xpa = 0);
+
+/*
+ * 0 = Do not use exception handler present in boot for UHI
+ * 1 = Use exception handler present in boot for UHI if BEV is 0 at
+ *     startup
+ * 2 = Always use exception handler present in boot for UHI
+ */
+PROVIDE (__use_excpt_boot = 0);
+/*
+ * Include the code to be able to return to boot context.  This is
+ * necessary if __use_excpt_boot != 0.
+ */
+EXTERN (__register_excpt_boot);
+
+ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
+	"Registration for boot context is required for UHI chaining")
+
+/* Control if subnormal floating-point values are flushed to zero in
+   hardware.  This applies to both FPU and MSA operations.  */
+PROVIDE (__flush_to_zero = 1);
+
+/* Set up the public symbols depending on whether the user has chosen
+   quiet or verbose exception handling above */
+EXTERN (__exception_handle);
+PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
+				      ? __exception_handle_quiet
+				      : __exception_handle_verbose));
+PROVIDE(_mips_handle_exception = __exception_handle);
+
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we multiple object file
+ * formats, as some prepend an underscore.
+ */
+PROVIDE (hardware_exit_hook = 0);
+PROVIDE (hardware_hazard_hook = 0);
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+
+/* The default base address for application code is 0x80200000 which
+   leaves 2M of space at the start of KSEG0 for a bootloader. */
+PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000);
+/* Set default vector spacing to 32 bytes. */
+PROVIDE (__isr_vec_space = 32);
+/* Leave space for 9 vector entries by default. 8 entry points and one
+   fallback handler. */
+PROVIDE (__isr_vec_count = 9);
+/*
+ * The start of flash must be set if including boot code.  By default
+ * the use of boot code will mean that application code is copied
+ * from flash to RAM at runtime before being executed.
+ */
+PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 : __app_start);
+
+SECTIONS
+{
+  /* Start of bootrom */
+  .bootrom 0x9fc00000 : /* Runs uncached (from 0x9fc00000) until I$ is
+			   initialized. */
+  AT (__flash_start)
+  {
+    *(.reset)		/* Reset entry point. */
+    *(.boot)		/* Boot code. */
+    . = ALIGN(8);
+  } = 0
+
+  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
+
+  /* Start of the application */
+  .exception_vector ALIGN(__app_start, 0x1000) :
+  AT (__flash_app_start)
+  {
+    __excpt_ebase = ABSOLUTE(.);
+    __base = .;
+    KEEP(* (.text.__exception_entry))
+    . = __base + 0x200;
+    KEEP(* (SORT(.text.__isr_vec*)))
+    /* Leave space for all the vector entries */
+    . = __base + 0x200 + (__isr_vec_space * __isr_vec_count);
+    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
+			       ? __isr_vec_sw1 - __isr_vec_sw0
+			       : __isr_vec_space),
+	   "Actual ISR vector spacing does not match __isr_vec_space");
+    ASSERT(__base + 0x200 == (DEFINED(__isr_vec_sw0)
+			      ? __isr_vec_sw0 & 0xfffffffe : __base + 0x200),
+	   "__isr_vec_sw0 is not placed at EBASE + 0x200");
+    . = ALIGN(8);
+  } = 0
+
+  .text : {
+     _ftext = . ;
+    PROVIDE (eprol  =  .);
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.mips16.fn.*)
+    *(.mips16.call.*)
+  }
+  .init : {
+    KEEP (*(.init))
+  }
+  .fini : {
+    KEEP (*(.fini))
+  }
+  .rel.sdata : {
+    PROVIDE (__runtime_reloc_start = .);
+    *(.rel.sdata)
+    PROVIDE (__runtime_reloc_stop = .);
+  }
+  PROVIDE (etext  =  .);
+  _etext  =  .;
+
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame : { KEEP (*(.eh_frame)) }
+  .gcc_except_table : { *(.gcc_except_table) }
+  .jcr : { KEEP (*(.jcr)) }
+  .ctors    :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+
+    KEEP (*crtbegin.o(.ctors))
+
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+
+  .dtors    :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+
+  . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
+  .rodata : {
+    *(.rdata)
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r.*)
+  }
+   . = ALIGN(16);
+   _fdata = .;
+  .data : {
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d.*)
+  }
+  . = ALIGN(8);
+  MIPS_REVISION = DEFINED (__mips_isa_rev) ? ABSOLUTE(__mips_isa_rev) : 0;
+  GP_OFFSET = (MIPS_REVISION < 7) ? 0x8000 : 0;
+  _gp = . + GP_OFFSET;
+  __global = _gp;
+  .lit8 : {
+    *(.lit8)
+  }
+  .lit4 : {
+    *(.lit4)
+  }
+  .sdata : {
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s.*)
+  }
+  . = ALIGN(4);
+  PROVIDE (edata  =  .);
+  _edata  =  .;
+  _fbss = .;
+  .sbss : {
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  .bss : {
+    _bss_start = . ;
+    *(.bss)
+    *(.bss.*)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+  }
+
+  . = ALIGN(4);
+  PROVIDE (end = .);
+  _end = .;
+  /* Now place the data that is only needed within start.S and can be
+     overwritten by the heap.  */
+  .startdata : {
+    *(.startdata)
+  }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+
+  /* Special sections generated by gcc */
+  /* Newer GNU linkers strip by default */
+  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
+  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
+  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
+  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
+  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
+  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
+  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
+  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
+}
diff --git a/libgloss/mips/mti32.ld b/libgloss/mips/mti32.ld
index 3c8daf6f1..9e2b18fb5 100644
--- a/libgloss/mips/mti32.ld
+++ b/libgloss/mips/mti32.ld
@@ -3,7 +3,6 @@ 
    the simulator.  */
 
 ENTRY(_start)
-OUTPUT_ARCH("mips:isa32r2")
 OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips")
 GROUP(-lc -lidt -lgcc)
 SEARCH_DIR(.)
diff --git a/libgloss/mips/mti64.ld b/libgloss/mips/mti64.ld
index 74d778412..af35af5c6 100644
--- a/libgloss/mips/mti64.ld
+++ b/libgloss/mips/mti64.ld
@@ -5,7 +5,6 @@ 
    each other (e.g., MIPS32r2 and MIPS64).  */
 
 ENTRY(_start)
-OUTPUT_ARCH("mips:isa64r2")
 OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips")
 GROUP(-lc -lidt -lgcc)
 SEARCH_DIR(.)
diff --git a/libgloss/mips/mti64_n32.ld b/libgloss/mips/mti64_n32.ld
index 5098a88d0..47b26f800 100644
--- a/libgloss/mips/mti64_n32.ld
+++ b/libgloss/mips/mti64_n32.ld
@@ -8,7 +8,6 @@ 
    o32 ABI targets in OUTPUT_FORMAT.  */
 
 ENTRY(_start)
-OUTPUT_ARCH("mips:isa64r2")
 OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips", "elf32-ntradlittlemips")
 GROUP(-lc -lidt -lgcc)
 SEARCH_DIR(.)
diff --git a/libgloss/mips/regs.S b/libgloss/mips/regs.S
index e4b134307..ac2935465 100644
--- a/libgloss/mips/regs.S
+++ b/libgloss/mips/regs.S
@@ -98,7 +98,10 @@ 
 #define SR_SX		0x00000040	/* Supervisor extended addressing enabled */
 #define SR_UX		0x00000020	/* User extended addressing enabled */
 
-#define SR_MSA		0x08000000	/* MSA ASE */
+#define SR_IE		0x00000001	/* Interrupt enable */
+
+#define SR_MX		0x01000000	/* MDMX or DSP ASE */
+#define CFG5_MSAEN	0x08000000	/* MSA ASE */
 
 /* Standard (R4000) cache operations. Taken from "MIPS R4000
    Microprocessor User's Manual" 2nd edition: */
diff --git a/libgloss/mips/syscalls.c b/libgloss/mips/syscalls.c
deleted file mode 100644
index 3ab543674..000000000
--- a/libgloss/mips/syscalls.c
+++ /dev/null
@@ -1,45 +0,0 @@ 
-#include <_ansi.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "regs.S"
-
-extern char _end[];
-
-/* FIXME: This is not ideal, since we do a get_mem_info() call for
-   every sbrk() call. */
-char *
-sbrk (nbytes)
-     int nbytes;
-{
-  static char *heap_ptr = _end;
-  static char *heap_start = _end;
-  char        *base;
-  struct s_mem {
-    unsigned int size;
-    unsigned int icsize;
-    unsigned int dcsize;
-  } mem;
-  unsigned int avail = 0;
-
-  /* The sizeof (s_mem.size) must be 4 bytes.  The compiler should be
-     able to eliminate this check */
-  if (sizeof (unsigned int) != 4)
-    return (char *)-1;
-
-  get_mem_info(&mem);
-  /* NOTE: The value returned from the get_mem_info call is the amount
-     of memory, and not the address of the (last byte + 1) */
-
-  if (((size_t)heap_ptr >= heap_start) && ((size_t)heap_ptr < (heap_start + mem.size))) {
-    avail = (heap_start + mem.size) - (size_t)heap_ptr;
-    base = heap_ptr;
-  } /* else will fail since "nbytes" will be greater than zeroed "avail" value */
-
-  if ((nbytes > avail) || (heap_ptr + nbytes < _end))
-   base = (char *)-1;
-  else
-   heap_ptr += nbytes;
-
-  return base;
-}
diff --git a/libgloss/mips/test.c b/libgloss/mips/test.c
index a99347914..0cdf7803c 100644
--- a/libgloss/mips/test.c
+++ b/libgloss/mips/test.c
@@ -1,4 +1,7 @@ 
-main()
+void outbyte (char);
+void print (char *);
+
+int main (void)
 {
   outbyte ('&');
   outbyte ('@');
@@ -9,5 +12,5 @@  main()
   
   print ("\r\nDone...");
 
-  return;
+  return 0;
 }
diff --git a/libgloss/mips/uhi/uhi_assert.c b/libgloss/mips/uhi/uhi_assert.c
new file mode 100644
index 000000000..ff414a9dc
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_assert.c
@@ -0,0 +1,73 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     void __assert_func (const char *filename, int32_t line_num,
+ *				     const char *func, const char *expr);
+ *
+ *		 Parameters:
+ *		   filename - Name of the file
+ *		   line_num - Line number
+ *		   func - Name of the function
+ *		   expr - Expression
+ *
+ *		 Return:
+ *		   None
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for __assert_func
+ *		   $4 - Name of the file
+ *		   $5 - Line number
+ *		   $6 - Name of the function
+ *		   $7 - Expression
+ *
+ *		 Return from syscall:
+ *		   None
+ *
+ * @Description  Assert
+*/
+
+#include <stdint.h>
+#include <mips/hal.h>
+#include <mips/uhi_syscalls.h>
+
+void _MIPS_HAL_NOMIPS16
+__uhi_assert (const char *message, const char *filename, int32_t line_num)
+{
+  register const char *arg1 asm ("$4") = message;
+  register const char *arg2 asm ("$5") = filename;
+  register int32_t arg3 asm ("$6") = line_num;
+  register int32_t op asm ("$25") = __MIPS_UHI_ASSERT;
+  register int32_t ret1 asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t ret2 asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # __assert_func(%0, %1, %2, %3, %4, %5) op=%6\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret1), "+r" (ret2), "+r" (arg1), "+r" (arg2)
+			: "r" (arg3), "r" (op));
+}
diff --git a/libgloss/mips/uhi/uhi_break.c b/libgloss/mips/uhi/uhi_break.c
new file mode 100644
index 000000000..305825c25
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_break.c
@@ -0,0 +1,62 @@ 
+/*
+ * Copyright (C) 2017-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.
+*/
+
+/*
+ * @Synopsis     int __uhi_break (struct gp_ctx *ctx);
+ *
+ *               Parameters:
+ *                 $4 - GP context
+ *
+ *               Arguments to break:
+ *                 $25 - Operation code for __uhi_break
+ *                 $4 - GP context
+ *
+ *               Return from break:
+ *                 $2 - Return 1 if breakpoint exception is handled else 0
+ *
+ * @Description  Handle a breakpoint exception
+*/
+
+#include <stdint.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+/* Forward a breakpoint exception to boot.  */
+int _MIPS_HAL_NOMIPS16
+__uhi_break (struct gpctx *ctx)
+{
+  register struct gpctx *arg1 asm ("$4") = ctx;
+  register int32_t op asm ("$25") = __MIPS_UHI_BREAK;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+
+  __asm__ __volatile__ (" # %0 = __uhi_break(%1) op=%2\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret)
+			: "r" (arg1), "r" (op));
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_close.c b/libgloss/mips/uhi/uhi_close.c
new file mode 100644
index 000000000..a95b39936
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_close.c
@@ -0,0 +1,71 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 close
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for close
+ *		   $4 - File handle
+ *
+ *		 Return from syscall:
+ *		   $2 - 0 on success else -1
+ *		   $3 - errno
+ *
+ * @Description  File close
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int _MIPS_HAL_NOMIPS16
+close (int fd)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register int32_t op asm ("$25") = __MIPS_UHI_CLOSE;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = close(%2) op=%3\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1)
+			: "r" (op)
+			: "$5");
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+         clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_exception.c b/libgloss/mips/uhi/uhi_exception.c
new file mode 100644
index 000000000..857442c6b
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_exception.c
@@ -0,0 +1,63 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     int __uhi_exception (struct gp_ctx *ctx);
+ *
+ *               Parameters:
+ *                 $4 - GP context
+ *
+ *               Arguments to syscall:
+ *                 $25 - Operation code for __uhi_exception
+ *                 $4 - GP context
+ *
+ *               Return from syscall:
+ *                 $2 - 
+ *
+ * @Description  Handle an unhandled exception
+*/
+
+#include <stdint.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int32_t _MIPS_HAL_NOMIPS16
+__uhi_exception (struct gpctx *ctx, int32_t abi)
+{
+  register struct gpctx *arg1 asm ("$4") = ctx;
+  register int32_t arg2 asm ("$5") = abi;
+  register int32_t op asm ("$25") = __MIPS_UHI_EXCEPTION;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+
+  __asm__ __volatile__ (" # %0 = __uhi_exception(%1, %2) op=%3\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret)
+			: "r" (arg1), "r" (arg2), "r" (op)
+			: "$3");
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_exit.c b/libgloss/mips/uhi/uhi_exit.c
new file mode 100644
index 000000000..5d4384e8f
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_exit.c
@@ -0,0 +1,87 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 void __exit (int32_t exit_code);
+ *
+ *		 Parameters:
+ *		   exit_code - Exit code
+ *
+ *		 Return:
+ *		   None
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for exit
+ *		   $4 - Exit code
+ *
+ * @Description  Transfer control to the debug port
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+void __return_to_boot (int32_t exit_code) __attribute__((noreturn))
+  __attribute__((weak));
+
+/* Defined in .ld file */
+extern char __use_excpt_boot[];
+
+/* _exit has been declared weak to allow its defination in the application */
+int _MIPS_HAL_NOMIPS16
+__exit (int exit_code)
+{
+  register int32_t arg1 asm ("$4") = exit_code;
+  register int32_t op asm ("$25") = __MIPS_UHI_EXIT;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+
+  __asm__ __volatile__ (" # _exit(%0 %1) op=%2\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "+r" (arg1)
+			: "r" (op)
+			: "$3", "$5");
+
+  /* exit wasn't handled, return to caller of _start 
+   * __use_excpt_boot has following values
+   * 0 = Do not use exception handler present in boot
+   * 1 = Use exception handler present in boot if BEV 
+	 is 0 at startup
+   * 2 = Always use exception handler present in boot
+  */
+  if (((long) __use_excpt_boot == 2
+       || ((long) __use_excpt_boot == 1
+	   && __get_startup_BEV
+	   && __get_startup_BEV () == 0))
+      && __return_to_boot)
+    __return_to_boot (exit_code);
+
+  /* Infinite loop if control returns.  */
+  __exit (exit_code);
+  return exit_code;
+}
diff --git a/libgloss/mips/uhi/uhi_fstat.c b/libgloss/mips/uhi/uhi_fstat.c
new file mode 100644
index 000000000..6bbe53a1b
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_fstat.c
@@ -0,0 +1,159 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 int32_t fstat (int32_t file, struct stat *sbuf);
+ *
+ *		 Parameters:
+ *		   file - File handle
+ *		   sbuf - Pointer to dst buffer
+ *
+ *		 Return:
+ *		   0 on success else -1
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for fstat
+ *		   $4 - File handle
+ *		   $5 - Pointer to dst buffer (struct stat *)
+ *
+ *		 Return from syscall:
+ *		   $2 - 0 on success else -1
+ *		   $3 - errno
+ *
+ * @Description  File statistics
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stddef.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+#include "uhi_stat.h"
+
+/* This macro declares a dummy type with -ve size if CONDITION is false */
+#define __paste(STR1, STR2) STR1##STR2
+#define __check(LINE, CONDITION) typedef char __paste(assertion_failed_at_line_, LINE) [(int)(CONDITION)-1]
+
+int _MIPS_HAL_NOMIPS16
+fstat (int file, struct stat *sbuf)
+{
+  struct uhi_stat hbuf = {0,};
+  register int32_t arg1 asm ("$4") = file;
+  register struct uhi_stat *arg2 asm ("$5") = &hbuf;
+  register int32_t op asm ("$25") = __MIPS_UHI_FSTAT;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  /*
+   * We assume that NewLib has following 'struct stat'. Any change in
+   * this structure (either offset or size) would generate a compile
+   * time error.
+  */
+#if defined (_LP64)
+  __check (__LINE__, sizeof (struct stat) == 104);
+  __check (__LINE__, offsetof (struct stat, st_dev) == 0);
+  __check (__LINE__, offsetof (struct stat, st_ino) == 2);
+  __check (__LINE__, offsetof (struct stat, st_mode) == 4);
+  __check (__LINE__, offsetof (struct stat, st_nlink) == 8);
+  __check (__LINE__, offsetof (struct stat, st_uid) == 10);
+  __check (__LINE__, offsetof (struct stat, st_gid) == 12);
+  __check (__LINE__, offsetof (struct stat, st_rdev) == 14);
+  __check (__LINE__, offsetof (struct stat, st_size) == 16);
+  __check (__LINE__, offsetof (struct stat, st_atime) == 24);
+  __check (__LINE__, offsetof (struct stat, st_spare1) == 32);
+  __check (__LINE__, offsetof (struct stat, st_mtime) == 40);
+  __check (__LINE__, offsetof (struct stat, st_spare2) == 48);
+  __check (__LINE__, offsetof (struct stat, st_ctime) == 56);
+  __check (__LINE__, offsetof (struct stat, st_spare3) == 64);
+  __check (__LINE__, offsetof (struct stat, st_blksize) == 72);
+  __check (__LINE__, offsetof (struct stat, st_blocks) == 80);
+  __check (__LINE__, offsetof (struct stat, st_spare4) == 88);
+#else
+  __check (__LINE__, sizeof (struct stat) == 60);
+  __check (__LINE__, offsetof (struct stat, st_dev) == 0);
+  __check (__LINE__, offsetof (struct stat, st_ino) == 2);
+  __check (__LINE__, offsetof (struct stat, st_mode) == 4);
+  __check (__LINE__, offsetof (struct stat, st_nlink) == 8);
+  __check (__LINE__, offsetof (struct stat, st_uid) == 10);
+  __check (__LINE__, offsetof (struct stat, st_gid) == 12);
+  __check (__LINE__, offsetof (struct stat, st_rdev) == 14);
+  __check (__LINE__, offsetof (struct stat, st_size) == 16);
+  __check (__LINE__, offsetof (struct stat, st_atime) == 20);
+  __check (__LINE__, offsetof (struct stat, st_spare1) == 24);
+  __check (__LINE__, offsetof (struct stat, st_mtime) == 28);
+  __check (__LINE__, offsetof (struct stat, st_spare2) == 32);
+  __check (__LINE__, offsetof (struct stat, st_ctime) == 36);
+  __check (__LINE__, offsetof (struct stat, st_spare3) == 40);
+  __check (__LINE__, offsetof (struct stat, st_blksize) == 44);
+  __check (__LINE__, offsetof (struct stat, st_blocks) == 48);
+  __check (__LINE__, offsetof (struct stat, st_spare4) == 52);
+#endif
+
+  __asm__ __volatile__ (" # %0,%1 = fstat(%2, %3) op=%4\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (op));
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+  else
+    {
+      sbuf->st_dev = hbuf.st_dev;
+      sbuf->st_ino = hbuf.st_ino;
+      sbuf->st_mode = hbuf.st_mode;
+      sbuf->st_nlink = hbuf.st_nlink;
+      sbuf->st_uid = hbuf.st_uid;
+      sbuf->st_gid = hbuf.st_gid;
+      sbuf->st_rdev = hbuf.st_rdev;
+      sbuf->st_size = (long) hbuf.st_size;
+      sbuf->st_atime = (time_t) hbuf.st_atime;
+      sbuf->st_spare1 = (long) hbuf.st_spare1;
+      sbuf->st_mtime = (time_t) hbuf.st_mtime;
+      sbuf->st_spare2 = (long) hbuf.st_spare2;
+      sbuf->st_ctime = (time_t) hbuf.st_ctime;
+      sbuf->st_spare3 = (long) hbuf.st_spare3;
+      sbuf->st_blksize = (long) hbuf.st_blksize;
+      sbuf->st_blocks = (long) hbuf.st_blocks;
+      sbuf->st_spare4[0] = (long) hbuf.st_spare4[0];
+      sbuf->st_spare4[1] = (long) hbuf.st_spare4[1];
+    }
+
+  return ret;
+}
+
+#undef __paste
+#undef __check
diff --git a/libgloss/mips/uhi/uhi_get_ram_range.c b/libgloss/mips/uhi/uhi_get_ram_range.c
new file mode 100644
index 000000000..b8d86d12c
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_get_ram_range.c
@@ -0,0 +1,62 @@ 
+/*
+ * 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.
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+extern char __attribute__((weak)) __memory_size[];
+extern char __attribute__((weak)) __memory_base[];
+
+void _MIPS_HAL_NOMIPS16
+_get_ram_range (void **ram_base, void **ram_extent)
+{
+  register int32_t op asm ("$25") = __MIPS_UHI_RAMRANGE;
+  register void* r_base asm ("$2") = (void*)__MIPS_UHI_SYSCALL_NUM;
+  register void* r_extent asm ("$3") = NULL;
+
+  if (__memory_size != NULL)
+    {
+      if (ram_base)
+	*ram_base = (void*)(unsigned long)__memory_base;
+      *ram_extent = (void*)((unsigned long)__memory_base
+			    + (unsigned long)__memory_size);
+      return;
+    }
+
+  __asm__ __volatile__ (" # %0,%1 = ramrange() op=%2\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (r_base), "=r" (r_extent)
+			: "r" (op)
+			: "$4", "$5");
+
+  if (ram_base)
+    *ram_base = r_base;
+  *ram_extent = r_extent;
+}
diff --git a/libgloss/mips/uhi/uhi_getargs.S b/libgloss/mips/uhi/uhi_getargs.S
new file mode 100644
index 000000000..e27e7ff42
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_getargs.S
@@ -0,0 +1,106 @@ 
+/*
+ * 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.
+*/
+
+#include <mips/asm.h>
+#include <mips/regdef.h>
+#include <mips/cpu.h>
+#include <mips/uhi_syscalls.h>
+
+MIPS_NOMIPS16
+
+	.text
+	.align  2
+	.globl  __getargs
+	.ent  __getargs
+	.type __getargs, @function
+__getargs:
+
+	move	t0, zero		/* argc */
+	move	t1, zero		/* argv */
+
+	li	t9, __MIPS_UHI_ARGC
+	li	vt0, __MIPS_UHI_SYSCALL_NUM
+
+	ASM_SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+
+	/* return on error (-1) */
+	blez	vt0, .Lreturn
+
+	move	t0, vt0			/* argc: number of arguments */
+	sll	t3, t0, LOG2_SZPTR	/* Multiply by size of pointer */
+	addiu	t3, t3, ALSZ		/* Round to stack alignment */
+	and	t3, t3, ALMASK
+	PTR_SUBU  sp, sp, t3		/* make room for argv */
+	move	t1, sp			/* argv */
+	move	t2, zero
+
+.Lloop:
+
+	li	t9, __MIPS_UHI_ARGLEN
+	li	vt0, __MIPS_UHI_SYSCALL_NUM
+	move	a0, t2			/* argument number */
+
+	ASM_SYSCALL (__MIPS_UHI_SYSCALL_NUM)	/* get length of arg N */
+
+	blez	vt0, .Lreturn		/* return on error */
+
+	addiu	vt0, vt0, 1
+	addiu	vt0, vt0, ALSZ
+	and	vt0, vt0, ALMASK
+	PTR_SUBU sp, sp, vt0
+	sll	t3, t2, LOG2_SZPTR
+	PTR_ADDU t3, t3, t1
+	PTR_S	sp, 0(t3)		/* argv[i] */
+
+	li	t9, __MIPS_UHI_ARGN
+	li	vt0, __MIPS_UHI_SYSCALL_NUM
+	move	a0, t2			/* argument number */
+	move	a1, sp			/* argument buffer */
+
+	ASM_SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+
+	bltz	vt0, .Lreturn		/* return on error */
+
+	addiu	t2, t2, 1
+	slt	vt0, t2, t0
+	bnez	vt0, .Lloop
+
+.Lreturn:
+	move	a0, t0
+	move	a1, t1
+
+	/* Leave 16-bytes for register arguments and up to 8 bytes for
+	   a null envp.  Round up to 32 for alignment.  */
+	PTR_SUBU sp, sp, 16+(NARGSAVE*SZARG)
+	PTR_ADDU a2, sp, (NARGSAVE*SZARG)
+	PTR_S	zero, 0(a2)
+
+	jr	$31
+
+	.end  __getargs
+	.size __getargs, .-__getargs
diff --git a/libgloss/mips/uhi/uhi_indirect.c b/libgloss/mips/uhi/uhi_indirect.c
new file mode 100644
index 000000000..c3feac29d
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_indirect.c
@@ -0,0 +1,56 @@ 
+/*
+ * 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.
+*/
+
+#include <mips/hal.h>
+
+/* Forward a UHI SYSCALL operation to SDBPP interface.  */
+int _MIPS_HAL_NOMIPS16
+__uhi_indirect (struct gpctx *ctx)
+{
+  register reg_t arg1 asm ("$4") = ctx->r[C_CTX_REGNO(4)];
+  register reg_t arg2 asm ("$5") = ctx->r[C_CTX_REGNO(5)];
+  register reg_t arg3 asm ("$6") = ctx->r[C_CTX_REGNO(6)];
+  register reg_t arg4 asm ("$7") = ctx->r[C_CTX_REGNO(7)];
+  register reg_t op asm ("$25") = ctx->r[C_CTX_REGNO(25)];
+  register reg_t ret1 asm ("$2") = 1;
+  register reg_t ret2 asm ("$3");
+
+  __asm__ __volatile__(" # UHI indirect\n"
+		       "\tsdbbp 1"
+		       : "+r" (ret1), "=r" (ret2), "+r" (arg1), "+r" (arg2)
+		       : "r" (arg3), "r" (arg4), "r" (op));
+
+  ctx->r[C_CTX_REGNO(2)] = ret1;
+  ctx->r[C_CTX_REGNO(3)] = ret2;
+  ctx->r[C_CTX_REGNO(4)] = arg1;
+  ctx->r[C_CTX_REGNO(5)] = arg2;
+  /* Handled, move on.  SYSCALL is 4-bytes in all ISAs.  */
+  ctx->epc += 4;
+
+  return 1; /* exception handled */
+}
diff --git a/libgloss/mips/uhi/uhi_link.c b/libgloss/mips/uhi/uhi_link.c
new file mode 100644
index 000000000..7eddc0606
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_link.c
@@ -0,0 +1,80 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 int32_t link (const char *oldname, const char *newname);
+ *
+ *		 Parameters:
+ *		   oldname - Name of the file to rename
+ *		   newname - New file name
+ *
+ *		 Return:
+ *		   $2 - Zero on success or -1 in case of error
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for rename
+ *		   $4 - Name of the file to rename
+ *		   $5 - New file name
+ *
+ *		 Return from syscall:
+ *		   $2 - Zero on success or -1 in case of error
+ *		   $3 - errno
+ *
+ * @Description  Rename a file
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int _MIPS_HAL_NOMIPS16
+link (const char *oldname, const char *newname)
+{
+  register const char *arg1 asm ("$4") = oldname;
+  register const char *arg2 asm ("$5") = newname;
+  register int32_t op asm ("$25") = __MIPS_UHI_LINK;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = link(%2, %3) op=%4\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (op));
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_lseek.c b/libgloss/mips/uhi/uhi_lseek.c
new file mode 100644
index 000000000..0146843e4
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_lseek.c
@@ -0,0 +1,76 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 lseek
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for seek
+ *		   $4 - File handle
+ *		   $5 - Offset
+ *		   $6 - Direction
+ *
+ *		 Return from syscall:
+ *		   $2 - New offset
+ *		   $3 - errno
+ *
+ * @Description  File seek
+*/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+off_t _MIPS_HAL_NOMIPS16
+lseek (int fd, off_t offset, int whence)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register int32_t arg2 asm ("$5") = offset;
+  register int32_t arg3 asm ("$6") = whence;
+  register int32_t op asm ("$25") = __MIPS_UHI_LSEEK;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = lseek(%2, %3, %4) op=%5\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (arg3), "r" (op));
+
+  if (ret == -1)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_open.c b/libgloss/mips/uhi/uhi_open.c
new file mode 100644
index 000000000..38bc229b6
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_open.c
@@ -0,0 +1,75 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 open
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for open
+ *		   $4 - Name of the file
+ *		   $5 - Read/Write etc. flags
+ *		   $6 - Privileges
+ *
+ *		 Return from syscall:
+ *		   $2 - File handle
+ *		   $3 - errno
+ *
+ * @Description  File open
+*/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int _MIPS_HAL_NOMIPS16
+open (const char *file_name, int flags, mode_t mode)
+{
+  register const char * arg1 asm ("$4") = file_name;
+  register int32_t arg2 asm ("$5") = flags;
+  register int32_t arg3 asm ("$6") = mode;
+  register int32_t op asm ("$25") = __MIPS_UHI_OPEN;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = open(%2, %3, %4) op=%5\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1), "+r" (arg2)
+			: "r" (arg3), "r" (op));
+
+  if (ret == -1)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_plog.c b/libgloss/mips/uhi/uhi_plog.c
new file mode 100644
index 000000000..c0376c0bb
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_plog.c
@@ -0,0 +1,79 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 int32_t plog (int8_t *fmt, int32_t num);
+ *
+ *		 Parameters:
+ *		   fmt - Format string
+ *		   num - The only int argument
+ *
+ *		 Return:
+ *		   Number of chars written
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for __plog
+ *		   $4 - Format string
+ *		   $5 - The only int argument
+ *
+ *		 Return from syscall:
+ *		   $2 - Number of chars written
+ *		   $3 - errno
+ *
+ * @Description  Print information
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/hal.h>
+#include <mips/uhi_syscalls.h>
+
+int32_t _MIPS_HAL_NOMIPS16
+__plog (int8_t *fmt, int32_t num)
+{
+  register int8_t *arg1 asm ("$4") = fmt;
+  register int32_t arg2 asm ("$5") = num;
+  register int32_t op asm ("$25") = __MIPS_UHI_LOG;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = __plog(%2, %3) op=%4\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1), "+r" (arg2)
+			: "r" (op));
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_pread.c b/libgloss/mips/uhi/uhi_pread.c
new file mode 100644
index 000000000..814de0355
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_pread.c
@@ -0,0 +1,78 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 pread
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for pread
+ *		   $4 - File handle
+ *		   $5 - Destination buffer
+ *		   $6 - Max number of bytes to read
+ *		   $7 - Offset in file from which bytes to be read
+ *
+ *		 Return from syscall:
+ *		   $2 - Number of bytes read or -1 in case of error
+ *		   $3 - errno
+ *
+ * @Description  File read from a given offset
+*/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+ssize_t _MIPS_HAL_NOMIPS16
+pread (int fd, void *buf, size_t count, off_t offset)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register void *arg2 asm ("$5") = buf;
+  register int32_t arg3 asm ("$6") = count;
+  register int32_t arg4 asm ("$7") = offset;
+  register int32_t op asm ("$25") = __MIPS_UHI_PREAD;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = pread(%2, %3, %4, %5) op=%6\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (arg3), "r" (arg4), "r" (op));
+
+  if (ret == -1)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_pwrite.c b/libgloss/mips/uhi/uhi_pwrite.c
new file mode 100644
index 000000000..8a1529a05
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_pwrite.c
@@ -0,0 +1,78 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 pwrite
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for pwrite
+ *		   $4 - File handle
+ *		   $5 - Buffer to write
+ *		   $6 - Length of the buffer
+ *		   $7 - Offset in file at which bytes to be written
+ *
+ *		 Return from syscall:
+ *		   $2 - Number of bytes written
+ *		   $3 - errno
+ *
+ * @Description  Write to a file at a given offset
+*/
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+ssize_t _MIPS_HAL_NOMIPS16
+pwrite (int fd, const void *buf, size_t count, off_t offset)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register const void *arg2 asm ("$5") = buf;
+  register int32_t arg3 asm ("$6") = count;
+  register int32_t arg4 asm ("$7") = offset;
+  register int32_t op asm ("$25") = __MIPS_UHI_PWRITE;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = pwrite(%2, %3, %4 %5) op=%6\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (arg3), "r" (arg4), "r" (op));
+
+  if (ret == -1)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_read.c b/libgloss/mips/uhi/uhi_read.c
new file mode 100644
index 000000000..ffc017e97
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_read.c
@@ -0,0 +1,75 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 read
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for read
+ *		   $4 - File handle
+ *		   $5 - Destination buffer
+ *		   $6 - Max number of bytes to read
+ *
+ *		 Return from syscall:
+ *		   $2 - Number of bytes read
+ *		   $3 - errno
+ *
+ * @Description  File read
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int _MIPS_HAL_NOMIPS16
+read (int fd, void *buffer, size_t len)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register void *arg2 asm ("$5") = buffer;
+  register int32_t arg3 asm ("$6") = len;
+  register int32_t op asm ("$25") = __MIPS_UHI_READ;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = read(%2, %3, %4) op=%5\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (arg3), "r" (op));
+
+  if (ret == -1)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_stat.c b/libgloss/mips/uhi/uhi_stat.c
new file mode 100644
index 000000000..fd6636895
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_stat.c
@@ -0,0 +1,58 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 stat
+ *
+ * @Description  File statistics
+*/
+
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+#include "uhi_stat.h"
+
+int
+stat (const char *filename, struct stat *buf)
+{
+  int32_t fid, ret = -1;
+
+  fid = open (filename, 0, 0666); /* open in read mode */
+
+  if (fid >= 0)
+    {
+      ret = fstat (fid, buf);
+      close (fid);
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_stat.h b/libgloss/mips/uhi/uhi_stat.h
new file mode 100644
index 000000000..0bbba833a
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_stat.h
@@ -0,0 +1,51 @@ 
+/*
+ * 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.
+*/
+
+#include <stdio.h>
+#include <time.h>
+
+struct uhi_stat
+{
+  short st_dev;
+  unsigned short st_ino;
+  unsigned int st_mode;
+  unsigned short st_nlink;
+  unsigned short st_uid;
+  unsigned short st_gid;
+  short st_rdev;
+  unsigned long long st_size;
+  unsigned long long st_atime;
+  unsigned long long st_spare1;
+  unsigned long long st_mtime;
+  unsigned long long st_spare2;
+  unsigned long long st_ctime;
+  unsigned long long st_spare3;
+  unsigned long long st_blksize;
+  unsigned long long st_blocks;
+  unsigned long long st_spare4[2];
+};
diff --git a/libgloss/mips/uhi/uhi_unlink.c b/libgloss/mips/uhi/uhi_unlink.c
new file mode 100644
index 000000000..2fc323cbc
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_unlink.c
@@ -0,0 +1,77 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 int32_t unlink (const char *file);
+ *
+ *		 Parameters:
+ *		   file - Name of the file
+ *
+ *		 Return:
+ *		   0 on success else -1
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for unlink
+ *		   $4 - Name of the file
+ *
+ *		 Return from syscall:
+ *		   $2 - 0 on success else -1
+ *		   $3 - errno
+ *
+ * @Description  Unlink a file
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int _MIPS_HAL_NOMIPS16
+unlink (const char *file)
+{
+  register const char *arg1 asm ("$4") = file;
+  register int32_t op asm ("$25") = __MIPS_UHI_UNLINK;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = unlink(%2) op=%3\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1)
+			: "r" (op)
+			: "$5");
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/uhi_write.c b/libgloss/mips/uhi/uhi_write.c
new file mode 100644
index 000000000..c30202df6
--- /dev/null
+++ b/libgloss/mips/uhi/uhi_write.c
@@ -0,0 +1,75 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis	 write
+ *
+ *		 Arguments to syscall:
+ *		   $25 - Operation code for write
+ *		   $4 - File handle
+ *		   $5 - Buffer to write
+ *		   $6 - Length of the buffer
+ *
+ *		 Return from syscall:
+ *		   $2 - Number of bytes written
+ *		   $3 - errno
+ *
+ * @Description  File write
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int _MIPS_HAL_NOMIPS16
+write (int fd, const void *buf, size_t count)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register const void *arg2 asm ("$5") = buf;
+  register int32_t arg3 asm ("$6") = count;
+  register int32_t op asm ("$25") = __MIPS_UHI_WRITE;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  __asm__ __volatile__ (" # %0,%1 = write(%2, %3, %4) op=%5\n"
+			SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+			: "+r" (ret), "=r" (new_errno), "+r" (arg1),
+			  "+r" (arg2)
+			: "r" (arg3), "r" (op));
+
+  if (ret == -1)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+	 clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
diff --git a/libgloss/mips/uhi/yamon_close.c b/libgloss/mips/uhi/yamon_close.c
new file mode 100644
index 000000000..c08bd140c
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_close.c
@@ -0,0 +1,81 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     int32_t close (int32_t fd);
+ *
+ *               Parameters:
+ *                 $4 - File handle
+ *
+ *               Return:
+ *                 $2 - 0 on success else -1
+ *
+ *               Arguments to syscall:
+ *                 $25 - Operation code for close
+ *                 $4 - File handle
+ *
+ *               Return from syscall:
+ *                 $2 - 0 on success else -1
+ *                 $3 - errno
+ *
+ * @Description  File close
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int32_t _MIPS_HAL_NOMIPS16
+close (int32_t fd)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register int32_t op asm ("$25") = __MIPS_UHI_CLOSE;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+  
+  if (fd == 0 || fd == 1 || fd == 2)
+    return 0;
+
+  __asm__ __volatile__(" # %0,%1 = close(%2) op=%3\n"
+                       SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+                       : "+r" (ret), "=r" (new_errno), "+r" (arg1)
+		       : "r" (op)
+		       : "$5");
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+         clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
+
diff --git a/libgloss/mips/uhi/yamon_exception.c b/libgloss/mips/uhi/yamon_exception.c
new file mode 100644
index 000000000..f4d9a6452
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_exception.c
@@ -0,0 +1,52 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     int __uhi_exception (struct gp_ctx *ctx);
+ *
+ *               Parameters:
+ *                 $4 - GP context
+ *
+ *               Arguments to syscall:
+ *                 $25 - Operation code for __uhi_exception
+ *                 $4 - GP context
+ *
+ *               Return from syscall:
+ *                 $2 - 
+ *
+ * @Description  Handle an unhandled exception
+*/
+
+#include <stdint.h>
+#include <mips/hal.h>
+
+int32_t _MIPS_HAL_NOMIPS16
+__uhi_exception (struct gpctx *ctx, int32_t abi)
+{
+  return -1;
+}
diff --git a/libgloss/mips/uhi/yamon_exit.c b/libgloss/mips/uhi/yamon_exit.c
new file mode 100644
index 000000000..e28811814
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_exit.c
@@ -0,0 +1,60 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     void __exit (int32_t exit_code);
+ *
+ *               Parameters:
+ *                 $4 - Exit code
+ *
+ *               Return:
+ *                 None
+ *
+ * @Description  Transfer control to the debug port
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include "yamon_syscalls.h"
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+__attribute__ ((weak)) int _MIPS_HAL_NOMIPS16
+__exit (int exit_code)
+{
+  typedef void (*funcptr) (int32_t);
+  extern funcptr __yamon_functions[];
+  funcptr yamonexit;
+
+  yamonexit = (funcptr)__yamon_functions[__YAMON_EXIT];
+  (yamonexit) (exit_code);
+
+  __exit (exit_code);    /* just to avoide the warning */
+  return exit_code;
+}
+
diff --git a/libgloss/mips/uhi/yamon_fstat.c b/libgloss/mips/uhi/yamon_fstat.c
new file mode 100644
index 000000000..e1f8d1a07
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_fstat.c
@@ -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.
+*/
+
+/*
+ * @Synopsis     int32_t fstat (int32_t file, struct stat *sbuf);
+ *
+ *               Parameters:
+ *                 $4 - File handle
+ *                 $5 - Pointer to dst buffer (struct stat *)
+ *
+ *               Return:
+ *                 $2 - 0 on success else -1
+ *
+ *               Arguments to syscall:
+ *                 $25 - Operation code for fstat
+ *                 $4 - File handle
+ *                 $5 - Pointer to dst buffer (struct stat *)
+ *
+ *               Return from syscall:
+ *                 $2 - 0 on success else -1
+ *                 $3 - errno
+ *
+ * @Description  File statistics
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+#include "uhi_stat.h"
+
+/* This macro declares a dummy type with -ve size if CONDITION is false */
+#define __paste(STR1, STR2) STR1##STR2
+#define __check(LINE, CONDITION) typedef char __paste(assertion_failed_at_line_, LINE) [(int)(CONDITION)-1]
+
+int _MIPS_HAL_NOMIPS16
+fstat (int file, struct stat *sbuf)
+{
+  struct uhi_stat hbuf = {0,};
+  register int32_t arg1 asm ("$4") = file;
+  register struct uhi_stat *arg2 asm ("$5") = &hbuf;
+  register int32_t op asm ("$25") = __MIPS_UHI_FSTAT;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  /*
+   * We assume that NewLib has following 'struct stat'. Any change in
+   * this structure (either offset or size) would generate a compile
+   * time error.
+  */
+#if defined (_LP64)
+  __check (__LINE__, sizeof (struct stat) == 104);
+  __check (__LINE__, offsetof (struct stat, st_dev) == 0);
+  __check (__LINE__, offsetof (struct stat, st_ino) == 2);
+  __check (__LINE__, offsetof (struct stat, st_mode) == 4);
+  __check (__LINE__, offsetof (struct stat, st_nlink) == 8);
+  __check (__LINE__, offsetof (struct stat, st_uid) == 10);
+  __check (__LINE__, offsetof (struct stat, st_gid) == 12);
+  __check (__LINE__, offsetof (struct stat, st_rdev) == 14);
+  __check (__LINE__, offsetof (struct stat, st_size) == 16);
+  __check (__LINE__, offsetof (struct stat, st_atime) == 24);
+  __check (__LINE__, offsetof (struct stat, st_spare1) == 32);
+  __check (__LINE__, offsetof (struct stat, st_mtime) == 40);
+  __check (__LINE__, offsetof (struct stat, st_spare2) == 48);
+  __check (__LINE__, offsetof (struct stat, st_ctime) == 56);
+  __check (__LINE__, offsetof (struct stat, st_spare3) == 64);
+  __check (__LINE__, offsetof (struct stat, st_blksize) == 72);
+  __check (__LINE__, offsetof (struct stat, st_blocks) == 80);
+  __check (__LINE__, offsetof (struct stat, st_spare4) == 88);
+#else
+  __check (__LINE__, sizeof (struct stat) == 60);
+  __check (__LINE__, offsetof (struct stat, st_dev) == 0);
+  __check (__LINE__, offsetof (struct stat, st_ino) == 2);
+  __check (__LINE__, offsetof (struct stat, st_mode) == 4);
+  __check (__LINE__, offsetof (struct stat, st_nlink) == 8);
+  __check (__LINE__, offsetof (struct stat, st_uid) == 10);
+  __check (__LINE__, offsetof (struct stat, st_gid) == 12);
+  __check (__LINE__, offsetof (struct stat, st_rdev) == 14);
+  __check (__LINE__, offsetof (struct stat, st_size) == 16);
+  __check (__LINE__, offsetof (struct stat, st_atime) == 20);
+  __check (__LINE__, offsetof (struct stat, st_spare1) == 24);
+  __check (__LINE__, offsetof (struct stat, st_mtime) == 28);
+  __check (__LINE__, offsetof (struct stat, st_spare2) == 32);
+  __check (__LINE__, offsetof (struct stat, st_ctime) == 36);
+  __check (__LINE__, offsetof (struct stat, st_spare3) == 40);
+  __check (__LINE__, offsetof (struct stat, st_blksize) == 44);
+  __check (__LINE__, offsetof (struct stat, st_blocks) == 48);
+  __check (__LINE__, offsetof (struct stat, st_spare4) == 52);
+#endif
+
+  if (file == 0 || file == 1 || file == 2)
+  {
+    sbuf->st_mode = S_IRUSR | S_IWUSR | S_IWGRP;
+    sbuf->st_blksize = BUFSIZ;
+    sbuf->st_dev = 0;
+    sbuf->st_ino = 0;
+    sbuf->st_nlink = 0;
+    sbuf->st_uid = 0;
+    sbuf->st_gid = 0;
+    sbuf->st_rdev = 0;
+    sbuf->st_size = 0;
+    sbuf->st_atime = (time_t) 0;
+    sbuf->st_spare1 = 0;
+    sbuf->st_mtime = (time_t) 0;
+    sbuf->st_spare2 = 0;
+    sbuf->st_ctime = (time_t) 0;
+    sbuf->st_spare3 = 0;
+    sbuf->st_blocks = 0;
+    sbuf->st_spare4[0] = 0;
+    sbuf->st_spare4[1] = 0;
+    return 0;
+  }
+
+  __asm__ __volatile__(" # %0,%1 = fstat(%2, %3) op=%4\n"
+                       SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+                       : "+r" (ret), "=r" (new_errno), "+r" (arg1), "+r" (arg2)
+		       : "r" (op));
+
+  if (ret != 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+         clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+  else
+    {
+      sbuf->st_dev = hbuf.st_dev;
+      sbuf->st_ino = hbuf.st_ino;
+      sbuf->st_mode = hbuf.st_mode;
+      sbuf->st_nlink = hbuf.st_nlink;
+      sbuf->st_uid = hbuf.st_uid;
+      sbuf->st_gid = hbuf.st_gid;
+      sbuf->st_rdev = hbuf.st_rdev;
+      sbuf->st_size = (long) hbuf.st_size;
+      sbuf->st_atime = (time_t) hbuf.st_atime;
+      sbuf->st_spare1 = (long) hbuf.st_spare1;
+      sbuf->st_mtime = (time_t) hbuf.st_mtime;
+      sbuf->st_spare2 = (long) hbuf.st_spare2;
+      sbuf->st_ctime = (time_t) hbuf.st_ctime;
+      sbuf->st_spare3 = (long) hbuf.st_spare3;
+      sbuf->st_blksize = (long) hbuf.st_blksize;
+      sbuf->st_blocks = (long) hbuf.st_blocks;
+      sbuf->st_spare4[0] = (long) hbuf.st_spare4[0];
+      sbuf->st_spare4[1] = (long) hbuf.st_spare4[1];
+    }
+
+  return ret;
+}
+
+#undef __paste
+#undef __check
+
diff --git a/libgloss/mips/uhi/yamon_read.c b/libgloss/mips/uhi/yamon_read.c
new file mode 100644
index 000000000..1e365ce14
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_read.c
@@ -0,0 +1,101 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     int32_t read (int32_t fd, void *buffer, int32_t len);
+ *
+ *               Parameters:
+ *                 $4 - File handle
+ *                 $5 - Destination buffer
+ *                 $6 - Max number of bytes to read
+ *
+ *               Return:
+ *                 $2 - Number of bytes read
+ *
+ *               Arguments to syscall:
+ *                 $25 - Operation code for read
+ *                 $4 - File handle
+ *                 $5 - Destination buffer
+ *                 $6 - Max number of bytes to read
+ *
+ *               Return from syscall:
+ *                 $2 - Number of bytes read
+ *                 $3 - errno
+ *
+ * @Description  File read
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include "yamon_syscalls.h"
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+
+int32_t _MIPS_HAL_NOMIPS16
+read (int32_t fd, void *buffer, int32_t len)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register void *arg2 asm ("$5") = buffer;
+  register int32_t arg3 asm ("$6") = len;
+  register int32_t op asm ("$25") = __MIPS_UHI_READ;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  /* yamon getchar always reads from stdin */
+  if (fd == 0)
+   {
+     typedef int32_t (*funcptr) (int32_t, char *);
+     extern funcptr __yamon_functions[];
+     funcptr yamonread;
+     int32_t i;
+     yamonread = (funcptr)__yamon_functions[__YAMON_GETCHAR];
+
+     for (i=0; i<=len; i++)
+      ret += (yamonread) (fd, (char*)buffer+i);
+   }
+  else
+   {
+     /* Use UHI read when reading from source other than stdin */
+     __asm__ __volatile__(" # %0,%1 = read (%2, %3, %4) op=%5\n"
+                         SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+                         : "+r" (ret), "=r" (new_errno), "+r" (arg1), "+r" (arg2)
+			 : "r" (arg3), "r" (op));
+    }
+
+  if (ret < 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+         clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
+
diff --git a/libgloss/mips/uhi/yamon_syscalls.h b/libgloss/mips/uhi/yamon_syscalls.h
new file mode 100644
index 000000000..038012ec6
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_syscalls.h
@@ -0,0 +1,33 @@ 
+/*
+ * 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.
+*/
+
+/* These defines are used as array indices in c code */
+#define __YAMON_PRINT_COUNT    0x01  /* At location 0x04 in vector table */
+#define __YAMON_GETCHAR        0x14  /* At location 0x50 in vector table */
+#define __YAMON_EXIT           0x08  /* At location 0x20 in vector table */
+
diff --git a/libgloss/mips/uhi/yamon_write.c b/libgloss/mips/uhi/yamon_write.c
new file mode 100644
index 000000000..f42bb65b9
--- /dev/null
+++ b/libgloss/mips/uhi/yamon_write.c
@@ -0,0 +1,98 @@ 
+/*
+ * 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.
+*/
+
+/*
+ * @Synopsis     int32_t write (int32_t fd, void *buffer, int32_t count);
+ *
+ *               Parameters:
+ *                 $4 - File handle
+ *                 $5 - Buffer to write
+ *                 $6 - Length of the buffer
+ *
+ *               Return:
+ *                 $2 - Number of bytes written
+ *
+ *               Arguments to syscall:
+ *                 $25 - Operation code for write
+ *                 $4 - File handle
+ *                 $5 - Buffer to write
+ *                 $6 - Length of the buffer
+ *
+ *               Return from syscall:
+ *                 $2 - Number of bytes written
+ *                 $3 - errno
+ *
+ * @Description  File write
+*/
+
+#include <stdint.h>
+#include <errno.h>
+#include "yamon_syscalls.h"
+#include <mips/uhi_syscalls.h>
+#include <mips/hal.h>
+
+int32_t _MIPS_HAL_NOMIPS16
+write (int32_t fd, void *buffer, int32_t count)
+{
+  register int32_t arg1 asm ("$4") = fd;
+  register void *arg2 asm ("$5") = buffer;
+  register int32_t arg3 asm ("$6") = count;
+  register int32_t op asm ("$25") = __MIPS_UHI_WRITE;
+  register int32_t ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
+  register int32_t new_errno asm ("$3") = 0;
+
+  /* yamon print_count always writes to stdout */
+  if (fd == 1 || fd == 2)
+   {
+     typedef int32_t (*funcptr) (int32_t, char *, int32_t);
+     extern funcptr __yamon_functions[];
+     funcptr yamonwrite;
+
+     yamonwrite = (funcptr)__yamon_functions[__YAMON_PRINT_COUNT];
+
+     ret = (yamonwrite) (0, buffer, count);
+   }
+  else
+   {
+     /* Use UHI write when writing to destination other than stdout */
+     __asm__ __volatile__(" # %0,%1 = write(%2, %3, %4) op=%5\n"
+                         SYSCALL (__MIPS_UHI_SYSCALL_NUM)
+                         : "+r" (ret), "=r" (new_errno), "+r" (arg1), "+r" (arg2)
+			 : "r" (arg3), "r" (op));
+   }
+  if (ret < 0)
+    {
+      /* Do a dance to set errno, errno is a function call that can
+         clobber $3.  */
+      volatile uint32_t errno_tmp = new_errno;
+      errno = errno_tmp;
+    }
+
+  return ret;
+}
+
diff --git a/libgloss/mips/uhi32.ld b/libgloss/mips/uhi32.ld
new file mode 100644
index 000000000..d9df8e5e0
--- /dev/null
+++ b/libgloss/mips/uhi32.ld
@@ -0,0 +1,322 @@ 
+/*
+ * A platform and target independent link script to produce UHI
+ * compliant binaries with varying levels of system initialization
+ * support.
+ */
+
+__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start;
+ENTRY(__entry)
+OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", "elf32-tradlittlemips")
+GROUP(-lc -luhi -lgcc -lhal)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+STARTUP(crt0.o)
+/* Force the exception handler to be registered */
+EXTERN(__register_excpt_handler)
+/* Force the exception handler to be included in the link */
+EXTERN(__exception_entry)
+/*
+ * Require verbose exceptions. This can be changed to pull in
+ * __exception_handle_quiet to reduce code size but be less
+ * informative
+ */
+EXTERN(__exception_handle_verbose)
+/* Force ISRs 0-7 to be included in the link */
+EXTERN(__isr_vec_007)
+/* Require the UHI getargs support */
+EXTERN(__getargs)
+/* Include the breakpoint exception handler.  */
+EXTERN (__uhi_break);
+
+/*
+ * Set the location of the top of the stack.  A value of 0 means
+ * that it will be automatically placed at the highest address
+ * available as described by the __memory_* setttings
+ */
+PROVIDE (__stack = 0);
+
+/* Size of the memory returned by _get_ram_range */
+PROVIDE (__memory_size = 3M);
+
+/* Base of the memory returned by _get_ram_range */
+PROVIDE (__memory_base = 0x80000000);
+
+/* Stride length for tlb software invalidate for tlbinvf
+ * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
+ * differently in the index register. Either sets LSB or ways LSB.
+ *
+ * By setting this to 1 we presume that sets come first. The default boot
+ * code will decrement this value from the Number of TLB entries.
+ */
+PROVIDE (__tlb_stride_length = 1);
+
+/* By default, XPA is not used even if available. To enable XPA,
+ * __enable_xpa should be 1.
+ */
+PROVIDE (__enable_xpa = 0);
+
+/*
+ * 0 = Do not use exception handler present in boot for UHI
+ * 1 = Use exception handler present in boot for UHI if BEV is 0 at
+ *     startup
+ * 2 = Always use exception handler present in boot for UHI
+ */
+PROVIDE (__use_excpt_boot = 1);
+/*
+ * Include the code to be able to return to boot context.  This is
+ * necessary if __use_excpt_boot != 0.
+ */
+EXTERN (__register_excpt_boot);
+
+ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
+	"Registration for boot context is required for UHI chaining")
+
+/* Control if subnormal floating-point values are flushed to zero in
+   hardware.  This applies to both FPU and MSA operations.  */
+PROVIDE (__flush_to_zero = 1);
+
+/* Set up the public symbols depending on whether the user has chosen
+   quiet or verbose exception handling above */
+EXTERN (__exception_handle);
+PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
+				      ? __exception_handle_quiet
+				      : __exception_handle_verbose));
+PROVIDE(_mips_handle_exception = __exception_handle);
+
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we multiple object file
+ * formats, as some prepend an underscore.
+ */
+PROVIDE (hardware_exit_hook = 0);
+PROVIDE (hardware_hazard_hook = 0);
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+
+/* The default base address for application code is 0x80200000 which
+   leaves 2M of space at the start of KSEG0 for a bootloader. */
+PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000);
+/* Set default vector spacing to 32 bytes. */
+PROVIDE (__isr_vec_space = 32);
+/* Leave space for 9 vector entries by default. 8 entry points and one
+   fallback handler. */
+PROVIDE (__isr_vec_count = 9);
+/*
+ * The start of flash must be set if including boot code.  By default
+ * the use of boot code will mean that application code is copied
+ * from flash to RAM at runtime before being executed.
+ */
+PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 : __app_start);
+/* Set the default execution address for boot code. */
+PROVIDE (__bev_override = 0x9fc00000);
+
+SECTIONS
+{
+  /* Start of bootrom */
+  .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is
+			       initialized. */
+  AT (__flash_start)
+  {
+    *(.reset)		/* Reset entry point. */
+    *(.boot)		/* Boot code. */
+    . = ALIGN(8);
+  } = 0
+
+  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
+
+  __aligned_app_start = DEFINED(__xip)
+			? __bev_override + SIZEOF(.bootrom)
+			: ALIGN(__app_start, 0x1000);
+
+  PROVIDE (__ebase_size = 0x200);
+
+  /* Start of the application */
+  .exception_vector __aligned_app_start :
+  AT (__flash_app_start)
+  {
+    PROVIDE (__excpt_ebase = ABSOLUTE(.));
+    __base = .;
+    KEEP(* (.text.__exception_entry))
+    . = __base + __ebase_size;
+    KEEP(* (SORT(.text.__isr_vec*)))
+    /* Leave space for all the vector entries */
+    . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count);
+    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
+			       ? __isr_vec_sw1 - __isr_vec_sw0
+			       : __isr_vec_space),
+	   "Actual ISR vector spacing does not match __isr_vec_space");
+    ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0)
+				     ? __isr_vec_sw0 & 0xfffffffe
+				     : __base + __ebase_size),
+	   "__isr_vec_sw0 is not placed at EBASE + 0x200");
+    . = ALIGN(8);
+  } = 0
+
+  .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector)) {
+     _ftext = . ;
+    PROVIDE (eprol  =  .);
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.mips16.fn.*)
+    *(.mips16.call.*)
+  }
+  .init . : AT (LOADADDR (.text) + SIZEOF(.text)) {
+    KEEP (*(.init))
+  }
+  .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) {
+    KEEP (*(.fini))
+  }
+  .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) {
+    PROVIDE (__runtime_reloc_start = .);
+    *(.rel.sdata)
+    PROVIDE (__runtime_reloc_stop = .);
+  }
+  PROVIDE (etext  =  .);
+  _etext  =  .;
+
+  .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) { *(.eh_frame_hdr) }
+  .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) { KEEP (*(.eh_frame)) }
+  .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) { *(.gcc_except_table) }
+  .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table)) { KEEP (*(.jcr)) }
+  .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr))
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+
+    KEEP (*crtbegin.o(.ctors))
+
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+
+  .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors))
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+
+  . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
+  .rodata : {
+    *(.rdata)
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r.*)
+  }
+   . = ALIGN(16);
+   _fdata = .;
+  .data : {
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d.*)
+  }
+  . = ALIGN(8);
+  _gp = . + 0x8000;
+  __global = _gp;
+  .lit8 : {
+    *(.lit8)
+  }
+  .lit4 : {
+    *(.lit4)
+  }
+  .sdata : {
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s.*)
+  }
+  . = ALIGN(4);
+  PROVIDE (edata  =  .);
+  _edata  =  .;
+  _fbss = .;
+  .sbss : {
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  .bss : {
+    _bss_start = . ;
+    *(.bss)
+    *(.bss.*)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+  }
+
+  . = ALIGN(4);
+  PROVIDE (end = .);
+  _end = .;
+  /* Now place the data that is only needed within start.S and can be
+     overwritten by the heap.  */
+  .startdata : {
+    *(.startdata)
+  }
+
+  /* We do not support any runtime relocation handling with this script.  */
+  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+
+  /* Special sections generated by gcc */
+  /* Newer GNU linkers strip by default */
+  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
+  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
+  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
+  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
+  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
+  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
+  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
+  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
+}
diff --git a/libgloss/mips/uhi64_64.ld b/libgloss/mips/uhi64_64.ld
new file mode 100644
index 000000000..15aeb2ecc
--- /dev/null
+++ b/libgloss/mips/uhi64_64.ld
@@ -0,0 +1,322 @@ 
+/*
+ * A platform and target independent link script to produce UHI
+ * compliant binaries with varying levels of system initialization
+ * support.
+ */
+
+__entry = DEFINED(__reset_vector) ? 0xffffffffbfc00000 : _start;
+ENTRY(__entry)
+OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", "elf64-tradlittlemips")
+GROUP(-lc -luhi -lgcc -lhal)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+STARTUP(crt0.o)
+/* Force the exception handler to be registered */
+EXTERN(__register_excpt_handler)
+/* Force the exception handler to be included in the link */
+EXTERN(__exception_entry)
+/*
+ * Require verbose exceptions. This can be changed to pull in
+ * __exception_handle_quiet to reduce code size but be less
+ * informative
+ */
+EXTERN(__exception_handle_verbose)
+/* Force ISRs 0-7 to be included in the link */
+EXTERN(__isr_vec_007)
+/* Require the UHI getargs support */
+EXTERN(__getargs)
+/* Include the breakpoint exception handler.  */
+EXTERN (__uhi_break);
+
+/*
+ * Set the location of the top of the stack.  A value of 0 means
+ * that it will be automatically placed at the highest address
+ * available as described by the __memory_* setttings
+ */
+PROVIDE (__stack = 0);
+
+/* Size of the memory returned by _get_ram_range */
+PROVIDE (__memory_size = 3M);
+
+/* Base of the memory returned by _get_ram_range */
+PROVIDE (__memory_base = 0xffffffff80000000);
+
+/* Stride length for tlb software invalidate for tlbinvf
+ * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
+ * differently in the index register. Either sets LSB or ways LSB.
+ *
+ * By setting this to 1 we presume that sets come first. The default boot
+ * code will decrement this value from the Number of TLB entries.
+ */
+PROVIDE (__tlb_stride_length = 1);
+
+/* By default, XPA is not used even if available. To enable XPA,
+ * __enable_xpa should be 1.
+ */
+PROVIDE (__enable_xpa = 0);
+
+/*
+ * 0 = Do not use exception handler present in boot for UHI
+ * 1 = Use exception handler present in boot for UHI if BEV is 0 at
+ *     startup
+ * 2 = Always use exception handler present in boot for UHI
+ */
+PROVIDE (__use_excpt_boot = 1);
+/*
+ * Include the code to be able to return to boot context.  This is
+ * necessary if __use_excpt_boot != 0.
+ */
+EXTERN (__register_excpt_boot);
+
+ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
+	"Registration for boot context is required for UHI chaining")
+
+/* Control if subnormal floating-point values are flushed to zero in
+   hardware.  This applies to both FPU and MSA operations.  */
+PROVIDE (__flush_to_zero = 1);
+
+/* Set up the public symbols depending on whether the user has chosen
+   quiet or verbose exception handling above */
+EXTERN (__exception_handle);
+PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
+				      ? __exception_handle_quiet
+				      : __exception_handle_verbose));
+PROVIDE(_mips_handle_exception = __exception_handle);
+
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we multiple object file
+ * formats, as some prepend an underscore.
+ */
+PROVIDE (hardware_exit_hook = 0);
+PROVIDE (hardware_hazard_hook = 0);
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+
+/* The default base address for application code is 0x80200000 which
+   leaves 2M of space at the start of KSEG0 for a bootloader. */
+PROVIDE (__app_start = DEFINED(__reset_vector) ? 0xffffffff80000000 :0xffffffff80200000);
+/* Set default vector spacing to 64 bytes. */
+PROVIDE (__isr_vec_space = 64);
+/* Leave space for 9 vector entries by default. 8 entry points and one
+   fallback handler. */
+PROVIDE (__isr_vec_count = 9);
+/*
+ * The start of flash must be set if including boot code.  By default
+ * the use of boot code will mean that application code is copied
+ * from flash to RAM at runtime before being executed.
+ */
+PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xffffffffbfc00000 : __app_start);
+/* Set the default execution address for boot code. */
+PROVIDE (__bev_override = 0xffffffff9fc00000);
+
+SECTIONS
+{
+  /* Start of bootrom */
+  .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is
+			       initialized. */
+  AT (__flash_start)
+  {
+    *(.reset)		/* Reset entry point. */
+    *(.boot)		/* Boot code. */
+    . = ALIGN(8);
+  } = 0
+
+  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
+
+  __aligned_app_start = DEFINED(__xip)
+			? __bev_override + SIZEOF(.bootrom)
+			: ALIGN(__app_start, 0x1000);
+
+  PROVIDE (__ebase_size = 0x200);
+
+  /* Start of the application */
+  .exception_vector __aligned_app_start :
+  AT (__flash_app_start)
+  {
+    PROVIDE (__excpt_ebase = ABSOLUTE(.));
+    __base = .;
+    KEEP(* (.text.__exception_entry))
+    . = __base + __ebase_size;
+    KEEP(* (SORT(.text.__isr_vec*)))
+    /* Leave space for all the vector entries */
+    . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count);
+    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
+			       ? __isr_vec_sw1 - __isr_vec_sw0
+			       : __isr_vec_space),
+	   "Actual ISR vector spacing does not match __isr_vec_space");
+    ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0)
+				     ? __isr_vec_sw0
+				     : __base + __ebase_size),
+	   "__isr_vec_sw0 is not placed at EBASE + 0x200");
+    . = ALIGN(8);
+  } = 0
+
+  .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector)) {
+     _ftext = . ;
+    PROVIDE (eprol  =  .);
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.mips16.fn.*)
+    *(.mips16.call.*)
+  }
+  .init . : AT (LOADADDR (.text) + SIZEOF(.text)) {
+    KEEP (*(.init))
+  }
+  .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) {
+    KEEP (*(.fini))
+  }
+  .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) {
+    PROVIDE (__runtime_reloc_start = .);
+    *(.rel.sdata)
+    PROVIDE (__runtime_reloc_stop = .);
+  }
+  PROVIDE (etext  =  .);
+  _etext  =  .;
+
+  .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) { *(.eh_frame_hdr) }
+  .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) { KEEP (*(.eh_frame)) }
+  .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) { *(.gcc_except_table) }
+  .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table)) { KEEP (*(.jcr)) }
+  .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr))
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+
+    KEEP (*crtbegin.o(.ctors))
+
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+
+  .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors))
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+
+  . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
+  .rodata : {
+    *(.rdata)
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r.*)
+  }
+   . = ALIGN(16);
+   _fdata = .;
+  .data : {
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d.*)
+  }
+  . = ALIGN(8);
+  _gp = . + 0x8000;
+  __global = _gp;
+  .lit8 : {
+    *(.lit8)
+  }
+  .lit4 : {
+    *(.lit4)
+  }
+  .sdata : {
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s.*)
+  }
+  . = ALIGN(4);
+  PROVIDE (edata  =  .);
+  _edata  =  .;
+  _fbss = .;
+  .sbss : {
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  .bss : {
+    _bss_start = . ;
+    *(.bss)
+    *(.bss.*)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+  }
+
+  . = ALIGN(4);
+  PROVIDE (end = .);
+  _end = .;
+  /* Now place the data that is only needed within start.S and can be
+     overwritten by the heap.  */
+  .startdata : {
+    *(.startdata)
+  }
+
+  /* We do not support any runtime relocation handling with this script.  */
+  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+
+  /* Special sections generated by gcc */
+  /* Newer GNU linkers strip by default */
+  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
+  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
+  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
+  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
+  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
+  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
+  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
+  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
+}
diff --git a/libgloss/mips/uhi64_n32.ld b/libgloss/mips/uhi64_n32.ld
new file mode 100644
index 000000000..d68f2eaaa
--- /dev/null
+++ b/libgloss/mips/uhi64_n32.ld
@@ -0,0 +1,322 @@ 
+/*
+ * A platform and target independent link script to produce UHI
+ * compliant binaries with varying levels of system initialization
+ * support.
+ */
+
+__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start;
+ENTRY(__entry)
+OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips", "elf32-ntradlittlemips")
+GROUP(-lc -luhi -lgcc -lhal)
+SEARCH_DIR(.)
+__DYNAMIC  =  0;
+STARTUP(crt0.o)
+/* Force the exception handler to be registered */
+EXTERN(__register_excpt_handler)
+/* Force the exception handler to be included in the link */
+EXTERN(__exception_entry)
+/*
+ * Require verbose exceptions. This can be changed to pull in
+ * __exception_handle_quiet to reduce code size but be less
+ * informative
+ */
+EXTERN(__exception_handle_verbose)
+/* Force ISRs 0-7 to be included in the link */
+EXTERN(__isr_vec_007)
+/* Require the UHI getargs support */
+EXTERN(__getargs)
+/* Include the breakpoint exception handler.  */
+EXTERN (__uhi_break);
+
+/*
+ * Set the location of the top of the stack.  A value of 0 means
+ * that it will be automatically placed at the highest address
+ * available as described by the __memory_* setttings
+ */
+PROVIDE (__stack = 0);
+
+/* Size of the memory returned by _get_ram_range */
+PROVIDE (__memory_size = 3M);
+
+/* Base of the memory returned by _get_ram_range */
+PROVIDE (__memory_base = 0x80000000);
+
+/* Stride length for tlb software invalidate for tlbinvf
+ * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
+ * differently in the index register. Either sets LSB or ways LSB.
+ *
+ * By setting this to 1 we presume that sets come first. The default boot
+ * code will decrement this value from the Number of TLB entries.
+ */
+PROVIDE (__tlb_stride_length = 1);
+
+/* By default, XPA is not used even if available. To enable XPA,
+ * __enable_xpa should be 1.
+ */
+PROVIDE (__enable_xpa = 0);
+
+/*
+ * 0 = Do not use exception handler present in boot for UHI
+ * 1 = Use exception handler present in boot for UHI if BEV is 0 at
+ *     startup
+ * 2 = Always use exception handler present in boot for UHI
+ */
+PROVIDE (__use_excpt_boot = 1);
+/*
+ * Include the code to be able to return to boot context.  This is
+ * necessary if __use_excpt_boot != 0.
+ */
+EXTERN (__register_excpt_boot);
+
+ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
+	"Registration for boot context is required for UHI chaining")
+
+/* Control if subnormal floating-point values are flushed to zero in
+   hardware.  This applies to both FPU and MSA operations.  */
+PROVIDE (__flush_to_zero = 1);
+
+/* Set up the public symbols depending on whether the user has chosen
+   quiet or verbose exception handling above */
+EXTERN (__exception_handle);
+PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
+				      ? __exception_handle_quiet
+				      : __exception_handle_verbose));
+PROVIDE(_mips_handle_exception = __exception_handle);
+
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we multiple object file
+ * formats, as some prepend an underscore.
+ */
+PROVIDE (hardware_exit_hook = 0);
+PROVIDE (hardware_hazard_hook = 0);
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+
+/* The default base address for application code is 0x80200000 which
+   leaves 2M of space at the start of KSEG0 for a bootloader. */
+PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000);
+/* Set default vector spacing to 32 bytes. */
+PROVIDE (__isr_vec_space = 32);
+/* Leave space for 9 vector entries by default. 8 entry points and one
+   fallback handler. */
+PROVIDE (__isr_vec_count = 9);
+/*
+ * The start of flash must be set if including boot code.  By default
+ * the use of boot code will mean that application code is copied
+ * from flash to RAM at runtime before being executed.
+ */
+PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 : __app_start);
+/* Set the default execution address for boot code. */
+PROVIDE (__bev_override = 0x9fc00000);
+
+SECTIONS
+{
+  /* Start of bootrom */
+  .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is
+			       initialized. */
+  AT (__flash_start)
+  {
+    *(.reset)		/* Reset entry point. */
+    *(.boot)		/* Boot code. */
+    . = ALIGN(8);
+  } = 0
+
+  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
+
+  __aligned_app_start = DEFINED(__xip)
+			? __bev_override + SIZEOF(.bootrom)
+			: ALIGN(__app_start, 0x1000);
+
+  PROVIDE (__ebase_size = 0x200);
+
+  /* Start of the application */
+  .exception_vector __aligned_app_start :
+  AT (__flash_app_start)
+  {
+    PROVIDE (__excpt_ebase = ABSOLUTE(.));
+    __base = .;
+    KEEP(* (.text.__exception_entry))
+    . = __base + __ebase_size;
+    KEEP(* (SORT(.text.__isr_vec*)))
+    /* Leave space for all the vector entries */
+    . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count);
+    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
+			       ? __isr_vec_sw1 - __isr_vec_sw0
+			       : __isr_vec_space),
+	   "Actual ISR vector spacing does not match __isr_vec_space");
+    ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0)
+				     ? __isr_vec_sw0
+				     : __base + __ebase_size),
+	   "__isr_vec_sw0 is not placed at EBASE + 0x200");
+    . = ALIGN(8);
+  } = 0
+
+  .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector)) {
+     _ftext = . ;
+    PROVIDE (eprol  =  .);
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.mips16.fn.*)
+    *(.mips16.call.*)
+  }
+  .init . : AT (LOADADDR (.text) + SIZEOF(.text)) {
+    KEEP (*(.init))
+  }
+  .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) {
+    KEEP (*(.fini))
+  }
+  .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) {
+    PROVIDE (__runtime_reloc_start = .);
+    *(.rel.sdata)
+    PROVIDE (__runtime_reloc_stop = .);
+  }
+  PROVIDE (etext  =  .);
+  _etext  =  .;
+
+  .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) { *(.eh_frame_hdr) }
+  .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) { KEEP (*(.eh_frame)) }
+  .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) { *(.gcc_except_table) }
+  .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table)) { KEEP (*(.jcr)) }
+  .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr))
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+
+    KEEP (*crtbegin.o(.ctors))
+
+    /* We don't want to include the .ctor section from
+       from the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+
+  .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors))
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+
+  . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
+  .rodata : {
+    *(.rdata)
+    *(.rodata)
+    *(.rodata.*)
+    *(.gnu.linkonce.r.*)
+  }
+   . = ALIGN(16);
+   _fdata = .;
+  .data : {
+    *(.data)
+    *(.data.*)
+    *(.gnu.linkonce.d.*)
+  }
+  . = ALIGN(8);
+  _gp = . + 0x8000;
+  __global = _gp;
+  .lit8 : {
+    *(.lit8)
+  }
+  .lit4 : {
+    *(.lit4)
+  }
+  .sdata : {
+    *(.sdata)
+    *(.sdata.*)
+    *(.gnu.linkonce.s.*)
+  }
+  . = ALIGN(4);
+  PROVIDE (edata  =  .);
+  _edata  =  .;
+  _fbss = .;
+  .sbss : {
+    *(.sbss)
+    *(.sbss.*)
+    *(.gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  .bss : {
+    _bss_start = . ;
+    *(.bss)
+    *(.bss.*)
+    *(.gnu.linkonce.b.*)
+    *(COMMON)
+  }
+
+  . = ALIGN(4);
+  PROVIDE (end = .);
+  _end = .;
+  /* Now place the data that is only needed within start.S and can be
+     overwritten by the heap.  */
+  .startdata : {
+    *(.startdata)
+  }
+
+  /* We do not support any runtime relocation handling with this script.  */
+  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
+
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to
+     the beginning of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+
+  /* Special sections generated by gcc */
+  /* Newer GNU linkers strip by default */
+  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
+  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
+  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
+  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
+  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
+  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
+  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
+  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
+}
diff --git a/newlib/configure.host b/newlib/configure.host
index ff2e51275..846148c25 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -251,6 +251,7 @@  case "${host_cpu}" in
   mips*)
 	machine_dir=mips
 	libm_machine_dir=mips
+	newlib_cflags="${newlib_cflags}"
 	;;
   mmix)
 	;;
diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h
index f99577bea..c5fafcf05 100644
--- a/newlib/libc/include/machine/ieeefp.h
+++ b/newlib/libc/include/machine/ieeefp.h
@@ -263,9 +263,15 @@ 
 
 #ifdef __MIPSEL__
 #define __IEEE_LITTLE_ENDIAN
+#if __SIZEOF_DOUBLE__ == 4
+#define _DOUBLE_IS_32BITS
+#endif
 #endif
 #ifdef __MIPSEB__
 #define __IEEE_BIG_ENDIAN
+#if __SIZEOF_DOUBLE__ == 4
+#define _DOUBLE_IS_32BITS
+#endif
 #endif
 
 #ifdef __MMIX__
diff --git a/newlib/libc/include/sys/config.h b/newlib/libc/include/sys/config.h
index 5dcc77a80..4c9acc55c 100644
--- a/newlib/libc/include/sys/config.h
+++ b/newlib/libc/include/sys/config.h
@@ -4,7 +4,7 @@ 
 #include <machine/ieeefp.h>  /* floating point macros */
 #include <sys/features.h>	/* POSIX defs */
 
-#ifdef __aarch64__
+#if defined(__aarch64__) || defined(__mips__)
 #define MALLOC_ALIGNMENT 16
 #endif
 
diff --git a/newlib/libc/include/sys/stat.h b/newlib/libc/include/sys/stat.h
index b4e27f22e..7edfe34ff 100644
--- a/newlib/libc/include/sys/stat.h
+++ b/newlib/libc/include/sys/stat.h
@@ -38,6 +38,16 @@  struct	stat
   time_t	st_atime;
   time_t	st_mtime;
   time_t	st_ctime;
+#elif defined(__mips__)
+  time_t	st_atime;
+  long		st_spare1;
+  time_t	st_mtime;
+  long		st_spare2;
+  time_t	st_ctime;
+  long		st_spare3;
+  blksize_t	st_blksize;
+  blkcnt_t	st_blocks;
+  long		st_spare4[2];
 #else
   struct timespec st_atim;
   struct timespec st_mtim;
@@ -50,7 +60,7 @@  struct	stat
 #endif
 };
 
-#if !(defined(__svr4__) && !defined(__PPC__) && !defined(__sun__))
+#if !((defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)) || defined(__mips__))
 #define st_atime st_atim.tv_sec
 #define st_ctime st_ctim.tv_sec
 #define st_mtime st_mtim.tv_sec
@@ -136,7 +146,11 @@  struct	stat
 
 int	chmod (const char *__path, mode_t __mode );
 int     fchmod (int __fd, mode_t __mode);
+#if defined(__mips__) && defined(__mips16)
+int __attribute__((nomips16)) fstat (int __fd, struct stat *__sbuf );
+#else
 int	fstat (int __fd, struct stat *__sbuf );
+#endif // __mips__
 int	mkdir (const char *_path, mode_t __mode );
 int	mkfifo (const char *__path, mode_t __mode );
 int	stat (const char *__restrict __path, struct stat *__restrict __sbuf );
diff --git a/newlib/libc/machine/mips/machine/regdef.h b/newlib/libc/machine/mips/machine/regdef.h
index 0164164b1..5d19f90c6 100644
--- a/newlib/libc/machine/mips/machine/regdef.h
+++ b/newlib/libc/machine/mips/machine/regdef.h
@@ -45,6 +45,11 @@ 
 
 #define v0 	$2
 #define v1	$3
+#define va0	$2
+#define va1	$3
+
+#define vt0	$2
+#define vt1	$3
 
 #define a0	$4
 #define a1	$5
@@ -100,4 +105,37 @@ 
 #define fp	$30
 #define ra	$31
 
+#define r0	$0
+#define r1	$1
+#define r2	$2
+#define r3	$3
+#define r4	$4
+#define r5	$5
+#define r6	$6
+#define r7	$7
+#define r8	$8
+#define r9	$9
+#define r10	$10
+#define r11	$11
+#define r12	$12
+#define r13	$13
+#define r14	$14
+#define r15	$15
+#define r16	$16
+#define r17	$17
+#define r18	$18
+#define r19	$19
+#define r20	$20
+#define r21	$21
+#define r22	$22
+#define r23	$23
+#define r24	$24
+#define r25	$25
+#define r26	$26
+#define r27	$27
+#define r28	$28
+#define r29	$29
+#define r30	$30
+#define r31	$31
+
 #endif
diff --git a/newlib/libc/machine/mips/setjmp.S b/newlib/libc/machine/mips/setjmp.S
index cfc1d517a..1e3ee0dbf 100644
--- a/newlib/libc/machine/mips/setjmp.S
+++ b/newlib/libc/machine/mips/setjmp.S
@@ -67,7 +67,7 @@ 
    regardless of whether the realignment happened or not.  */
 
 #define FPR_LAYOUT		\
-	and $8, $4, 4;	 	\
+	andi $8, $4, 4;	 	\
 	beq $8, $0, 1f;		\
 	GPR_OFFSET ($31, 22);	\
 	addiu $4, $4, -4;	\
@@ -133,7 +133,7 @@  setjmp:
 #undef FPR_OFFSET
 
 	move	$2,$0
-	j	$31
+	jr	$31
 
 	.end	setjmp
 
@@ -154,6 +154,6 @@  longjmp:
 	li	$5,1
 1:
 	move	$2,$5
-	j	$31
+	jr	$31
 
 	.end longjmp
diff --git a/newlib/libc/machine/mips/strcmp.S b/newlib/libc/machine/mips/strcmp.S
index 9d33a4ee0..a59f73e52 100644
--- a/newlib/libc/machine/mips/strcmp.S
+++ b/newlib/libc/machine/mips/strcmp.S
@@ -1,31 +1,30 @@ 
 /*
- * Copyright (c) 2014
- *      Imagination Technologies Limited.
+ * 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 MIPS Technologies, Inc., nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions are met:
  *
- * THIS SOFTWARE IS PROVIDED BY IMAGINATION TECHNOLOGIES LIMITED ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * 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 IMAGINATION TECHNOLOGIES LIMITED 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.
- */
+ * 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.
+*/
 
 #ifdef ANDROID_CHANGES
 # include "machine/asm.h"
@@ -38,18 +37,6 @@ 
 # include <sys/asm.h>
 #endif
 
-/* Technically strcmp should not read past the end of the strings being
-   compared.  We will read a full word that may contain excess bits beyond
-   the NULL string terminator but unless ENABLE_READAHEAD is set, we will not
-   read the next word after the end of string.  Setting ENABLE_READAHEAD will
-   improve performance but is technically illegal based on the definition of
-   strcmp.  */
-#ifdef ENABLE_READAHEAD
-# define DELAY_READ
-#else
-# define DELAY_READ nop
-#endif
-
 /* Testing on a little endian machine showed using CLZ was a
    performance loss, so we are not turning it on by default.  */
 #if defined(ENABLE_CLZ) && (__mips_isa_rev > 1)
@@ -85,7 +72,6 @@  LEAF(STRCMP_NAME, 0)
 LEAF(STRCMP_NAME)
 #endif
 	.set	nomips16
-	.set	noreorder
 
 	or	t0, a0, a1
 	andi	t0,0x3
@@ -93,50 +79,47 @@  LEAF(STRCMP_NAME)
 
 /* Both strings are 4 byte aligned at this point.  */
 
-	lui	t8, 0x0101
-	ori	t8, t8, 0x0101
-	lui	t9, 0x7f7f
-	ori	t9, 0x7f7f
+	li	t8, 0x01010101
+	li	t9, 0x7f7f7f7f
 
 #define STRCMP32(OFFSET) \
-	lw	v0, OFFSET(a0); \
-	lw	v1, OFFSET(a1); \
-	subu	t0, v0, t8; \
-	bne	v0, v1, L(worddiff); \
-	nor	t1, v0, t9; \
+	lw	vt0, OFFSET(a0); \
+	lw	vt1, OFFSET(a1); \
+	subu	t0, vt0, t8; \
+	nor	t1, vt0, t9; \
+	bne	vt0, vt1, L(worddiff); \
 	and	t0, t0, t1; \
 	bne	t0, zero, L(returnzero)
 
 L(wordloop):
 	STRCMP32(0)
-	DELAY_READ
 	STRCMP32(4)
-	DELAY_READ
 	STRCMP32(8)
-	DELAY_READ
 	STRCMP32(12)
-	DELAY_READ
 	STRCMP32(16)
-	DELAY_READ
 	STRCMP32(20)
-	DELAY_READ
 	STRCMP32(24)
-	DELAY_READ
-	STRCMP32(28)
+	lw	vt0, 28(a0)
+	lw	vt1, 28(a1)
+	subu	t0, vt0, t8
+	nor	t1, vt0, t9
+	bne	vt0, vt1, L(worddiff)
+	and	t0, t0, t1
 	PTR_ADDIU a0, a0, 32
-	b	L(wordloop)
+	bne	t0, zero, L(returnzero)
 	PTR_ADDIU a1, a1, 32
+	b	L(wordloop)
 
 L(returnzero):
-	j	ra
-	move	v0, zero
+	move	va0, zero
+	jr	ra
 
 L(worddiff):
 #ifdef USE_CLZ
-	subu	t0, v0, t8
-	nor	t1, v0, t9
+	subu	t0, vt0, t8
+	nor	t1, vt0, t9
 	and	t1, t0, t1
-	xor	t0, v0, v1
+	xor	t0, vt0, vt1
 	or	t0, t0, t1
 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 	wsbh	t0, t0
@@ -148,85 +131,86 @@  L(worddiff):
 	neg	t1
 	addu	t1, 24
 # endif
-	rotrv	v0, v0, t1
-	rotrv	v1, v1, t1
-	and	v0, v0, 0xff
-	and	v1, v1, 0xff
-	j	ra
-	subu	v0, v0, v1
+	rotrv	vt0, vt0, t1
+	rotrv	vt1, vt1, t1
+	and	vt0, vt0, 0xff
+	and	vt1, vt1, 0xff
+	subu	va0, vt0, vt1
+	jr	ra
 #else /* USE_CLZ */
 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-	andi	t0, v0, 0xff
+	andi	t0, vt0, 0xff
+	andi	t1, vt1, 0xff
 	beq	t0, zero, L(wexit01)
-	andi	t1, v1, 0xff
+	srl	t8, vt0, 8
 	bne	t0, t1, L(wexit01)
 
-	srl	t8, v0, 8
-	srl	t9, v1, 8
+	srl	t9, vt1, 8
 	andi	t8, t8, 0xff
-	beq	t8, zero, L(wexit89)
 	andi	t9, t9, 0xff
+	beq	t8, zero, L(wexit89)
+	srl	t0, vt0, 16
 	bne	t8, t9, L(wexit89)
 
-	srl	t0, v0, 16
-	srl	t1, v1, 16
+	srl	t1, vt1, 16
 	andi	t0, t0, 0xff
-	beq	t0, zero, L(wexit01)
 	andi	t1, t1, 0xff
+	beq	t0, zero, L(wexit01)
+	srl	t8, vt0, 24
 	bne	t0, t1, L(wexit01)
 
-	srl	t8, v0, 24
-	srl	t9, v1, 24
+	srl	t9, vt1, 24
 # else /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
-	srl	t0, v0, 24
+	srl	t0, vt0, 24
+	srl	t1, vt1, 24
 	beq	t0, zero, L(wexit01)
-	srl	t1, v1, 24
+	srl	t8, vt0, 16
 	bne	t0, t1, L(wexit01)
 
-	srl	t8, v0, 16
-	srl	t9, v1, 16
+	srl	t9, vt1, 16
 	andi	t8, t8, 0xff
-	beq	t8, zero, L(wexit89)
 	andi	t9, t9, 0xff
+	beq	t8, zero, L(wexit89)
+	srl	t0, vt0, 8
 	bne	t8, t9, L(wexit89)
 
-	srl	t0, v0, 8
-	srl	t1, v1, 8
+	srl	t1, vt1, 8
 	andi	t0, t0, 0xff
-	beq	t0, zero, L(wexit01)
 	andi	t1, t1, 0xff
+	beq	t0, zero, L(wexit01)
+	andi	t8, vt0, 0xff
 	bne	t0, t1, L(wexit01)
 
-	andi	t8, v0, 0xff
-	andi	t9, v1, 0xff
+	andi	t9, vt1, 0xff
 # endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
 
 L(wexit89):
-	j	ra
-	subu	v0, t8, t9
+	subu	va0, t8, t9
+	jr	ra
 L(wexit01):
-	j	ra
-	subu	v0, t0, t1
+	subu	va0, t0, t1
+	jr	ra
 #endif /* USE_CLZ */
 
 /* It might seem better to do the 'beq' instruction between the two 'lbu'
    instructions so that the nop is not needed but testing showed that this
    code is actually faster (based on glibc strcmp test).  */
 #define BYTECMP01(OFFSET) \
-	lbu	v0, OFFSET(a0); \
-	lbu	v1, OFFSET(a1); \
-	beq	v0, zero, L(bexit01); \
+	lbu	vt1, OFFSET(a1); \
 	nop; \
-	bne	v0, v1, L(bexit01)
+	beq	vt0, zero, L(bexit01); \
+	lbu	t8, OFFSET+1(a0); \
+	bne	vt0, vt1, L(bexit01)
 
 #define BYTECMP89(OFFSET) \
-	lbu	t8, OFFSET(a0); \
 	lbu	t9, OFFSET(a1); \
-	beq	t8, zero, L(bexit89); \
 	nop;	\
+	beq	t8, zero, L(bexit89); \
+	lbu	vt0, OFFSET+1(a0); \
 	bne	t8, t9, L(bexit89)
 
 L(byteloop):
+	lbu	vt0, 0(a0)
 	BYTECMP01(0)
 	BYTECMP89(1)
 	BYTECMP01(2)
@@ -234,19 +218,21 @@  L(byteloop):
 	BYTECMP01(4)
 	BYTECMP89(5)
 	BYTECMP01(6)
-	BYTECMP89(7)
+	lbu	t9, 7(a1)
+	nop
+	beq	t8, zero, L(bexit89)
 	PTR_ADDIU a0, a0, 8
-	b	L(byteloop)
+	bne	t8, t9, L(bexit89)
 	PTR_ADDIU a1, a1, 8
+	b	L(byteloop)
 
 L(bexit01):
-	j	ra
-	subu	v0, v0, v1
+	subu	va0, vt0, vt1
+	jr	ra
 L(bexit89):
-	j	ra
-	subu	v0, t8, t9
+	subu	va0, t8, t9
+	jr	ra
 
 	.set	at
-	.set	reorder
 
 END(STRCMP_NAME)
diff --git a/newlib/libc/machine/mips/strlen.c b/newlib/libc/machine/mips/strlen.c
index a87bddd11..65cbaf3a6 100644
--- a/newlib/libc/machine/mips/strlen.c
+++ b/newlib/libc/machine/mips/strlen.c
@@ -33,27 +33,21 @@  strlen (const char *str)
 }
 #elif defined(__mips64)
 __asm__(""			/* 64-bit MIPS targets */
-	"	.set	noreorder\n"
-	"	.set	nomacro\n"
 	"	.globl	strlen\n"
 	"	.ent	strlen\n"
 	"strlen:\n"
 	"	daddiu	$2,$4,1\n"
 	"\n"
 	"1:	lbu	$3,0($4)\n"
-	"	bnez	$3,1b\n"
 	"	daddiu	$4,$4,1\n"
+	"	bnez	$3,1b\n"
 	"\n"
-	"	jr	$31\n"
 	"	dsubu	$2,$4,$2\n"
-	"	.end	strlen\n"
-	"	.set	macro\n"
-	"	.set	reorder\n");
+	"	jr	$31\n"
+	"	.end	strlen\n");
 
 #else
 __asm__(""			/* 32-bit MIPS targets */
-	"	.set	noreorder\n"
-	"	.set	nomacro\n"
 	"	.globl	strlen\n"
 	"	.ent	strlen\n"
 	"strlen:\n"
@@ -63,12 +57,10 @@  __asm__(""			/* 32-bit MIPS targets */
 #if defined(_R3000)
 	"	nop	\n"
 #endif
-	"	bnez	$3,1b\n"
 	"	addiu	$4,$4,1\n"
+	"	bnez	$3,1b\n"
 	"\n"
-	"	jr	$31\n"
 	"	subu	$2,$4,$2\n"
-	"	.end	strlen\n"
-	"	.set	macro\n"
-	"	.set	reorder\n");
+	"	jr	$31\n"
+	"	.end	strlen\n");
 #endif