Re: [PATCH 01/21] Add HAL for MIPS architecture

Jeff Johnston <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <CAOox84uBH_8C-rNKadDcyz=zOoRvO9srYJQYoP9n_b_OWsLO6A@mail.gmail.com>
A few things:

1. You are deleting crt0.S but crt0.o is referenced in various mips .ld
files and specified in Makefie.in.  Can you clarify?
2. You are adding platform-specific checks to generic libnosys and libgloss
fstat files.  Please clarify why this is being done since you have a
mips-specific fstat file.
3. abiflags.S doesn't have a license header
4. there appears to be examples directories added to mips and to top level
libgloss in this patch.  Plus, there is a Makefile without generation.

-- Jeff J.


On Thu, Oct 31, 2024 at 1:51 AM Aleksandar Rikalo <[email protected]> wrote:

> From: Jaydeep Patil <[email protected]>
>
> Signed-off-by: Jaydeep Patil <[email protected]>
> Signed-off-by: Aleksandar Rikalo <[email protected]>
> ---
>  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
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.