[PATCH 01/21] Add HAL for MIPS architecture

Aleksandar Rikalo arikalo@gmail.com
Thu Oct 31 05:49:17 GMT 2024


From: Jaydeep Patil <jaydeep.patil@imgtec.com>

Signed-off-by: Jaydeep Patil <jaydeep.patil@imgtec.com>
Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
---
 libgloss/config/mips.mt                       |   19 +
 libgloss/fstat.c                              |    3 +
 libgloss/libnosys/fstat.c                     |    3 +
 libgloss/mips/Makefile.in                     |   33 +
 libgloss/mips/crt0.S                          |  316 ----
 .../mips/examples/romable_predef_xip/Makefile |  107 ++
 .../examples/romable_predef_xip/README.txt    |   21 +
 .../romable_predef_xip/romable_predef_xip.c   |   35 +
 libgloss/mips/fstat.c                         |   32 +
 libgloss/mips/hal/__exit.c                    |   50 +
 libgloss/mips/hal/abiflags.S                  |   82 +
 libgloss/mips/hal/cache.h                     |   84 +
 libgloss/mips/hal/crt0.S                      |  313 ++++
 libgloss/mips/hal/get_ram_range.c             |   67 +
 libgloss/mips/hal/libcm3.a                    |   36 +
 libgloss/mips/hal/link.c                      |   41 +
 libgloss/mips/hal/minicrt.S                   |   31 +
 libgloss/mips/hal/mips64_tlb.c                |  221 +++
 libgloss/mips/hal/mips_clean_cache.c          |  115 ++
 libgloss/mips/hal/mips_cm3_l2size.c           |   90 +
 libgloss/mips/hal/mips_dsp.S                  |  130 ++
 libgloss/mips/hal/mips_excpt_boot.S           |  381 ++++
 libgloss/mips/hal/mips_excpt_entry.S          |  212 +++
 libgloss/mips/hal/mips_excpt_handler.c        |  308 ++++
 libgloss/mips/hal/mips_excpt_isr_fallback.S   |   52 +
 libgloss/mips/hal/mips_excpt_isr_fragment.S   |   73 +
 libgloss/mips/hal/mips_excpt_register.S       |  147 ++
 libgloss/mips/hal/mips_excpt_timer.S          |  103 ++
 libgloss/mips/hal/mips_flush_cache.c          |  108 ++
 libgloss/mips/hal/mips_fp.S                   |  184 ++
 libgloss/mips/hal/mips_intctrl.c              |  151 ++
 libgloss/mips/hal/mips_l2size.c               |   96 +
 libgloss/mips/hal/mips_lock_cache.c           |   83 +
 libgloss/mips/hal/mips_msa.S                  |  183 ++
 libgloss/mips/hal/mips_size_cache.c           |  108 ++
 libgloss/mips/hal/mips_sync_cache.c           |   64 +
 libgloss/mips/hal/mips_tlb.c                  |  479 +++++
 libgloss/mips/hal/mips_xpa.S                  |   78 +
 libgloss/mips/hal/syscalls.c                  |   51 +
 libgloss/mips/include/mips/asm.h              |  356 ++++
 libgloss/mips/include/mips/cm3.h              |   77 +
 libgloss/mips/include/mips/cpu.h              |  356 ++++
 libgloss/mips/include/mips/ctx.S              |  149 ++
 libgloss/mips/include/mips/dsp.h              |   60 +
 libgloss/mips/include/mips/endian.h           |   96 +
 libgloss/mips/include/mips/fgregdef.h         |  128 ++
 libgloss/mips/include/mips/fpa.h              |   33 +
 libgloss/mips/include/mips/hal.h              |  452 +++++
 libgloss/mips/include/mips/intctrl.h          |   71 +
 libgloss/mips/include/mips/m32c0.h            | 1607 +++++++++++++++++
 libgloss/mips/include/mips/m32c1.h            |  276 +++
 libgloss/mips/include/mips/m32tlb.h           |  103 ++
 libgloss/mips/include/mips/m64c0.h            |  268 +++
 libgloss/mips/include/mips/m64tlb.h           |  106 ++
 libgloss/mips/include/mips/mips32.h           |  177 ++
 libgloss/mips/include/mips/mips64.h           |  116 ++
 libgloss/mips/include/mips/mt.h               |  521 ++++++
 libgloss/mips/include/mips/notlb.h            |  115 ++
 libgloss/mips/include/mips/prid.h             |  130 ++
 libgloss/mips/include/mips/regdef.h           |  133 ++
 libgloss/mips/include/mips/version.h          |    4 +
 libgloss/mips/malta32-yamon.ld                |  318 ++++
 libgloss/mips/regs.S                          |    5 +-
 libgloss/mips/syscalls.c                      |   45 -
 libgloss/mips/uhi32.ld                        |  322 ++++
 libgloss/mips/uhi64_64.ld                     |  322 ++++
 libgloss/mips/uhi64_n32.ld                    |  322 ++++
 67 files changed, 10996 insertions(+), 362 deletions(-)
 delete mode 100644 libgloss/mips/crt0.S
 create mode 100644 libgloss/mips/examples/romable_predef_xip/Makefile
 create mode 100644 libgloss/mips/examples/romable_predef_xip/README.txt
 create mode 100644 libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
 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/version.h
 create mode 100644 libgloss/mips/malta32-yamon.ld
 delete mode 100644 libgloss/mips/syscalls.c
 create mode 100644 libgloss/mips/uhi32.ld
 create mode 100644 libgloss/mips/uhi64_64.ld
 create mode 100644 libgloss/mips/uhi64_n32.ld

