[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