diff --git a/libgloss/config/mips.mt b/libgloss/config/mips.mt
index 6ae84b44f..814caf957 100644
--- a/libgloss/config/mips.mt
+++ b/libgloss/config/mips.mt
@@ -29,3 +29,22 @@ unlink.o: ${srcdir}/../unlink.c
 	$(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
 write.o: ${srcdir}/../write.c
 	$(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+
+get_ram_range.o: ${srcdir}/hal/get_ram_range.c
+	$(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+link.o: $(srcdir)/hal/link.c
+	$(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
+
+# Exception and interrupt handling support
+mips_excpt_handler.o: $(srcdir)/hal/mips_excpt_handler.c
+	$(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -DVERBOSE_EXCEPTIONS=1 -O2 $(INCLUDES) -c $(CFLAGS) $<
+mips_excpt_handler_quiet.o: $(srcdir)/hal/mips_excpt_handler.c
+	$(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c $(CFLAGS) $< -o $@
+%.o: $(srcdir)/hal/%.S
+	$(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c $(CFLAGS) $< -o $@
+%.o: $(srcdir)/hal/%.c
+	$(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c $(CFLAGS) $< -o $@
+mips_excpt_isr_0.o:
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $(HALINCLUDE) -c -DDEF=__isr_vec_0 -DREF=__isr_vec_0 -DISR=_mips_isr_0 -DZERO ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@
+mips_excpt_isr_%.o:
+	$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $(HALINCLUDE) -c -DDEF=__isr_vec_$* -DREF=__isr_vec_$(shell expr $* - 1) -DISR=_mips_isr_$* ${srcdir}/hal/mips_excpt_isr_fragment.S -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/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..65581ec71 100644
--- a/libgloss/mips/Makefile.in
+++ b/libgloss/mips/Makefile.in
@@ -77,11 +77,44 @@ 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}
 
+define GENISROBJ
+$(eval ISROBJS:=)\
+$(if $(filter ${1},0),,\
+$(call GENISROBJ_DO,${1})\
+)\
+$(eval ISROBJS+=mips_excpt_isr_fallback.o)
+endef
+
+define GENISROBJ_DO
+$(if $(word ${1}, ${ISROBJS}),,\
+$(eval ISROBJS+=mips_excpt_isr_$(words $(ISROBJS)).o)\
+	$(call GENISROBJ_DO,${1})\
+)
+endef
+
+$(call GENISROBJ,256)
+
+HALOBJ = mips64_tlb.o mips_clean_cache.o mips_flush_cache.o mips_l2size.o \
+  mips_lock_cache.o mips_size_cache.o mips_sync_cache.o mips_tlb.o \
+  mips_fp.o mips_msa.o \
+  mips_excpt_entry.o mips_excpt_handler.o mips_excpt_handler_quiet.o \
+  mips_excpt_register.o mips_excpt_boot.o mips_xpa.o \
+  mips_intctrl.o $(ISROBJS)
+
+HALINCLUDE = -I $(srcdir)/include
+
+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 
 
+EXAMPLES = custom_excpt fault_recovery interrupt_handler isr_vector_space \
+	   romable romable_minimal romable_predef romable_predef_xip
+
 GCC_LDFLAGS = `if [ -d ${objroot}/../gcc ] ; \
 	then echo -L${objroot}/../gcc ; fi`
 
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/examples/romable_predef_xip/Makefile b/libgloss/mips/examples/romable_predef_xip/Makefile
new file mode 100644
index 000000000..c95b186db
--- /dev/null
+++ b/libgloss/mips/examples/romable_predef_xip/Makefile
@@ -0,0 +1,107 @@
+# Copyright 2015, Imagination Technologies Limited and/or its
+#                 affiliated group companies.
+# All rights reserved.
+#
+# 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.
+
+# Variables that mipshal.mk will expand to compiler/linker arguments must be
+# defined before inclusion of mipshal.mk
+
+# Indicate the application should start via the reset vector
+ROMABLE = 1
+
+ifeq ($(CORE), P5600)
+ DEFINES =  -DC0_CONFIG0_VALUE=0xB6040483
+ DEFINES += -DC0_CONFIG1_VALUE=0xFEA3519B
+ DEFINES += -DC0_CONFIG2_VALUE=0x80000000
+ DEFINES += -DC0_CONFIG3_VALUE=0xBF8032A8
+ DEFINES += -DC0_CONFIG4_VALUE=0xc01c0000
+ DEFINES += -DC0_CONFIG5_VALUE=0x10000038
+ DEFINES += -DC0_WATCHHI_VALUE=0x00000000
+ OBJS += init_l23caches_predef.o
+ override ABI = 32
+ override ENDIAN = EL
+ override MIPS_TOOLCHAIN = mips-mti-elf
+ APP_START = 0x80000000
+else
+ ifeq ($(CORE), I6400)
+  DEFINES =  -DC0_CONFIG0_VALUE=0x80004A05
+  DEFINES += -DC0_CONFIG1_VALUE=0x9EAB559B
+  DEFINES += -DC0_CONFIG2_VALUE=0x80000000
+  DEFINES += -DC0_CONFIG3_VALUE=0xFC8031E9
+  DEFINES += -DC0_CONFIG4_VALUE=0xD0FC0227
+  DEFINES += -DC0_CONFIG5_VALUE=0x00000098
+  DEFINES += -DC0_WATCHHI_VALUE=0x80000000
+  DEFINES += -DC0_WATCHHI1_VALUE=0x80000000
+  DEFINES += -DC0_WATCHHI2_VALUE=0x80000000
+  DEFINES += -DC0_WATCHHI3_VALUE=0x00000000
+  DEFINES += -DC0_CMGCRBASE_VALUE=0x01fbf800
+  DEFINES += -DGCR_L2_CONFIG_VALUE=0x00000000
+  OBJS = init_cm3l2_predef.o
+  override ABI = 64
+  override ENDIAN = EL
+  override MIPS_TOOLCHAIN = mips-img-elf
+  APP_START = 0xFFFFFFFF80000000
+ else
+  $(error Please specify a core using CORE=(P5600|I6400))
+ endif
+endif
+
+include ${MIPS_ELF_ROOT}/share/mips/rules/mipshal.mk
+
+ifeq ($(ENABLE_XPA), 1)
+  DEFINES += -DENABLE_XPA=1
+endif
+
+OBJS += romable_predef_xip.o reset_predef.o init_caches_predef.o init_cp0_predef.o
+OBJS += init_tlb_predef.o corecheck_predef.o
+APP = romable_predef_xip.elf
+
+CFLAGS += -g -O1 $(DEFINES)
+LDFLAGS += -g -Wl,--defsym,__getargs=0 -Wl,--defsym,__exception_handle_verbose=0
+LDFLAGS += -Wl,--defsym,__register_excpt_boot=0 -Wl,--defsym,__exception_entry=0
+LDFLAGS += -Wl,--defsym,__register_excpt_handler=0
+LDFLAGS += -Wl,--defsym,__isr_vec_007=0 -Wl,--defsym,__uhi_break=0
+LDFLAGS += -Wl,--defsym,__ebase_size=0 -Wl,--defsym,__isr_vec_count=0
+LDFLAGS += -Wl,--defsym,__xip=1
+LDFLAGS += -nostartfiles -nostdlib
+
+all: $(APP)
+
+$(APP): $(OBJS) crt0.o
+	$(LD) $(LDFLAGS) $(OBJS) -o $@
+
+%.o: %.c
+	$(CC) $(CFLAGS) -c $^ -o $@
+
+crt0.o: $(MIPS_ELF_ROOT)/share/mips/hal/minicrt.S
+	$(CC) $(CFLAGS) -c $^ -o $@
+
+%.o: $(MIPS_ELF_ROOT)/share/mips/boot/%.S
+	$(CC) $(CFLAGS) -c $^ -o $@
+
+.PHONY: clean
+clean:
+	rm -f $(APP) $(OBJS) crt0.o
diff --git a/libgloss/mips/examples/romable_predef_xip/README.txt b/libgloss/mips/examples/romable_predef_xip/README.txt
new file mode 100644
index 000000000..082e8c362
--- /dev/null
+++ b/libgloss/mips/examples/romable_predef_xip/README.txt
@@ -0,0 +1,21 @@
+Demonstration of a bootable example built for a specific cpu core, either the
+P5600 or I6400, relying on compile time CONFIG_XXX values for compile time
+specialization.  This variant produces boot code that eXecutes In Place (XIP)
+rather than copying code to RAM first.  It also eliminates all C runtime
+support code leading to a very thin image which puts restrictions on what C
+features can be used.  For example any code reliant on the HEAP is unsupported,
+constructors and destructors are unsupported and almost all standard library
+functions are unavailable for the above reasons.
+
+Set environment variable MIPS_ELF_ROOT
+	This should be set to the root of the installation directory for the
+	toolchain (that is, below the bin directory)
+
+To build for the P5600
+	# make CORE=P5600
+
+To build for the I6400
+	# make CORE=I6400
+
+To delete temporary and built files
+	# make clean CORE=P5600
diff --git a/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c b/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
new file mode 100644
index 000000000..b436eaed1
--- /dev/null
+++ b/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015, Imagination Technologies Limited and/or its
+ *                 affiliated group companies.
+ * All rights reserved.
+ *
+ * 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.
+*/
+
+int
+main ()
+{
+  return 0;
+}
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..d6f7c1a3b
--- /dev/null
+++ b/libgloss/mips/hal/__exit.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..a8350cc95
--- /dev/null
+++ b/libgloss/mips/hal/cache.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..07a5cc3ac
--- /dev/null
+++ b/libgloss/mips/hal/crt0.S
@@ -0,0 +1,313 @@
+/*
+ * crt0.S -- startup file for MIPS.
+ *
+ * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support
+ * Copyright 2016-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ *
+ * 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..0a484c303
--- /dev/null
+++ b/libgloss/mips/hal/get_ram_range.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..3d7534f57
--- /dev/null
+++ b/libgloss/mips/hal/libcm3.a
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015, Imagination Technologies Limited and/or its
+ *                 affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..56254c0b1
--- /dev/null
+++ b/libgloss/mips/hal/link.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..8bcaf1554
--- /dev/null
+++ b/libgloss/mips/hal/mips64_tlb.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                 affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..2b98307f3
--- /dev/null
+++ b/libgloss/mips/hal/mips_clean_cache.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                 affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..7006ecbeb
--- /dev/null
+++ b/libgloss/mips/hal/mips_cm3_l2size.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..a383ba739
--- /dev/null
+++ b/libgloss/mips/hal/mips_dsp.S
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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>
+#include <mips/endian.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..08ab1b579
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_boot.S
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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>
+#include <mips/endian.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..ddbd2bf9c
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_entry.S
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..4c83c9b0a
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_handler.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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:
+      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..d3afce8ec
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_isr_fallback.S
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..b7c50de3e
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_isr_fragment.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..1c6bdc04c
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_register.S
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..faccb4185
--- /dev/null
+++ b/libgloss/mips/hal/mips_excpt_timer.S
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..f651e6d51
--- /dev/null
+++ b/libgloss/mips/hal/mips_flush_cache.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..801ba79e2
--- /dev/null
+++ b/libgloss/mips/hal/mips_fp.S
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..e1e55b48b
--- /dev/null
+++ b/libgloss/mips/hal/mips_intctrl.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                 affiliated group companies.
+ * All rights reserved.
+ *
+ * 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/endian.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..960205ba3
--- /dev/null
+++ b/libgloss/mips/hal/mips_l2size.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..475e2e84c
--- /dev/null
+++ b/libgloss/mips/hal/mips_lock_cache.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..3d59fa179
--- /dev/null
+++ b/libgloss/mips/hal/mips_msa.S
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2015-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..74a2c49f0
--- /dev/null
+++ b/libgloss/mips/hal/mips_size_cache.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..69425fa46
--- /dev/null
+++ b/libgloss/mips/hal/mips_sync_cache.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..eb43c0483
--- /dev/null
+++ b/libgloss/mips/hal/mips_tlb.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..5f47e8ff3
--- /dev/null
+++ b/libgloss/mips/hal/mips_xpa.S
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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>
+#include <mips/endian.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/include/mips/asm.h b/libgloss/mips/include/mips/asm.h
new file mode 100644
index 000000000..ac9157511
--- /dev/null
+++ b/libgloss/mips/include/mips/asm.h
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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
+
+#ifdef __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..251d39782
--- /dev/null
+++ b/libgloss/mips/include/mips/cm3.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..067e1a14c
--- /dev/null
+++ b/libgloss/mips/include/mips/cpu.h
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..2257f0e33
--- /dev/null
+++ b/libgloss/mips/include/mips/ctx.S
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2016-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..b10c98561
--- /dev/null
+++ b/libgloss/mips/include/mips/dsp.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..057af7e19
--- /dev/null
+++ b/libgloss/mips/include/mips/endian.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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_ENDIAN_H_
+#define _MIPS_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
+
+#include <machine/endian.h>
+
+#endif /*_MIPS_ENDIAN_H_*/
diff --git a/libgloss/mips/include/mips/fgregdef.h b/libgloss/mips/include/mips/fgregdef.h
new file mode 100644
index 000000000..b36ea159f
--- /dev/null
+++ b/libgloss/mips/include/mips/fgregdef.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..93dde7184
--- /dev/null
+++ b/libgloss/mips/include/mips/fpa.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..b161dfb89
--- /dev/null
+++ b/libgloss/mips/include/mips/hal.h
@@ -0,0 +1,452 @@
+/*
+ * Copyright 2014-2018, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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)
+
+#ifndef __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);
+
+#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..7e6c00097
--- /dev/null
+++ b/libgloss/mips/include/mips/intctrl.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..67c2c37bd
--- /dev/null
+++ b/libgloss/mips/include/mips/m32c0.h
@@ -0,0 +1,1607 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..e33837c2b
--- /dev/null
+++ b/libgloss/mips/include/mips/m32c1.h
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..0abd99dde
--- /dev/null
+++ b/libgloss/mips/include/mips/m32tlb.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..2fc0203ea
--- /dev/null
+++ b/libgloss/mips/include/mips/m64c0.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..86b0e58aa
--- /dev/null
+++ b/libgloss/mips/include/mips/m64tlb.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2015-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..20e31a2e7
--- /dev/null
+++ b/libgloss/mips/include/mips/mips32.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..03b608e2e
--- /dev/null
+++ b/libgloss/mips/include/mips/mips64.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..91a75f28c
--- /dev/null
+++ b/libgloss/mips/include/mips/mt.h
@@ -0,0 +1,521 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..2a6c1b439
--- /dev/null
+++ b/libgloss/mips/include/mips/notlb.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..2bf017cf1
--- /dev/null
+++ b/libgloss/mips/include/mips/prid.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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..f901c3043
--- /dev/null
+++ b/libgloss/mips/include/mips/regdef.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2014-2017, Imagination Technologies Limited and/or its
+ *                      affiliated group companies.
+ * All rights reserved.
+ *
+ * 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/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..5175071c2
--- /dev/null
+++ b/libgloss/mips/malta32-yamon.ld
@@ -0,0 +1,318 @@
+/*
+ * 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 the interrupt handlers to be included in the link */
+EXTERN(__isr_vec)
+/* 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/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/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)) }
+}
-- 
2.25.1



More information about the Newlib mailing list