[01/21] Add HAL for MIPS architecture

Message ID 20241031054937.68189-2-arikalo@gmail.com
State New
Headers
Series A series of updates related to MIPS |

Commit Message

Aleksandar Rikalo Oct. 31, 2024, 5:49 a.m. UTC
  From: Jaydeep Patil <jaydeep.patil@imgtec.com>

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

Comments

Jeff Johnston Nov. 4, 2024, 11:21 p.m. UTC | #1
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 <arikalo@gmail.com> wrote:

> From: Jaydeep Patil <jaydeep.patil@imgtec.com>
>
> Signed-off-by: Jaydeep Patil <jaydeep.patil@imgtec.com>
> Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
> ---
>  libgloss/config/mips.mt                       |   19 +
>  libgloss/fstat.c                              |    3 +
>  libgloss/libnosys/fstat.c                     |    3 +
>  libgloss/mips/Makefile.in                     |   33 +
>  libgloss/mips/crt0.S                          |  316 ----
>  .../mips/examples/romable_predef_xip/Makefile |  107 ++
>  .../examples/romable_predef_xip/README.txt    |   21 +
>  .../romable_predef_xip/romable_predef_xip.c   |   35 +
>  libgloss/mips/fstat.c                         |   32 +
>  libgloss/mips/hal/__exit.c                    |   50 +
>  libgloss/mips/hal/abiflags.S                  |   82 +
>  libgloss/mips/hal/cache.h                     |   84 +
>  libgloss/mips/hal/crt0.S                      |  313 ++++
>  libgloss/mips/hal/get_ram_range.c             |   67 +
>  libgloss/mips/hal/libcm3.a                    |   36 +
>  libgloss/mips/hal/link.c                      |   41 +
>  libgloss/mips/hal/minicrt.S                   |   31 +
>  libgloss/mips/hal/mips64_tlb.c                |  221 +++
>  libgloss/mips/hal/mips_clean_cache.c          |  115 ++
>  libgloss/mips/hal/mips_cm3_l2size.c           |   90 +
>  libgloss/mips/hal/mips_dsp.S                  |  130 ++
>  libgloss/mips/hal/mips_excpt_boot.S           |  381 ++++
>  libgloss/mips/hal/mips_excpt_entry.S          |  212 +++
>  libgloss/mips/hal/mips_excpt_handler.c        |  308 ++++
>  libgloss/mips/hal/mips_excpt_isr_fallback.S   |   52 +
>  libgloss/mips/hal/mips_excpt_isr_fragment.S   |   73 +
>  libgloss/mips/hal/mips_excpt_register.S       |  147 ++
>  libgloss/mips/hal/mips_excpt_timer.S          |  103 ++
>  libgloss/mips/hal/mips_flush_cache.c          |  108 ++
>  libgloss/mips/hal/mips_fp.S                   |  184 ++
>  libgloss/mips/hal/mips_intctrl.c              |  151 ++
>  libgloss/mips/hal/mips_l2size.c               |   96 +
>  libgloss/mips/hal/mips_lock_cache.c           |   83 +
>  libgloss/mips/hal/mips_msa.S                  |  183 ++
>  libgloss/mips/hal/mips_size_cache.c           |  108 ++
>  libgloss/mips/hal/mips_sync_cache.c           |   64 +
>  libgloss/mips/hal/mips_tlb.c                  |  479 +++++
>  libgloss/mips/hal/mips_xpa.S                  |   78 +
>  libgloss/mips/hal/syscalls.c                  |   51 +
>  libgloss/mips/include/mips/asm.h              |  356 ++++
>  libgloss/mips/include/mips/cm3.h              |   77 +
>  libgloss/mips/include/mips/cpu.h              |  356 ++++
>  libgloss/mips/include/mips/ctx.S              |  149 ++
>  libgloss/mips/include/mips/dsp.h              |   60 +
>  libgloss/mips/include/mips/endian.h           |   96 +
>  libgloss/mips/include/mips/fgregdef.h         |  128 ++
>  libgloss/mips/include/mips/fpa.h              |   33 +
>  libgloss/mips/include/mips/hal.h              |  452 +++++
>  libgloss/mips/include/mips/intctrl.h          |   71 +
>  libgloss/mips/include/mips/m32c0.h            | 1607 +++++++++++++++++
>  libgloss/mips/include/mips/m32c1.h            |  276 +++
>  libgloss/mips/include/mips/m32tlb.h           |  103 ++
>  libgloss/mips/include/mips/m64c0.h            |  268 +++
>  libgloss/mips/include/mips/m64tlb.h           |  106 ++
>  libgloss/mips/include/mips/mips32.h           |  177 ++
>  libgloss/mips/include/mips/mips64.h           |  116 ++
>  libgloss/mips/include/mips/mt.h               |  521 ++++++
>  libgloss/mips/include/mips/notlb.h            |  115 ++
>  libgloss/mips/include/mips/prid.h             |  130 ++
>  libgloss/mips/include/mips/regdef.h           |  133 ++
>  libgloss/mips/include/mips/version.h          |    4 +
>  libgloss/mips/malta32-yamon.ld                |  318 ++++
>  libgloss/mips/regs.S                          |    5 +-
>  libgloss/mips/syscalls.c                      |   45 -
>  libgloss/mips/uhi32.ld                        |  322 ++++
>  libgloss/mips/uhi64_64.ld                     |  322 ++++
>  libgloss/mips/uhi64_n32.ld                    |  322 ++++
>  67 files changed, 10996 insertions(+), 362 deletions(-)
>  delete mode 100644 libgloss/mips/crt0.S
>  create mode 100644 libgloss/mips/examples/romable_predef_xip/Makefile
>  create mode 100644 libgloss/mips/examples/romable_predef_xip/README.txt
>  create mode 100644
> libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
>  create mode 100644 libgloss/mips/fstat.c
>  create mode 100644 libgloss/mips/hal/__exit.c
>  create mode 100644 libgloss/mips/hal/abiflags.S
>  create mode 100644 libgloss/mips/hal/cache.h
>  create mode 100644 libgloss/mips/hal/crt0.S
>  create mode 100644 libgloss/mips/hal/get_ram_range.c
>  create mode 100644 libgloss/mips/hal/libcm3.a
>  create mode 100644 libgloss/mips/hal/link.c
>  create mode 100644 libgloss/mips/hal/minicrt.S
>  create mode 100644 libgloss/mips/hal/mips64_tlb.c
>  create mode 100644 libgloss/mips/hal/mips_clean_cache.c
>  create mode 100644 libgloss/mips/hal/mips_cm3_l2size.c
>  create mode 100644 libgloss/mips/hal/mips_dsp.S
>  create mode 100644 libgloss/mips/hal/mips_excpt_boot.S
>  create mode 100644 libgloss/mips/hal/mips_excpt_entry.S
>  create mode 100644 libgloss/mips/hal/mips_excpt_handler.c
>  create mode 100644 libgloss/mips/hal/mips_excpt_isr_fallback.S
>  create mode 100644 libgloss/mips/hal/mips_excpt_isr_fragment.S
>  create mode 100644 libgloss/mips/hal/mips_excpt_register.S
>  create mode 100644 libgloss/mips/hal/mips_excpt_timer.S
>  create mode 100644 libgloss/mips/hal/mips_flush_cache.c
>  create mode 100644 libgloss/mips/hal/mips_fp.S
>  create mode 100644 libgloss/mips/hal/mips_intctrl.c
>  create mode 100644 libgloss/mips/hal/mips_l2size.c
>  create mode 100644 libgloss/mips/hal/mips_lock_cache.c
>  create mode 100644 libgloss/mips/hal/mips_msa.S
>  create mode 100644 libgloss/mips/hal/mips_size_cache.c
>  create mode 100644 libgloss/mips/hal/mips_sync_cache.c
>  create mode 100644 libgloss/mips/hal/mips_tlb.c
>  create mode 100644 libgloss/mips/hal/mips_xpa.S
>  create mode 100644 libgloss/mips/hal/syscalls.c
>  create mode 100644 libgloss/mips/include/mips/asm.h
>  create mode 100644 libgloss/mips/include/mips/cm3.h
>  create mode 100644 libgloss/mips/include/mips/cpu.h
>  create mode 100644 libgloss/mips/include/mips/ctx.S
>  create mode 100644 libgloss/mips/include/mips/dsp.h
>  create mode 100644 libgloss/mips/include/mips/endian.h
>  create mode 100644 libgloss/mips/include/mips/fgregdef.h
>  create mode 100644 libgloss/mips/include/mips/fpa.h
>  create mode 100644 libgloss/mips/include/mips/hal.h
>  create mode 100644 libgloss/mips/include/mips/intctrl.h
>  create mode 100644 libgloss/mips/include/mips/m32c0.h
>  create mode 100644 libgloss/mips/include/mips/m32c1.h
>  create mode 100644 libgloss/mips/include/mips/m32tlb.h
>  create mode 100644 libgloss/mips/include/mips/m64c0.h
>  create mode 100644 libgloss/mips/include/mips/m64tlb.h
>  create mode 100644 libgloss/mips/include/mips/mips32.h
>  create mode 100644 libgloss/mips/include/mips/mips64.h
>  create mode 100644 libgloss/mips/include/mips/mt.h
>  create mode 100644 libgloss/mips/include/mips/notlb.h
>  create mode 100644 libgloss/mips/include/mips/prid.h
>  create mode 100644 libgloss/mips/include/mips/regdef.h
>  create mode 100644 libgloss/mips/include/mips/version.h
>  create mode 100644 libgloss/mips/malta32-yamon.ld
>  delete mode 100644 libgloss/mips/syscalls.c
>  create mode 100644 libgloss/mips/uhi32.ld
>  create mode 100644 libgloss/mips/uhi64_64.ld
>  create mode 100644 libgloss/mips/uhi64_n32.ld
>
> diff --git a/libgloss/config/mips.mt b/libgloss/config/mips.mt
> index 6ae84b44f..814caf957 100644
> --- a/libgloss/config/mips.mt
> +++ b/libgloss/config/mips.mt
> @@ -29,3 +29,22 @@ unlink.o: ${srcdir}/../unlink.c
>         $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
>  write.o: ${srcdir}/../write.c
>         $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
> +
> +get_ram_range.o: ${srcdir}/hal/get_ram_range.c
> +       $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
> +link.o: $(srcdir)/hal/link.c
> +       $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $?
> +
> +# Exception and interrupt handling support
> +mips_excpt_handler.o: $(srcdir)/hal/mips_excpt_handler.c
> +       $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -DVERBOSE_EXCEPTIONS=1
> -O2 $(INCLUDES) -c $(CFLAGS) $<
> +mips_excpt_handler_quiet.o: $(srcdir)/hal/mips_excpt_handler.c
> +       $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c
> $(CFLAGS) $< -o $@
> +%.o: $(srcdir)/hal/%.S
> +       $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c
> $(CFLAGS) $< -o $@
> +%.o: $(srcdir)/hal/%.c
> +       $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c
> $(CFLAGS) $< -o $@
> +mips_excpt_isr_0.o:
> +       $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $(HALINCLUDE) -c
> -DDEF=__isr_vec_0 -DREF=__isr_vec_0 -DISR=_mips_isr_0 -DZERO
> ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@
> +mips_excpt_isr_%.o:
> +       $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $(HALINCLUDE) -c
> -DDEF=__isr_vec_$* -DREF=__isr_vec_$(shell expr $* - 1) -DISR=_mips_isr_$*
> ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@
> diff --git a/libgloss/fstat.c b/libgloss/fstat.c
> index c9d14d103..d8f94af6f 100644
> --- a/libgloss/fstat.c
> +++ b/libgloss/fstat.c
> @@ -19,6 +19,9 @@
>   * fstat -- Since we have no file system, we just return an error.
>   */
>  int
> +#if defined(__mips__) && defined(__mips16)
> +__attribute__((nomips16))
> +#endif
>  fstat (int fd,
>         struct stat *buf)
>  {
> diff --git a/libgloss/libnosys/fstat.c b/libgloss/libnosys/fstat.c
> index c85b9f209..e3d4cec64 100644
> --- a/libgloss/libnosys/fstat.c
> +++ b/libgloss/libnosys/fstat.c
> @@ -13,6 +13,9 @@ extern int errno;
>  #include "warning.h"
>
>  int
> +#if defined(__mips__) && defined(__mips16)
> +__attribute__((nomips16))
> +#endif
>  _fstat (int          fildes,
>          struct stat *st)
>  {
> diff --git a/libgloss/mips/Makefile.in b/libgloss/mips/Makefile.in
> index 4213a1d1f..65581ec71 100644
> --- a/libgloss/mips/Makefile.in
> +++ b/libgloss/mips/Makefile.in
> @@ -77,11 +77,44 @@ JMR3904OBJS = jmr3904-io.o @MIPS_PART_SPECIFIC_OBJ@
> ${GENOBJS} ${GENOBJS2}
>  CFEOBJS = cfe.o cfe_api.o cfe_mem.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
> ${GENOBJS2}
>  CYGMONOBJS = open.o close.o cygmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
>
> +define GENISROBJ
> +$(eval ISROBJS:=)\
> +$(if $(filter ${1},0),,\
> +$(call GENISROBJ_DO,${1})\
> +)\
> +$(eval ISROBJS+=mips_excpt_isr_fallback.o)
> +endef
> +
> +define GENISROBJ_DO
> +$(if $(word ${1}, ${ISROBJS}),,\
> +$(eval ISROBJS+=mips_excpt_isr_$(words $(ISROBJS)).o)\
> +       $(call GENISROBJ_DO,${1})\
> +)
> +endef
> +
> +$(call GENISROBJ,256)
> +
> +HALOBJ = mips64_tlb.o mips_clean_cache.o mips_flush_cache.o mips_l2size.o
> \
> +  mips_lock_cache.o mips_size_cache.o mips_sync_cache.o mips_tlb.o \
> +  mips_fp.o mips_msa.o \
> +  mips_excpt_entry.o mips_excpt_handler.o mips_excpt_handler_quiet.o \
> +  mips_excpt_register.o mips_excpt_boot.o mips_xpa.o \
> +  mips_intctrl.o $(ISROBJS)
> +
> +HALINCLUDE = -I $(srcdir)/include
> +
> +CM3OBJ_IMPL = mips_cm3_l2size.o init_cm3l2.o
> +
> +CM3AR = libcm3.a
> +
>  # Nullmon cannot support read and write, but the test cases pull them in
> via libs
>  NULLMONOBJS = nullmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS}
>
>  CFLAGS = -g
>
> +EXAMPLES = custom_excpt fault_recovery interrupt_handler isr_vector_space
> \
> +          romable romable_minimal romable_predef romable_predef_xip
> +
>  GCC_LDFLAGS = `if [ -d ${objroot}/../gcc ] ; \
>         then echo -L${objroot}/../gcc ; fi`
>
> diff --git a/libgloss/mips/crt0.S b/libgloss/mips/crt0.S
> deleted file mode 100644
> index 254998242..000000000
> --- a/libgloss/mips/crt0.S
> +++ /dev/null
> @@ -1,316 +0,0 @@
> -/*
> - * crt0.S -- startup file for MIPS.
> - *
> - * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support
> - *
> - * The authors hereby grant permission to use, copy, modify, distribute,
> - * and license this software and its documentation for any purpose,
> provided
> - * that existing copyright notices are retained in all copies and that
> this
> - * notice is included verbatim in any distributions. No written agreement,
> - * license, or royalty fee is required for any of the authorized uses.
> - * Modifications to this software may be copyrighted by their authors
> - * and need not follow the licensing terms described here, provided that
> - * the new terms are clearly indicated on the first page of each file
> where
> - * they apply.
> - */
> -
> -/* This file does not use any floating-point ABI.  */
> -       .gnu_attribute 4,0
> -
> -#ifdef __mips16
> -/* This file contains 32 bit assembly code.  */
> -       .set nomips16
> -#endif
> -
> -#include "regs.S"
> -#include "abiflags.S"
> -
> -/*
> - * Set up some room for a stack. We just grab a chunk of memory.
> - */
> -#define STACK_SIZE  0x4000
> -#define GLOBAL_SIZE 0x2000
> -
> -#define STARTUP_STACK_SIZE     0x0100
> -
> -/* This is for referencing addresses that are not in the .sdata or
> -   .sbss section under embedded-pic, or before we've set up gp.  */
> -#ifdef __mips_embedded_pic
> -# ifdef __mips64
> -#  define LA(t,x) la t,x-PICBASE ; daddu t,s0,t
> -# else
> -#  define LA(t,x) la t,x-PICBASE ; addu t,s0,t
> -# endif
> -#else /* __mips_embedded_pic */
> -# define LA(t,x) la t,x
> -#endif /* __mips_embedded_pic */
> -
> -       .comm   __memsize, 12
> -       .comm   __lstack, STARTUP_STACK_SIZE
> -
> -       .text
> -       .align  2
> -
> -/* Without the following nop, GDB thinks _start is a data variable.
> - * This is probably a bug in GDB in handling a symbol that is at the
> - * start of the .text section.
> - */
> -       nop
> -
> -       .globl  hardware_hazard_hook .text
> -       .globl  _start
> -       .ent    _start
> -_start:
> -#ifdef __mips_embedded_pic
> -#define PICBASE start_PICBASE
> -       .set    noreorder
> -       PICBASE = .+8
> -        bal    PICBASE
> -       nop
> -       move    s0,$31
> -       .set    reorder
> -#endif
> -#if __mips<3
> -#  define STATUS_MASK (SR_CU1|SR_PE)
> -#else
> -/* Post-mips2 has no SR_PE bit.  */
> -#  ifdef __mips64
> -/* Turn on 64-bit addressing and additional float regs.  */
> -#    define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX)
> -#  else
> -#    if __mips_fpr==32
> -#      define STATUS_MASK (SR_CU1)
> -#    else
> -/* Turn on additional float regs.  */
> -#      define STATUS_MASK (SR_CU1|SR_FR)
> -#    endif
> -#  endif
> -#endif
> -
> -       /* Clear Cause register.  */
> -       mtc0    zero,C0_CAUSE
> -       nop
> -
> -       /* Read MIPS_abiflags structure and set status/config registers
> -          accordingly.  */
> -       .weak   __MIPS_abiflags_start
> -       .weak   __MIPS_abiflags_end
> -       LA      (t0,__MIPS_abiflags_start)
> -       LA      (t1,__MIPS_abiflags_end)
> -       addiu   t1,t1,-24
> -       move    v0,zero                 /* Mask for C0_SR.  */
> -
> -       /* Branch to 1f is the .MIPS.abiflags section is not 24 bytes.
> This
> -          indicates it is either missing or corrupt.  */
> -       bne     t0,t1,1f
> -
> -       /* Check isa_level.  */
> -       lbu     t1,ABIFlags_isa_level(t0)
> -       sltu    v1,t1,3                 /* Is MIPS < 3?  */
> -       xori    t1,t1,64                /* Is MIPS64?  */
> -       beq     v1,zero,4f
> -       li      v1,SR_PE
> -       or      v0,v0,v1                /* Enable soft reset.  */
> -4:
> -       li      v1,(SR_KX|SR_SX|SR_UX)
> -       bne     t1,zero,5f
> -       or      v0,v0,v1                /* Enable extended addressing.  */
> -5:
> -       /* Check fp_abi.  */
> -       lbu     t1,ABIFlags_fp_abi(t0)
> -       xori    t1,t1,Val_GNU_MIPS_ABI_FP_SOFT
> -       li      v1,SR_CU1
> -       beq     t1,zero,2f              /* Skip MSA and cpr1_size checks.
> */
> -       or      v0,v0,v1                /* Enable co-processor 1.  */
> -
> -       /* Check cpr1_size.  */
> -       lbu     t1,ABIFlags_cpr1_size(t0)
> -       xori    t1,t1,AFL_REG_64
> -       li      v1,SR_FR
> -       bne     t1,zero,3f
> -       or      v0,v0,v1                /* Enable 64-bit FPU registers.  */
> -3:
> -       /* Check ases.  */
> -       lw      t1,ABIFlags_ases(t0)
> -       andi    t1,t1,AFL_ASE_MSA
> -       li      v1,SR_FR
> -       beq     t1,zero,2f
> -       or      v0,v0,v1                /* Enable 64-bit FPU registers.  */
> -       li      v1,SR_MSA
> -       .set    push
> -       .set    mips32
> -       mtc0    v1,C0_CONFIG,5          /* Enable MSA.  */
> -       .set    pop
> -       b       2f
> -
> -1:
> -       /* MIPS_abiflags structure is not available.  Set status/config
> -          registers based on flags defined by compiler.  */
> -#ifdef __mips_soft_float
> -       li      v0,(STATUS_MASK-(STATUS_MASK & SR_CU1))
> -#else
> -       li      v0,STATUS_MASK
> -#endif
> -
> -2:
> -       /* Set C0_SR,  */
> -       mtc0    v0,C0_SR
> -       nop
> -
> -       /* Avoid hazard from C0_SR changes.  */
> -       LA      (t0, hardware_hazard_hook)
> -       beq     t0,zero,2f
> -       jalr    t0
> -2:
> -
> -
> -/* Fix high bits, if any, of the PC so that exception handling doesn't get
> -   confused.  */
> -       LA (v0, 3f)
> -       jr      v0
> -3:
> -       LA (gp, _gp)                            # set the global data
> pointer
> -       .end _start
> -
> -/*
> - * zero out the bss section.
> - */
> -       .globl  __memsize
> -       .globl  get_mem_info .text
> -       .globl  __stack
> -       .globl  __global
> -       .ent    zerobss
> -zerobss:
> -       LA (v0, _fbss)
> -       LA (v1, _end)
> -       beq     v0,v1,2f
> -1:
> -       addiu   v0,v0,4
> -       sw      zero,-4(v0)
> -       bne     v0,v1,1b
> -2:
> -       la      t0, __lstack                    # make a small stack so we
> -       addiu   sp, t0, STARTUP_STACK_SIZE      # can run some C code
> -       la      a0, __memsize                   # get the usable memory
> size
> -       jal     get_mem_info
> -
> -       /* setup the stack pointer */
> -       LA (t0, __stack)                        # is __stack set ?
> -       bne     t0,zero,4f
> -
> -       /* NOTE: a0[0] contains the amount of memory available, and
> -                not the last memory address. */
> -       la      a0, __memsize
> -       lw      t0,0(a0)                        # last address of memory
> available
> -       la      t1,K0BASE                       # cached kernel memory
> -       addu    t0,t0,t1                        # get the end of memory
> address
> -       /* Allocate 32 bytes for the register parameters.  Allocate 16
> -          bytes for a null argv and envp.  Round the result up to 64
> -          bytes to preserve alignment.  */
> -       subu    t0,t0,64
> -4:
> -       move    sp,t0                           # set stack pointer
> -       .end    zerobss
> -
> -/*
> - * initialize target specific stuff. Only execute these
> - * functions it they exist.
> - */
> -       .globl  hardware_init_hook .text
> -       .globl  software_init_hook .text
> -       .type   _fini,@function
> -       .type   _init,@function
> -       .globl  atexit .text
> -       .globl  exit .text
> -       .ent    init
> -init:
> -       LA (t9, hardware_init_hook)             # init the hardware if
> needed
> -       beq     t9,zero,6f
> -       jalr    t9
> -6:
> -       LA (t9, software_init_hook)             # init the hardware if
> needed
> -       beq     t9,zero,7f
> -       jalr    t9
> -7:
> -       LA (a0, _fini)
> -       jal     atexit
> -
> -#ifdef GCRT0
> -       .globl  _ftext
> -       .globl  _extext
> -       LA (a0, _ftext)
> -       LA (a1, _etext)
> -       jal     monstartup
> -#endif
> -
> -
> -       jal     _init                           # run global constructors
> -
> -       addiu   a1,sp,32                        # argv = sp + 32
> -       addiu   a2,sp,40                        # envp = sp + 40
> -#if __mips64
> -       sd      zero,(a1)                       # argv[argc] = 0
> -       sd      zero,(a2)                       # envp[0] = 0
> -#else
> -       sw      zero,(a1)
> -       sw      zero,(a2)
> -#endif
> -       move    a0,zero                         # set argc to 0
> -       jal     main                            # call the program start
> function
> -
> -       # fall through to the "exit" routine
> -       move    a0,v0                           # pass through the exit
> code
> -       jal     exit                            # call libc exit to run
> the G++
> -                                               # destructors
> -       .end    init
> -
> -
> -/* Assume the PICBASE set up above is no longer valid below here.  */
> -#ifdef __mips_embedded_pic
> -#undef PICBASE
> -#endif
> -
> -/*
> - * _exit -- Exit from the application. Normally we cause a user trap
> - *          to return to the ROM monitor for another run. NOTE: This is
> - *         the only other routine we provide in the crt0.o object, since
> - *          it may be tied to the "_start" routine. It also allows
> - *          executables that contain a complete world to be linked with
> - *          just the crt0.o object.
> - */
> -       .globl  hardware_exit_hook .text
> -       .globl  _exit
> -       .ent _exit
> -_exit:
> -7:
> -#ifdef __mips_embedded_pic
> -       /* Need to reinit PICBASE, since we might be called via exit()
> -          rather than via a return path which would restore old s0.  */
> -#define PICBASE exit_PICBASE
> -       .set    noreorder
> -       PICBASE = .+8
> -       bal     PICBASE
> -       nop
> -       move    s0,$31
> -       .set    reorder
> -#endif
> -#ifdef GCRT0
> -       LA (t0, _mcleanup)
> -       jalr    t0
> -#endif
> -       LA (t0, hardware_exit_hook)
> -       beq     t0,zero,1f
> -       jalr    t0
> -1:
> -
> -       # break instruction can cope with 0xfffff, but GAS limits the
> range:
> -       break   1023
> -       b       7b                              # but loop back just
> in-case
> -       .end _exit
> -
> -/* Assume the PICBASE set up above is no longer valid below here.  */
> -#ifdef __mips_embedded_pic
> -#undef PICBASE
> -#endif
> -
> -/* EOF crt0.S */
> diff --git a/libgloss/mips/examples/romable_predef_xip/Makefile
> b/libgloss/mips/examples/romable_predef_xip/Makefile
> new file mode 100644
> index 000000000..c95b186db
> --- /dev/null
> +++ b/libgloss/mips/examples/romable_predef_xip/Makefile
> @@ -0,0 +1,107 @@
> +# Copyright 2015, Imagination Technologies Limited and/or its
> +#                 affiliated group companies.
> +# All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions are
> met:
> +#
> +# 1. Redistributions of source code must retain the above copyright
> notice,
> +# this list of conditions and the following disclaimer.
> +# 2. Redistributions in binary form must reproduce the above copyright
> notice,
> +# this list of conditions and the following disclaimer in the
> documentation
> +# and/or other materials provided with the distribution.
> +# 3. Neither the name of the copyright holder nor the names of its
> +# contributors may be used to endorse or promote products derived from
> this
> +# software without specific prior written permission.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
> IS"
> +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> +# POSSIBILITY OF SUCH DAMAGE.
> +
> +# Variables that mipshal.mk will expand to compiler/linker arguments
> must be
> +# defined before inclusion of mipshal.mk
> +
> +# Indicate the application should start via the reset vector
> +ROMABLE = 1
> +
> +ifeq ($(CORE), P5600)
> + DEFINES =  -DC0_CONFIG0_VALUE=0xB6040483
> + DEFINES += -DC0_CONFIG1_VALUE=0xFEA3519B
> + DEFINES += -DC0_CONFIG2_VALUE=0x80000000
> + DEFINES += -DC0_CONFIG3_VALUE=0xBF8032A8
> + DEFINES += -DC0_CONFIG4_VALUE=0xc01c0000
> + DEFINES += -DC0_CONFIG5_VALUE=0x10000038
> + DEFINES += -DC0_WATCHHI_VALUE=0x00000000
> + OBJS += init_l23caches_predef.o
> + override ABI = 32
> + override ENDIAN = EL
> + override MIPS_TOOLCHAIN = mips-mti-elf
> + APP_START = 0x80000000
> +else
> + ifeq ($(CORE), I6400)
> +  DEFINES =  -DC0_CONFIG0_VALUE=0x80004A05
> +  DEFINES += -DC0_CONFIG1_VALUE=0x9EAB559B
> +  DEFINES += -DC0_CONFIG2_VALUE=0x80000000
> +  DEFINES += -DC0_CONFIG3_VALUE=0xFC8031E9
> +  DEFINES += -DC0_CONFIG4_VALUE=0xD0FC0227
> +  DEFINES += -DC0_CONFIG5_VALUE=0x00000098
> +  DEFINES += -DC0_WATCHHI_VALUE=0x80000000
> +  DEFINES += -DC0_WATCHHI1_VALUE=0x80000000
> +  DEFINES += -DC0_WATCHHI2_VALUE=0x80000000
> +  DEFINES += -DC0_WATCHHI3_VALUE=0x00000000
> +  DEFINES += -DC0_CMGCRBASE_VALUE=0x01fbf800
> +  DEFINES += -DGCR_L2_CONFIG_VALUE=0x00000000
> +  OBJS = init_cm3l2_predef.o
> +  override ABI = 64
> +  override ENDIAN = EL
> +  override MIPS_TOOLCHAIN = mips-img-elf
> +  APP_START = 0xFFFFFFFF80000000
> + else
> +  $(error Please specify a core using CORE=(P5600|I6400))
> + endif
> +endif
> +
> +include ${MIPS_ELF_ROOT}/share/mips/rules/mipshal.mk
> +
> +ifeq ($(ENABLE_XPA), 1)
> +  DEFINES += -DENABLE_XPA=1
> +endif
> +
> +OBJS += romable_predef_xip.o reset_predef.o init_caches_predef.o
> init_cp0_predef.o
> +OBJS += init_tlb_predef.o corecheck_predef.o
> +APP = romable_predef_xip.elf
> +
> +CFLAGS += -g -O1 $(DEFINES)
> +LDFLAGS += -g -Wl,--defsym,__getargs=0
> -Wl,--defsym,__exception_handle_verbose=0
> +LDFLAGS += -Wl,--defsym,__register_excpt_boot=0
> -Wl,--defsym,__exception_entry=0
> +LDFLAGS += -Wl,--defsym,__register_excpt_handler=0
> +LDFLAGS += -Wl,--defsym,__isr_vec_007=0 -Wl,--defsym,__uhi_break=0
> +LDFLAGS += -Wl,--defsym,__ebase_size=0 -Wl,--defsym,__isr_vec_count=0
> +LDFLAGS += -Wl,--defsym,__xip=1
> +LDFLAGS += -nostartfiles -nostdlib
> +
> +all: $(APP)
> +
> +$(APP): $(OBJS) crt0.o
> +       $(LD) $(LDFLAGS) $(OBJS) -o $@
> +
> +%.o: %.c
> +       $(CC) $(CFLAGS) -c $^ -o $@
> +
> +crt0.o: $(MIPS_ELF_ROOT)/share/mips/hal/minicrt.S
> +       $(CC) $(CFLAGS) -c $^ -o $@
> +
> +%.o: $(MIPS_ELF_ROOT)/share/mips/boot/%.S
> +       $(CC) $(CFLAGS) -c $^ -o $@
> +
> +.PHONY: clean
> +clean:
> +       rm -f $(APP) $(OBJS) crt0.o
> diff --git a/libgloss/mips/examples/romable_predef_xip/README.txt
> b/libgloss/mips/examples/romable_predef_xip/README.txt
> new file mode 100644
> index 000000000..082e8c362
> --- /dev/null
> +++ b/libgloss/mips/examples/romable_predef_xip/README.txt
> @@ -0,0 +1,21 @@
> +Demonstration of a bootable example built for a specific cpu core, either
> the
> +P5600 or I6400, relying on compile time CONFIG_XXX values for compile time
> +specialization.  This variant produces boot code that eXecutes In Place
> (XIP)
> +rather than copying code to RAM first.  It also eliminates all C runtime
> +support code leading to a very thin image which puts restrictions on what
> C
> +features can be used.  For example any code reliant on the HEAP is
> unsupported,
> +constructors and destructors are unsupported and almost all standard
> library
> +functions are unavailable for the above reasons.
> +
> +Set environment variable MIPS_ELF_ROOT
> +       This should be set to the root of the installation directory for
> the
> +       toolchain (that is, below the bin directory)
> +
> +To build for the P5600
> +       # make CORE=P5600
> +
> +To build for the I6400
> +       # make CORE=I6400
> +
> +To delete temporary and built files
> +       # make clean CORE=P5600
> diff --git
> a/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
> b/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
> new file mode 100644
> index 000000000..b436eaed1
> --- /dev/null
> +++ b/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c
> @@ -0,0 +1,35 @@
> +/*
> + * Copyright 2015, Imagination Technologies Limited and/or its
> + *                 affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +int
> +main ()
> +{
> +  return 0;
> +}
> diff --git a/libgloss/mips/fstat.c b/libgloss/mips/fstat.c
> new file mode 100644
> index 000000000..d8f94af6f
> --- /dev/null
> +++ b/libgloss/mips/fstat.c
> @@ -0,0 +1,32 @@
> +/* fstat.c -- get status of a file.
> + *
> + * Copyright (c) 1995 Cygnus Support
> + *
> + * The authors hereby grant permission to use, copy, modify, distribute,
> + * and license this software and its documentation for any purpose,
> provided
> + * that existing copyright notices are retained in all copies and that
> this
> + * notice is included verbatim in any distributions. No written agreement,
> + * license, or royalty fee is required for any of the authorized uses.
> + * Modifications to this software may be copyrighted by their authors
> + * and need not follow the licensing terms described here, provided that
> + * the new terms are clearly indicated on the first page of each file
> where
> + * they apply.
> + */
> +#include <sys/stat.h>
> +#include "glue.h"
> +
> +/*
> + * fstat -- Since we have no file system, we just return an error.
> + */
> +int
> +#if defined(__mips__) && defined(__mips16)
> +__attribute__((nomips16))
> +#endif
> +fstat (int fd,
> +       struct stat *buf)
> +{
> +  buf->st_mode = S_IFCHR;      /* Always pretend to be a tty */
> +  buf->st_blksize = 0;
> +
> +  return (0);
> +}
> diff --git a/libgloss/mips/hal/__exit.c b/libgloss/mips/hal/__exit.c
> new file mode 100644
> index 000000000..d6f7c1a3b
> --- /dev/null
> +++ b/libgloss/mips/hal/__exit.c
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +/*
> + * @Synopsis     void __exit (int32_t exit_code);
> + *
> + *               Parameters:
> + *                 $4 - Exit code
> + *
> + *               Return:
> + *                 None
> + *
> + * @Description  Transfer control to the debug port
> +*/
> +
> +#include <stdint.h>
> +
> +void
> +__exit (int32_t exit_code)
> +{
> +  return;
> +}
> +
> diff --git a/libgloss/mips/hal/abiflags.S b/libgloss/mips/hal/abiflags.S
> new file mode 100644
> index 000000000..953caafb4
> --- /dev/null
> +++ b/libgloss/mips/hal/abiflags.S
> @@ -0,0 +1,82 @@
> +/*
> + * abiflags.S - MIPS ABI flags.
> + */
> +
> +/* Values for the xxx_size bytes of an ABI flags structure.  */
> +#define AFL_REG_NONE         0x00       /* No registers.  */
> +#define AFL_REG_32           0x01       /* 32-bit registers.  */
> +#define AFL_REG_64           0x02       /* 64-bit registers.  */
> +#define AFL_REG_128          0x03       /* 128-bit registers.  */
> +
> +/* Masks for the ases word of an ABI flags structure.  */
> +#define AFL_ASE_DSP          0x00000001  /* DSP ASE.  */
> +#define AFL_ASE_DSPR2        0x00000002  /* DSP R2 ASE.  */
> +#define AFL_ASE_EVA          0x00000004  /* Enhanced VA Scheme.  */
> +#define AFL_ASE_MCU          0x00000008  /* MCU (MicroController) ASE.  */
> +#define AFL_ASE_MDMX         0x00000010  /* MDMX ASE.  */
> +#define AFL_ASE_MIPS3D       0x00000020  /* MIPS-3D ASE.  */
> +#define AFL_ASE_MT           0x00000040  /* MT ASE.  */
> +#define AFL_ASE_SMARTMIPS    0x00000080  /* SmartMIPS ASE.  */
> +#define AFL_ASE_VIRT         0x00000100  /* VZ ASE.  */
> +#define AFL_ASE_MSA          0x00000200  /* MSA ASE.  */
> +#define AFL_ASE_MIPS16       0x00000400  /* MIPS16 ASE.  */
> +#define AFL_ASE_MICROMIPS    0x00000800  /* MICROMIPS ASE.  */
> +#define AFL_ASE_XPA          0x00001000  /* XPA ASE.  */
> +
> +/* Values for the isa_ext word of an ABI flags structure.  */
> +#define AFL_EXT_XLR           1  /* RMI Xlr instruction.  */
> +#define AFL_EXT_OCTEON2       2  /* Cavium Networks Octeon2.  */
> +#define AFL_EXT_OCTEONP       3  /* Cavium Networks OcteonP.  */
> +#define AFL_EXT_LOONGSON_3A   4  /* Loongson 3A.  */
> +#define AFL_EXT_OCTEON        5  /* Cavium Networks Octeon.  */
> +#define AFL_EXT_5900          6  /* MIPS R5900 instruction.  */
> +#define AFL_EXT_4650          7  /* MIPS R4650 instruction.  */
> +#define AFL_EXT_4010          8  /* LSI R4010 instruction.  */
> +#define AFL_EXT_4100          9  /* NEC VR4100 instruction.  */
> +#define AFL_EXT_3900         10  /* Toshiba R3900 instruction.  */
> +#define AFL_EXT_10000        11  /* MIPS R10000 instruction.  */
> +#define AFL_EXT_SB1          12  /* Broadcom SB-1 instruction.  */
> +#define AFL_EXT_4111         13  /* NEC VR4111/VR4181 instruction.  */
> +#define AFL_EXT_4120         14  /* NEC VR4120 instruction.  */
> +#define AFL_EXT_5400         15  /* NEC VR5400 instruction.  */
> +#define AFL_EXT_5500         16  /* NEC VR5500 instruction.  */
> +#define AFL_EXT_LOONGSON_2E  17  /* ST Microelectronics Loongson 2E.  */
> +#define AFL_EXT_LOONGSON_2F  18  /* ST Microelectronics Loongson 2F.  */
> +
> +/* Values defined for Tag_GNU_MIPS_ABI_FP.  */
> +#define Val_GNU_MIPS_ABI_FP_ANY    0  /* Not tagged or not using any ABIs
> affected by the differences.  */
> +#define Val_GNU_MIPS_ABI_FP_DOUBLE 1  /* Using hard-float
> -mdouble-float.  */
> +#define Val_GNU_MIPS_ABI_FP_SINGLE 2  /* Using hard-float
> -msingle-float.  */
> +#define Val_GNU_MIPS_ABI_FP_SOFT   3  /* Using soft-float.  */
> +#define Val_GNU_MIPS_ABI_FP_OLD_64 4  /* Using -mips32r2 -mfp64.  */
> +#define Val_GNU_MIPS_ABI_FP_XX     5  /* Using -mfpxx */
> +#define Val_GNU_MIPS_ABI_FP_64     6  /* Using -mips32r2 -mfp64.  */
> +#define Val_GNU_MIPS_ABI_MSA_ANY   0  /* Not tagged or not using any ABIs
> affected by the differences.  */
> +#define Val_GNU_MIPS_ABI_MSA_128   1  /* Using 128-bit MSA.  */
> +
> +/* MIPS ABI flags structure */
> +  .struct 0
> +ABIFlags_version:
> +  .struct ABIFlags_version + 2
> +ABIFlags_isa_level:
> +  .struct ABIFlags_isa_level + 1
> +ABIFlags_isa_rev:
> +  .struct ABIFlags_isa_rev + 1
> +ABIFlags_gpr_size:
> +  .struct ABIFlags_gpr_size + 1
> +ABIFlags_cpr1_size:
> +  .struct ABIFlags_cpr1_size + 1
> +ABIFlags_cpr2_size:
> +  .struct ABIFlags_cpr2_size + 1
> +ABIFlags_fp_abi:
> +  .struct ABIFlags_fp_abi + 1
> +ABIFlags_isa_ext:
> +  .struct ABIFlags_isa_ext + 4
> +ABIFlags_ases:
> +  .struct ABIFlags_ases + 4
> +ABIFlags_flags1:
> +  .struct ABIFlags_flags1 + 4
> +ABIFlags_flags2:
> +  .struct ABIFlags_flags2 + 4
> +
> +/*> EOF abiflags.S <*/
> diff --git a/libgloss/mips/hal/cache.h b/libgloss/mips/hal/cache.h
> new file mode 100644
> index 000000000..a8350cc95
> --- /dev/null
> +++ b/libgloss/mips/hal/cache.h
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#define __MIPS_NO_IMPLICIT_EHB /* No implicit EHB after mtc0 */
> +#include <mips/cpu.h>
> +#include <mips/cm3.h>
> +#include <mips/m32c0.h>
> +#include <mips/m64c0.h>
> +#include <mips/hal.h>
> +
> +#if defined(__mips64) || (__mips == 64)
> +#define mips_getentryhi()      mips64_getentryhi()
> +#define mips_setentryhi(v)     mips64_setentryhi(v)
> +#define mips_getentrylo0()     mips64_getentrylo0()
> +#define mips_setentrylo0(v)    mips64_setentrylo0(v)
> +#define mips_getentrylo1()     mips64_getentrylo1()
> +#define mips_setentrylo1(v)    mips64_setentrylo1(v)
> +#define mips_getpagemask()     mips64_getpagemask()
> +#define mips_setpagemask(v)    mips64_setpagemask(v)
> +#define mips_getindex()                mips64_getindex()
> +#define mips_setindex(v)       mips64_setindex(v)
> +#define mips_getcmgcrbase()    mips64_get_c0(C0_CMGCRBASE)
> +#else
> +#define mips_getentryhi()      mips32_getentryhi()
> +#define mips_setentryhi(v)     mips32_setentryhi(v)
> +#define mips_getentrylo0()     mips32_getentrylo0()
> +#define mips_setentrylo0(v)    mips32_setentrylo0(v)
> +#define mips_getentrylo1()     mips32_getentrylo1()
> +#define mips_setentrylo1(v)    mips32_setentrylo1(v)
> +#define mips_getpagemask()     mips32_getpagemask()
> +#define mips_setpagemask(v)    mips32_setpagemask(v)
> +#define mips_getindex()                mips32_getindex()
> +#define mips_setindex(v)       mips32_setindex(v)
> +#define mips_getcmgcrbase()    mips32_get_c0(C0_CMGCRBASE)
> +#endif
> +
> +static inline __attribute__((always_inline)) _MIPS_HAL_NOMIPS16
> +void mips_cache_op (vaddr_t kva, size_t n, int lsize, const int op)
> +{
> +  vaddr_t addr, maxaddr, mask;
> +
> +  if (n <= 0)
> +    return;
> +
> +  mask = ~ (lsize - 1);
> +  addr = (kva & mask) - lsize;
> +  maxaddr = ((kva + n) - 1) & mask;
> +
> +  do
> +    {
> +      addr = addr + lsize;
> +      mips_cache (op, addr);
> +    }
> +  while (addr != maxaddr);
> +
> +  return;
> +}
> diff --git a/libgloss/mips/hal/crt0.S b/libgloss/mips/hal/crt0.S
> new file mode 100644
> index 000000000..07a5cc3ac
> --- /dev/null
> +++ b/libgloss/mips/hal/crt0.S
> @@ -0,0 +1,313 @@
> +/*
> + * crt0.S -- startup file for MIPS.
> + *
> + * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support
> + * Copyright 2016-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + *
> + * The authors hereby grant permission to use, copy, modify, distribute,
> + * and license this software and its documentation for any purpose,
> provided
> + * that existing copyright notices are retained in all copies and that
> this
> + * notice is included verbatim in any distributions. No written agreement,
> + * license, or royalty fee is required for any of the authorized uses.
> + * Modifications to this software may be copyrighted by their authors
> + * and need not follow the licensing terms described here, provided that
> + * the new terms are clearly indicated on the first page of each file
> where
> + * they apply.
> + */
> +
> +/* This file does not use any floating-point ABI.  */
> +       .gnu_attribute 4,0
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include "abiflags.S"
> +
> +MIPS_NOMIPS16
> +
> +#define STARTUP_STACK_SIZE     0x40      /* Temporary stack size to run C
> code */
> +
> +       .section .startdata, "aw", @nobits
> +       .balign 16
> +       .space  STARTUP_STACK_SIZE
> +__lstack: # Points to the end of the stack
> +__ram_extent:
> +       .space 8
> +
> +       .data
> +
> +       .balign SZREG
> +__temp_space:     /* Temporary space to save arguments */
> +       .space  SZREG * 3
> +
> +       .text
> +       .align  2
> +
> +/*
> + * Without the following nop, GDB thinks _start is a data variable.
> + * This is probably a bug in GDB in handling a symbol that is at the
> + * start of the .text section.
> + */
> +       nop
> +
> +       .globl  hardware_hazard_hook .text
> +       .globl  _start
> +       .ent    _start
> +_start:
> +#if __mips<3
> +#  define STATUS_MASK (SR_CU1|SR_PE)
> +#else
> +/* Post-mips2 has no SR_PE bit.  */
> +#  ifdef __mips64
> +/* Turn on 64-bit addressing and additional float regs.  */
> +#    define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX)
> +#  else
> +#    if __mips_fpr==32
> +#      define STATUS_MASK (SR_CU1)
> +#    else
> +/* Turn on additional float regs.  */
> +#      define STATUS_MASK (SR_CU1|SR_FR)
> +#    endif
> +#  endif
> +#endif
> +
> +       /* Save argument registers */
> +       LA      t0, __temp_space
> +       REG_S   a0, (SZREG * 0)(t0)
> +       REG_S   a1, (SZREG * 1)(t0)
> +       REG_S   a2, (SZREG * 2)(t0)
> +
> +       /*
> +        * Save k0, k1, ra and sp and register
> +        * default exception handler.
> +       */
> +       .weak   __register_excpt_handler
> +       LA      t9, __register_excpt_handler
> +       beqz    t9, 1f
> +       move    a0, ra          /* save ra */
> +       jalr    t9
> +       b       2f
> +1:
> +       /* Clear Cause register.  */
> +       mtc0    zero,C0_CAUSE
> +       move    va0,zero                        /* Mask for C0_SR.  */
> +2:
> +       /* Read MIPS_abiflags structure and set status/config registers
> +          accordingly.  */
> +       .weak   __MIPS_abiflags_start
> +       .weak   __MIPS_abiflags_end
> +       LA      t0,__MIPS_abiflags_start
> +       LA      t1,__MIPS_abiflags_end
> +       PTR_ADDU t1,t1,-24
> +
> +       /* Branch to 1f is the .MIPS.abiflags section is not 24 bytes.
> This
> +          indicates it is either missing or corrupt.  */
> +       bne     t0,t1,1f
> +
> +       /* Check isa_level.  */
> +       lbu     t1,ABIFlags_isa_level(t0)
> +       sltu    t2,t1,3                 /* Is MIPS < 3?  */
> +       xori    t1,t1,64                /* Is MIPS64?  */
> +       beq     t2,zero,3f
> +       li      t2,SR_PE
> +       or      va0,va0,t2              /* Enable soft reset.  */
> +3:
> +       li      t2,(SR_KX|SR_SX|SR_UX)
> +       bne     t1,zero,3f
> +       or      va0,va0,t2              /* Enable extended addressing.  */
> +3:
> +       /* Check DSP,DSP2,MDMX ase. */
> +       lw      t1,ABIFlags_ases(t0)
> +       andi    t1,t1,(AFL_ASE_DSP|AFL_ASE_DSPR2|AFL_ASE_MDMX)
> +       li      t2,SR_MX
> +       beq     t1,zero,3f
> +       or      va0,va0,t2
> +3:
> +       /* Check fp_abi.  */
> +       lbu     t1,ABIFlags_fp_abi(t0)
> +       xori    t1,t1,Val_GNU_MIPS_ABI_FP_SOFT
> +       li      t2,SR_CU1
> +       beq     t1,zero,2f              /* Skip MSA and cpr1_size checks.
> */
> +       or      va0,va0,t2              /* Enable co-processor 1.  */
> +
> +       /* Check cpr1_size.  */
> +       lbu     t1,ABIFlags_cpr1_size(t0)
> +       xori    t1,t1,AFL_REG_64
> +       li      t2,SR_FR
> +       bne     t1,zero,3f
> +       or      va0,va0,t2              /* Enable 64-bit FPU registers.  */
> +3:
> +       /* Check MSA ASE.  */
> +       lw      t1,ABIFlags_ases(t0)
> +       andi    t1,t1,AFL_ASE_MSA
> +       li      t2,SR_FR
> +       beq     t1,zero,2f
> +       or      va0,va0,t2              /* Enable 64-bit FPU registers.  */
> +       li      t2,CFG5_MSAEN
> +       mtc0    t2,C0_CONFIG,5          /* Enable MSA.  */
> +       b       2f
> +
> +1:
> +       /* MIPS_abiflags structure is not available.  Set status/config
> +          registers based on flags defined by compiler.  */
> +#ifdef __mips_soft_float
> +       li      va0,(STATUS_MASK-(STATUS_MASK & SR_CU1))
> +#else
> +       li      va0,STATUS_MASK
> +#endif
> +
> +2:
> +       /* Set C0_SR,  */
> +       mtc0    va0,C0_SR
> +       ehb
> +
> +       /* set the global data pointer */
> +       LA      gp, _gp
> +       .end _start
> +
> +/*
> + * zero out the bss section.
> + */
> +       .globl  _get_ram_info .text
> +       .globl  __stack
> +       .globl  __global
> +       .ent    zerobss
> +zerobss:
> +       LA      t0, _fbss
> +       LA      t1, _end
> +       beq     t0,t1,1f
> +2:
> +       PTR_ADDU t0,t0,4
> +       sw      zero,-4(t0)
> +       bne     t0,t1,2b
> +1:
> +       /* setup the stack pointer */
> +       LA      t0, __stack                     /* is __stack set? */
> +       bne     t0,zero,1f
> +
> +       LA      sp, __lstack                    /* make a small stack so
> we can */
> +                                               /* run some C code */
> +       li      a0,0                            /* no need for the ram
> base */
> +       LA      a1, __ram_extent                /* storage for the extent
> of ram */
> +       jal     _get_ram_range
> +
> +       /* NOTE: a0[0] contains the last address+1 of memory. */
> +       LA      a0, __ram_extent
> +       PTR_L   t0,0(a0)                        /* the extent of ram */
> +       lw      $0,-4(t0)                       /* check for valid memory
> */
> +       /* Allocate 32 bytes for the register parameters.  Allocate 16
> +          bytes for a null argv and envp.  Round the result up to 64
> +          bytes to preserve alignment.  */
> +1:
> +       PTR_ADDU t0,t0,-64
> +       move    sp,t0                           /* set stack pointer */
> +       .end    zerobss
> +
> +/*
> + * initialize target specific stuff. Only execute these
> + * functions it they exist.
> + */
> +       .globl  hardware_init_hook .text
> +       .globl  software_init_hook .text
> +       .type   _fini,@function
> +       .type   _init,@function
> +       .globl  atexit .text
> +       .globl  exit .text
> +       .ent    init
> +init:
> +       /* Init the hardware if needed */
> +       LA      t9, hardware_init_hook
> +       beq     t9,zero,1f
> +       jalr    t9
> +1:
> +       /* Init the software if needed */
> +       LA      t9, software_init_hook
> +       beq     t9,zero,1f
> +       jalr    t9
> +1:
> +       /* Register exit handlers */
> +       LA      a0, _fini
> +       jal     atexit
> +
> +       /* run global constructors */
> +       jal     _init
> +
> +       /* Restore argument registers */
> +       LA      t0, __temp_space
> +       REG_L   a0,(SZREG * 0)(t0)
> +       REG_L   a1,(SZREG * 1)(t0)
> +       REG_L   a2,(SZREG * 2)(t0)
> +
> +       /* Convert pointers potentially */
> +       .weak   __convert_argv_pointers
> +       LA      t0, __convert_argv_pointers
> +       beqz    t0, 1f
> +       jalr    t0
> +1:
> +       /* if a0 > 0 then we have arguments ready in a0 to a2 registers */
> +       bgtz    a0,.Lmain
> +       /* if a0 == 0 then no arguments have been set up */
> +       beqz    a0, 1f
> +       /* if a0 < -1 then we have undefined behaviour so assume no
> +          arguments have been set up */
> +       addiu   t0, a0, 1
> +       bltz    t0, 1f
> +
> +       /* a0 == -1 */
> +       .weak   __getargs
> +       LA      t0, __getargs
> +       beqz    t0, 1f
> +       jalr    t0                              /* get arguments */
> +       b       .Lmain
> +1:
> +       /* no arguments */
> +       move    a0,zero                         /* set argc to 0 */
> +       PTR_ADDU a1,sp,32                       /* argv = sp + 32 */
> +       PTR_ADDU a2,sp,40                       /* envp = sp + 40 */
> +       REG_S   zero,(a1)                       /* argv[argc] = 0 */
> +       REG_S   zero,(a2)                       /* envp[0] = 0 */
> +
> +.Lmain:
> +       jal     main                            /* call the program start
> function */
> +       move    a0,va0                          /* pass through the exit
> code */
> +       jal     exit                            /* call libc exit to run
> the G++ */
> +                                               /* destructors */
> +       .end    init
> +
> +/*
> + * _exit -- Exit from the application. Normally we cause a user trap
> + *          to return to the ROM monitor for another run. NOTE: This is
> + *         the only other routine we provide in the crt0.o object, since
> + *          it may be tied to the "_start" routine. It also allows
> + *          executables that contain a complete world to be linked with
> + *          just the crt0.o object.
> + */
> +       .globl  hardware_exit_hook .text
> +       .globl  _exit
> +       .ent _exit
> +_exit:
> +1:
> +       /* Save exit code */
> +       LA      t0, __temp_space
> +       REG_S   a0,0(t0)
> +
> +       LA      t0, hardware_exit_hook
> +       beq     t0,zero,2f
> +       jalr    t0
> +2:
> +
> +       /* Restore return value from main */
> +       LA      t0, __temp_space
> +       REG_L   a0,0(t0)
> +
> +       .global __exit .text
> +       jal     __exit
> +
> +       /* The BREAK instruction can cope with 0xfffff, but GAS limits the
> +          range */
> +       break   1023
> +       b       1b                              # but loop back just
> in-case
> +       .end _exit
> +
> +/* EOF crt0.S */
> diff --git a/libgloss/mips/hal/get_ram_range.c
> b/libgloss/mips/hal/get_ram_range.c
> new file mode 100644
> index 000000000..0a484c303
> --- /dev/null
> +++ b/libgloss/mips/hal/get_ram_range.c
> @@ -0,0 +1,67 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <_ansi.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +
> +#if _MIPS_SIM == _ABI64
> +# define K0BASE 0xFFFFFFFF80000000LL
> +#else
> +# define K0BASE 0x80000000
> +#endif
> +void
> +_get_ram_range (void **ram_base, void **ram_extent)
> +{
> +  struct s_mem
> +  {
> +    unsigned int size;
> +    unsigned int icsize;
> +    unsigned int dcsize;
> +  } mem;
> +  void get_mem_info (struct s_mem*);
> +
> +  /* The sizeof (s_mem.size) must be 4 bytes.  The compiler should be
> +     able to eliminate this check */
> +  if (sizeof (unsigned int) != 4)
> +    {
> +      *ram_extent = 0;
> +      return;
> +    }
> +
> +  get_mem_info (&mem);
> +
> +  /* NOTE: The value returned from the get_mem_info call is the amount
> +     of memory, and not the address of the (last byte + 1) */
> +
> +  if (ram_base)
> +    *ram_base = (void*)K0BASE;
> +  *ram_extent = (void*)(long)(K0BASE + mem.size);
> +}
> diff --git a/libgloss/mips/hal/libcm3.a b/libgloss/mips/hal/libcm3.a
> new file mode 100644
> index 000000000..3d7534f57
> --- /dev/null
> +++ b/libgloss/mips/hal/libcm3.a
> @@ -0,0 +1,36 @@
> +/*
> + * Copyright 2015, Imagination Technologies Limited and/or its
> + *                 affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +/*
> + * libcm3.a - Create a reference to __cache_size_hook near the
> + * start of the link to include the actual implementation.
> + */
> +EXTERN (__cache_size_hook);
> +GROUP(-lcm3_impl);
> diff --git a/libgloss/mips/hal/link.c b/libgloss/mips/hal/link.c
> new file mode 100644
> index 000000000..56254c0b1
> --- /dev/null
> +++ b/libgloss/mips/hal/link.c
> @@ -0,0 +1,41 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <errno.h>
> +
> +int
> +link (const char *oldname, const char *newname)
> +{
> +  (void) oldname;
> +  (void) newname;
> +  errno = EIO;
> +  return -1;
> +}
> +
> diff --git a/libgloss/mips/hal/minicrt.S b/libgloss/mips/hal/minicrt.S
> new file mode 100644
> index 000000000..fa4759499
> --- /dev/null
> +++ b/libgloss/mips/hal/minicrt.S
> @@ -0,0 +1,31 @@
> +#include <mips/asm.h>
> +#include <mips/regdef.h>
> +
> +LEAF(_start)
> +       /* Preserve return address */
> +       move s0, ra
> +       /* Set up global pointer for small data access */
> +       LA gp, _gp
> +       /* Set up stack pointer */
> +       LA sp, __stack
> +       /* Zero the BSS */
> +       LA v0, _fbss
> +       LA v1, _end
> +       beq v0,v1,2f
> +1:
> +       addiu v0,v0,4
> +       sw zero,-4(v0)
> +       bne v0,v1,1b
> +2:
> +       /* Set arguments to be null for main */
> +       li a0, 0
> +
> +       /* Reserve the ABI required argument area */
> +       addiu sp, sp, -(NARGSAVE * SZARG)
> +       /* Jump to C code */
> +       jal main
> +
> +       /* Return to boot */
> +       move ra, s0
> +       jr ra
> +END(_start)
> diff --git a/libgloss/mips/hal/mips64_tlb.c
> b/libgloss/mips/hal/mips64_tlb.c
> new file mode 100644
> index 000000000..8bcaf1554
> --- /dev/null
> +++ b/libgloss/mips/hal/mips64_tlb.c
> @@ -0,0 +1,221 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                 affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +#include <mips/hal.h>
> +
> +/* Writes hi, lo0, lo1 and mask into the TLB entry specified by index */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +m64_tlbwi2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
> +           unsigned long long mask,
> +           int index)
> +{
> +  mips64_setentryhi (hi);
> +  mips64_setentrylo0 (lo0);
> +  mips64_setentrylo1 (lo1);
> +  mips64_setpagemask (mask);
> +  mips64_setindex (index);
> +  mips_ehb ();
> +  mips_tlbwi ();
> +  return;
> +}
> +
> +/*
> + * Writes hi, lo0, lo1 and mask into the TLB entry specified by the
> + * Random register.
> +*/
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +m64_tlbwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
> +           unsigned long long mask)
> +{
> +  mips64_setentryhi (hi);
> +  mips64_setentrylo0 (lo0);
> +  mips64_setentrylo1 (lo1);
> +  mips64_setpagemask (mask);
> +  mips_ehb ();
> +  mips_tlbwr ();
> +  return;
> +}
> +
> +/*
> + * Probes the TLB for an entry matching hi and if present rewrites that
> entry,
> + * otherwise updates a random entry. A safe way to update the TLB.
> +*/
> +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +m64_tlbrwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
> +            unsigned long long mask)
> +{
> +  tlbhi64_t prev_hi;
> +  int index;
> +
> +  prev_hi = mips64_getentryhi ();
> +  mips64_setentryhi (hi);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbp ();
> +  mips_ehb (); /* tlbp hazard on mfc0 */
> +
> +  index = mips64_getindex ();
> +
> +  mips64_setentrylo0 (lo0);
> +  mips64_setentrylo1 (lo1);
> +  mips64_setpagemask (mask);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbwi/tlbwr */
> +
> +  if (index < 0)
> +    mips_tlbwr ();
> +  else
> +    mips_tlbwi ();
> +
> +  mips64_setentryhi (prev_hi);
> +
> +  return index;
> +}
> +
> +/*
> + * Reads the TLB entry specified index, and returns the EntryHi,
> + * EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmask
> + * respectively.
> +*/
> +void _MIPS_HAL_NOMIPS16
> +m64_tlbri2 (tlbhi64_t *phi, tlblo64_t *plo0, tlblo64_t *plo1,
> +           unsigned long long *pmask, int index)
> +{
> +  mips64_setindex (index);
> +  mips_ehb (); /* mtc0 hazard on tlbr */
> +  mips_tlbr ();
> +  mips_ehb (); /* tlbr hazard on mfc0 */
> +  *phi = mips64_getentryhi ();
> +  *plo0 = mips64_getentrylo0 ();
> +  *plo1 = mips64_getentrylo1 ();
> +  *pmask = mips64_getpagemask ();
> +  return;
> +}
> +
> +/*
> + * Probes the TLB for an entry matching hi and returns its index, or -1 if
> + * not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of
> the
> + * entry are also returned in *plo0, *plo1 and *pmask respectively.
> +*/
> +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +m64_tlbprobe2 (tlbhi64_t hi, tlblo64_t *plo0, tlblo64_t *plo1,
> +              unsigned long long *pmask)
> +{
> +  tlbhi64_t prev_hi;
> +  int index;
> +
> +  prev_hi = mips64_getentryhi ();
> +  mips64_setentryhi (hi);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbp ();
> +  mips_ehb (); /* tlbp hazard on mfc0 */
> +
> +  index = mips64_getindex ();
> +
> +  if (index >= 0)
> +    {
> +      mips_tlbr ();
> +      mips_ehb ();     /* tlbr hazard on mfc0 */
> +      *plo0 = mips64_getentrylo0 ();
> +      *plo1 = mips64_getentrylo1 ();
> +      *pmask = mips64_getpagemask ();
> +    }
> +  else
> +    index = -1;
> +
> +  mips64_setentryhi (prev_hi);
> +
> +  return index;
> +}
> +
> +/* Probes the TLB for an entry matching hi, and if present invalidates it
> */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +m64_tlbinval (tlbhi64_t hi)
> +{
> +  int index, tmp_idx;
> +  tlbhi64_t prev_hi, tmp_hi;
> +  register const unsigned long zero = 0;
> +  unsigned long cfg;
> +
> +  prev_hi = mips64_getentryhi ();
> +  mips64_setentryhi (hi);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbp ();
> +  mips_ehb (); /* tlbp hazard on mfc0 */
> +
> +  index = mips64_getindex ();
> +
> +  if (index < 0)
> +    goto restore;
> +
> +  mips64_setentrylo0 (zero);
> +  mips64_setentrylo1 (zero);
> +
> +  /* Check if Config4 is implemented */
> +  cfg = mips64_getconfig3 ();
> +  if ((cfg & CFG3_M) != 0)
> +    {
> +      cfg = mips64_getconfig4 ();
> +      if ((cfg & CFG4_IE_MASK) != 0)
> +       {
> +         tmp_hi = C0_ENTRYHI_EHINV_MASK;
> +         goto do_tlbwi;
> +       }
> +    }
> +
> +  tmp_hi = (tlbhi64_t) ((unsigned long) KSEG0_BASE - 0x4000);
> +
> +  do
> +    {
> +      tmp_hi = tmp_hi + 0x4000;
> +      mips64_setentryhi (tmp_hi);
> +      mips_ehb ();             /* mtc0 hazard on tlbp */
> +      mips_tlbp ();
> +      mips_ehb ();             /* tlbp hazard on mfc0 */
> +      tmp_idx = mips64_getindex ();
> +    }
> +  while (tmp_idx >= 0);
> +
> +  mips64_setindex (index);     /* restore Index */
> +
> +do_tlbwi:
> +  mips64_setentryhi (tmp_hi);
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbwi ();
> +  mips_ehb (); /* tlbwi hazard on mfc0 */
> +
> +restore:
> +  mips64_setentryhi (prev_hi); /* restore EntryHi */
> +
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_clean_cache.c
> b/libgloss/mips/hal/mips_clean_cache.c
> new file mode 100644
> index 000000000..2b98307f3
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_clean_cache.c
> @@ -0,0 +1,115 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                 affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <mips/hal.h>
> +#include "cache.h"
> +
> +/* Writeback and invalidate address range in all caches */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_clean_cache (vaddr_t kva, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If D-cache is present */
> +  if (mips_dcache_linesize > 0)
> +    mips_cache_op (kva, n, mips_dcache_linesize, Hit_Writeback_Inv_D);
> +
> +  /* If I-cache is present */
> +  if (mips_icache_linesize > 0)
> +    mips_cache_op (kva, n, mips_icache_linesize, Hit_Invalidate_I);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_linesize > 0)
> +    mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S);
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/* Writeback and invalidate address range in I-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_clean_icache (vaddr_t kva, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If I-cache is present */
> +  if (mips_icache_linesize > 0)
> +    mips_cache_op (kva, n, mips_icache_linesize, Hit_Invalidate_I);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_linesize > 0)
> +    mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S);
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/* Writeback and invalidate address range in D-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_clean_dcache (vaddr_t kva, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If D-cache is present */
> +  if (mips_dcache_linesize > 0)
> +    mips_cache_op (kva, n, mips_dcache_linesize, Hit_Writeback_Inv_D);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_linesize > 0)
> +    mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S);
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/*
> + * Invalidate but don't writeback address range in data caches
> + * Only safe if region is totally cache-line aligned.
> +*/
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_clean_dcache_nowrite (vaddr_t kva, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If D-cache is present */
> +  if (mips_dcache_linesize > 0)
> +    mips_cache_op (kva, n, mips_dcache_linesize, Hit_Invalidate_D);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_linesize > 0)
> +    mips_cache_op (kva, n, mips_scache_linesize, Hit_Invalidate_S);
> +
> +  mips_sync ();
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_cm3_l2size.c
> b/libgloss/mips/hal/mips_cm3_l2size.c
> new file mode 100644
> index 000000000..7006ecbeb
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_cm3_l2size.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +
> +_MIPS_HAL_NOMIPS16
> +void __def_cache_size_hook (void);
> +
> +/*
> + * Routine for calculating L2 cache size from CM3 configuration
> + * registers.  Sizing information is stored directly to memory.
> +*/
> +void _MIPS_HAL_NOMIPS16
> +__cache_size_hook (void)
> +{
> +  unsigned long cm_gcr_base, cm_gcr_l2_config;
> +  int associ;
> +
> +  /*
> +   * Fall back to Config2 based L2 if Config3[M] or Config4[M]
> +   * or Config5[L2C] is not present.
> +  */
> +  if ((mips32_getconfig3 () & CFG3_M) == 0
> +      || (mips32_getconfig4 () & CFG4_M) == 0
> +      || (mips32_getconfig5 () & CFG5_L2C) == 0)
> +    {
> +      __def_cache_size_hook ();
> +      return;
> +    }
> +
> +  /* Read CMGCRBase to find CMGCR_BASE_ADDR */
> +  cm_gcr_base = (mips_getcmgcrbase () << 4) | 0xB0000000UL;
> +
> +  /* Read GCR_L2_CONFIG */
> +  cm_gcr_l2_config = * ((unsigned long *) (cm_gcr_base + GCR_L2_CONFIG));
> +
> +  /* Extract line size */
> +  mips_scache_linesize = (cm_gcr_l2_config & GCR_L2_SL_MASK) >>
> GCR_L2_SL_SHIFT;
> +
> +  /* Check for no cache */
> +  if (mips_scache_linesize == 0)
> +    return;
> +
> +  /* Now have true L2 line size */
> +  mips_scache_linesize = 2 << mips_scache_linesize;
> +
> +  /* Extract sets/way */
> +  mips_scache_ways = (cm_gcr_l2_config & GCR_L2_SS_MASK) >>
> GCR_L2_SS_SHIFT;
> +
> +  /* Now we have true L2 sets/way */
> +  mips_scache_ways = 64 << mips_scache_ways;
> +
> +  /* Extract L2 associativity */
> +  associ = (cm_gcr_l2_config & GCR_L2_SA_MASK) >> GCR_L2_SA_SHIFT;
> +
> +  /* Get total number of sets */
> +  associ = (associ + 1) * mips_scache_ways;
> +
> +  /* L2 cache size */
> +  mips_scache_size = mips_scache_linesize * associ;
> +
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_dsp.S b/libgloss/mips/hal/mips_dsp.S
> new file mode 100644
> index 000000000..a383ba739
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_dsp.S
> @@ -0,0 +1,130 @@
> +/*
> + * Copyright 2016-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +.set nomips16
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +#include <mips/endian.h>
> +
> +#
> +# FUNCTION:    _dsp_save
> +# DESCRIPTION: save the DSP context.
> +# RETURNS:     int
> +#              0:      No context saved
> +#              CTX_*:  Type of conext stored
> +#
> +LEAF(_dsp_save)
> +       move    a1, a0
> +       PTR_S   zero, LINKCTX_NEXT(a1)
> +       move    va0, zero
> +
> +       /* Test for DSP support */
> +       mfc0    t0, C0_CONFIG3
> +       ext     t0, t0, CFG3_DSPP_SHIFT, 1
> +       beqz    t0, 1f
> +
> +       /* Test for DSP enabled */
> +       mfc0    t0, C0_STATUS
> +       ext     t0, t0, SR_MX_SHIFT, 1
> +       beqz    t0, 1f
> +
> +       li      va0, LINKCTX_TYPE_DSP
> +       .set push
> +       .set dsp
> +       rddsp   t1
> +       mfhi    t2, $ac1
> +       mflo    t3, $ac1
> +       mfhi    t4, $ac2
> +       mflo    t5, $ac2
> +       mfhi    t6, $ac3
> +       mflo    t7, $ac3
> +       .set pop
> +       sw      t1, DSPCTX_DSPC(a1)
> +       sw      t2, DSPCTX_HI1(a1)
> +       sw      t3, DSPCTX_LO1(a1)
> +       sw      t4, DSPCTX_HI2(a1)
> +       sw      t5, DSPCTX_LO2(a1)
> +       sw      t6, DSPCTX_HI3(a1)
> +       sw      t7, DSPCTX_LO3(a1)
> +       REG_S   va0, LINKCTX_ID(a1)
> +1:
> +       jr ra
> +END(_dsp_save)
> +
> +#
> +# FUNCTION:    _dsp_load
> +# DESCRIPTION: load the DSP context.
> +# RETURNS:     int
> +#              0:      Unrecognised context
> +#              CTX_*:  Type of context restored
> +#
> +LEAF(_dsp_load)
> +       move    a1, a0
> +       REG_L   va0, LINKCTX_ID(a1)
> +       li      v1, LINKCTX_TYPE_DSP
> +       bne     va0,v1,1f
> +
> +       /* Test for DSP support */
> +       mfc0    t0, C0_CONFIG3
> +       ext     t0, t0, CFG3_DSPP_SHIFT, 1
> +       beqz    t0, 1f
> +
> +       /* Force on DSP */
> +       di      t3
> +       ehb
> +       or      t3, t3, SR_MX
> +       mtc0    t3, C0_STATUS
> +       ehb
> +
> +       lw      t1, DSPCTX_DSPC(a1)
> +       lw      t2, DSPCTX_HI1(a1)
> +       lw      t3, DSPCTX_LO1(a1)
> +       lw      t4, DSPCTX_HI2(a1)
> +       lw      t5, DSPCTX_LO2(a1)
> +       lw      t6, DSPCTX_HI3(a1)
> +       lw      t7, DSPCTX_LO3(a1)
> +       .set push
> +       .set dsp
> +       wrdsp   t1
> +       mthi    t2, $ac1
> +       mtlo    t3, $ac1
> +       mthi    t4, $ac2
> +       mtlo    t5, $ac2
> +       mthi    t6, $ac3
> +       mtlo    t7, $ac3
> +       .set pop
> +       jr ra
> +1:
> +       /* Don't recognise this context, fail */
> +       move    va0, zero
> +       jr ra
> +END(_dsp_load)
> diff --git a/libgloss/mips/hal/mips_excpt_boot.S
> b/libgloss/mips/hal/mips_excpt_boot.S
> new file mode 100644
> index 000000000..08ab1b579
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_boot.S
> @@ -0,0 +1,381 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +#include <mips/endian.h>
> +
> +MIPS_NOMIPS16
> +
> +       # Create space to store k0, k1, ra and sp
> +       .data
> +       .global __start_ctx
> +       .balign SZREG
> +__start_ctx:
> +       .space  SZREG * 18
> +#define        start_ctx_sr    (SZREG * 0)
> +#define        start_ctx_s0    (SZREG * 1)
> +#define        start_ctx_s1    (SZREG * 2)
> +#define        start_ctx_s2    (SZREG * 3)
> +#define        start_ctx_s3    (SZREG * 4)
> +#define        start_ctx_s4    (SZREG * 5)
> +#define        start_ctx_s5    (SZREG * 6)
> +#define        start_ctx_s6    (SZREG * 7)
> +#define        start_ctx_s7    (SZREG * 8)
> +#define        start_ctx_k0    (SZREG * 9)
> +#define        start_ctx_k1    (SZREG * 10)
> +#define        start_ctx_gp    (SZREG * 11)
> +#define        start_ctx_sp    (SZREG * 12)
> +#define        start_ctx_fp    (SZREG * 13)
> +#define        start_ctx_ra    (SZREG * 14)
> +#define        start_ctx_ictl  (SZREG * 15)
> +#define        start_ctx_ebase (SZREG * 16)    /* saved EBASE */
> +#define        chain_ebase     (SZREG * 17)    /* chained EBASE */
> +
> +#if defined (__mips_micromips)
> +       .space  SZREG
> +#define        start_ctx_conf3 (SZREG * 18)    /* saved Config3 $16,3 for
> micromips */
> +#endif
> +
> +#
> +# FUNCTION:    void* __register_excpt_boot (void*, int, void*)
> +#
> +# DESCRIPTION: Save all boot state. Some state is already clobbered but
> passed
> +#             in as arguments:
> +#              a0 = Boot ra
> +#             a1 = Boot SR
> +#             a2 = caller's RA (to be returned back)
> +#
> +WLEAF(__register_excpt_boot)
> +       .set    push
> +       .set    noat
> +
> +       /* Save C0_SR IE and BEV */
> +       LA      t1, __start_ctx
> +       REG_S   a0, start_ctx_ra(t1)
> +       REG_S   a1, start_ctx_sr(t1)
> +
> +       REG_S   s0, start_ctx_s0(t1)
> +       REG_S   s1, start_ctx_s1(t1)
> +       REG_S   s2, start_ctx_s2(t1)
> +       REG_S   s3, start_ctx_s3(t1)
> +       REG_S   s4, start_ctx_s4(t1)
> +       REG_S   s5, start_ctx_s5(t1)
> +       REG_S   s6, start_ctx_s6(t1)
> +       REG_S   s7, start_ctx_s7(t1)
> +       REG_S   k0, start_ctx_k0(t1)
> +       REG_S   k1, start_ctx_k1(t1)
> +       REG_S   gp, start_ctx_gp(t1)
> +       REG_S   sp, start_ctx_sp(t1)
> +       REG_S   fp, start_ctx_fp(t1)
> +
> +#if defined (__mips_micromips)
> +       /* Save Config3 */
> +       mfc0    t0, C0_CONFIG3
> +       REG_S   t0, start_ctx_conf3(t1)
> +#endif
> +       mfc0    t0, C0_INTCTL
> +       REG_S   t0, start_ctx_ictl(t1)
> +
> +       /* Save C0_EBASE */
> +       PTR_MFC0 t2, C0_EBASE
> +       REG_S   t2, start_ctx_ebase(t1)
> +
> +       /* Check if we booted with BEV==1 */
> +       ext     t3, a1, SR_BEV_SHIFT, 1
> +       beqz    t3, 1f
> +
> +       /*
> +        * BEV==0 - set chain_ebase to 0xbfc00200
> +        * Apply the offset of 0x200 so that the boot vector entries line
> up
> +        * with the offsets in a non-boot vectora.
> +        */
> +       li      t2, 0xbfc00200
> +
> +       /* No - set chain_ebase to C0_EBASE */
> +1:     REG_S   t2, chain_ebase(t1)
> +
> +       /* Return the third argument */
> +       move    va0, a2
> +       jr      ra
> +
> +       .set    pop
> +WEND(__register_excpt_boot)
> +
> +#
> +# FUNCTION:    int __return_to_boot (int)
> +#
> +# DESCRIPTION: This is used if UHI EXIT was not handled. Return back to
> +#             caller of _start.
> +#             a0 = exit code to return to caller
> +#
> +WLEAF(__return_to_boot)
> +       .set    push
> +       .set    noat
> +       /* Disable interrupts for safety */
> +       di
> +       ehb
> +       /* Set BEV=1 to allow changing EBASE */
> +       mfc0    t0, C0_SR
> +       li      t1, SR_BEV
> +       or      t0, t0, t1
> +       mtc0    t0, C0_SR
> +       ehb
> +
> +       /* Restore C0_EBASE */
> +       LA      t0, __start_ctx
> +       REG_L   t0, start_ctx_ebase(t0)
> +       /* Set the write gate to potentially change upper bits */
> +       ori     t1, t0, EBASE_WG
> +       PTR_MTC0 t1, C0_EBASE
> +       ehb
> +       /* Check if the write gate was set on startup */
> +       andi    t1, t0, EBASE_WG
> +       bnez    t1, 1f
> +
> +       /* If write gate wasn't set then clear the write gate again */
> +       PTR_MTC0 t0, C0_EBASE
> +       ehb
> +
> +1:     /* Restore original state */
> +       LA      t0, __start_ctx
> +       REG_L   s0, start_ctx_s0(t0)
> +       REG_L   s1, start_ctx_s1(t0)
> +       REG_L   s2, start_ctx_s2(t0)
> +       REG_L   s3, start_ctx_s3(t0)
> +       REG_L   s4, start_ctx_s4(t0)
> +       REG_L   s5, start_ctx_s5(t0)
> +       REG_L   s6, start_ctx_s6(t0)
> +       REG_L   s7, start_ctx_s7(t0)
> +       REG_L   k0, start_ctx_k0(t0)
> +       REG_L   k1, start_ctx_k1(t0)
> +       REG_L   gp, start_ctx_gp(t0)
> +       REG_L   sp, start_ctx_sp(t0)
> +       REG_L   fp, start_ctx_fp(t0)
> +       REG_L   ra, start_ctx_ra(t0)
> +
> +#if defined (__mips_micromips)
> +       /* Restore Config3 */
> +       REG_L   t1, start_ctx_conf3(t0)
> +       mtc0    t1, C0_CONFIG3
> +#endif
> +       /* Restore IntCtl */
> +       REG_L   t1, start_ctx_ictl(t0)
> +       mtc0    t1, C0_INTCTL
> +
> +       REG_L   t0, start_ctx_sr(t0)
> +
> +       /* Restore C0_STATUS IE and BEV to boot value */
> +       mtc0    t0, C0_SR
> +       mtc0    zero, C0_CAUSE
> +
> +       /* Return with exit code */
> +       move    va0, a0
> +       MIPS_JRHB(ra)
> +       .set    pop
> +WEND(__return_to_boot)
> +
> +#
> +# FUNCTION:    void __chain_uhi_excpt (struct gpctx *);
> +#
> +# DESCRIPTION: Transfer to the exception handler in the boot environment.
> +#             a0 == pointer to the context to restore
> +#
> +WLEAF(__chain_uhi_excpt)
> +       .set    push
> +       .set    noat
> +
> +       /*
> +        * Move context pointer into position.  Use $3 as scratch
> +        * as it is the only register that is clobbered by all
> +        * UHI calls and is not used as an input.
> +        */
> +       move    r3, a0
> +
> +#if (__mips_isa_rev < 6)
> +       REG_L   t0, CTX_HI0(r3)
> +       REG_L   t1, CTX_LO0(r3)
> +       mthi    t0
> +       mtlo    t1
> +#endif
> +
> +       lw      t0, CTX_STATUS(r3)
> +       mtc0    t0, C0_SR
> +       REG_L   t0, CTX_EPC(r3)
> +       PTR_MTC0 t0, C0_EPC
> +       ehb
> +
> +       /* Restore the common context */
> +       REG_L   r1, CTX_REG(1)(r3)
> +       REG_L   r2, CTX_REG(2)(r3)
> +       REG_L   r4, CTX_REG(4)(r3)
> +       REG_L   r5, CTX_REG(5)(r3)
> +       REG_L   r6, CTX_REG(6)(r3)
> +       REG_L   r7, CTX_REG(7)(r3)
> +       REG_L   r8, CTX_REG(8)(r3)
> +       REG_L   r9, CTX_REG(9)(r3)
> +       REG_L   r10, CTX_REG(10)(r3)
> +       REG_L   r11, CTX_REG(11)(r3)
> +       REG_L   r12, CTX_REG(12)(r3)
> +       REG_L   r13, CTX_REG(13)(r3)
> +       REG_L   r14, CTX_REG(14)(r3)
> +       REG_L   r15, CTX_REG(15)(r3)
> +       REG_L   r16, CTX_REG(16)(r3)
> +       REG_L   r17, CTX_REG(17)(r3)
> +       REG_L   r18, CTX_REG(18)(r3)
> +       REG_L   r19, CTX_REG(19)(r3)
> +       REG_L   r20, CTX_REG(20)(r3)
> +       REG_L   r21, CTX_REG(21)(r3)
> +       REG_L   r22, CTX_REG(22)(r3)
> +       REG_L   r23, CTX_REG(23)(r3)
> +       REG_L   r24, CTX_REG(24)(r3)
> +       REG_L   r25, CTX_REG(25)(r3)
> +       REG_L   r28, CTX_REG(28)(r3)
> +       REG_L   r29, CTX_REG(29)(r3)
> +       REG_L   r30, CTX_REG(30)(r3)
> +       REG_L   r31, CTX_REG(31)(r3)
> +
> +       /* Restore chained exception handlers kernel regs */
> +       LA      r3, __start_ctx
> +       REG_L   k0, start_ctx_k0(r3)
> +       REG_L   k1, start_ctx_k1(r3)
> +
> +#if defined (__mips_micromips)
> +       /* OR the address with Config3.ISAOnExc bit */
> +       REG_L   r3, start_ctx_conf3(r3)
> +       ext     r3, r3, CFG3_IOE_SHIFT, 1
> +       beqz    r3, 1f
> +
> +       /* Compute exception vector */
> +       LA      r3, __start_ctx
> +       REG_L   r3, chain_ebase(r3)
> +       PTR_ADDU r3, r3, 0x181          # OR ISAOnExc bit
> +
> +       /* Chain */
> +       jr      r3
> +1:
> +       /* Compute exception vector */
> +       LA      r3, __start_ctx
> +#endif
> +
> +       REG_L   r3, chain_ebase(r3)
> +       PTR_ADDU r3, r3, 0x180
> +
> +       /* Chain */
> +       jr      r3
> +
> +       .set    pop
> +WEND(__chain_uhi_excpt)
> +
> +#
> +# FUNCTION:    int __get_startup_BEV (void)
> +#
> +# DESCRIPTION: Return value of BEV flag saved in __register_excpt_handler.
> +#
> +WLEAF(__get_startup_BEV)
> +       .set    push
> +       .set    noat
> +
> +       LA      t0, __start_ctx
> +       REG_L   va0, start_ctx_sr(t0)
> +       li      t1, SR_BEV
> +       and     va0, va0, t1
> +       jr      ra
> +
> +       .set    pop
> +WEND(__get_startup_BEV)
> +
> +
> +EXPORTS(__MIPS_UHI_BAD_POINTER, 32)
> +       .ascii "UHI: BAD POINTER\000"
> +
> +#
> +# FUNCTION: __convert_argv_pointers (int, char*[], char*[])
> +#
> +# DESCRIPTION: Convert 64-bit pointers to 32-bit.  This allocates the new
> +#             argument structure on the stack and verifies all pointers
> are
> +#             canonical for a 32-bit address space.
> +#
> +#if _MIPS_SIM==_ABIO32 || _MIPS_SIM==_ABIN32
> +WLEAF(__convert_argv_pointers)
> +       /* Early out if a0 <= 0 */
> +       blez    a0, .Lend
> +
> +       /* Verify we came from 64-bit mode */
> +       LA      t0, __start_ctx
> +       REG_L   t0, start_ctx_sr(t0)
> +       ext     t1, t0, SR_KX_SHIFT, 1
> +       beqz    t1, .Lend
> +
> +       /* Set up stack pointer */
> +       move    t0, a0
> +       sll     t1, t0, 2
> +       /* Round to stack alignment */
> +       addiu   t1, t1, ALSZ
> +       and     t1, t1, ALMASK
> +
> +       PTR_SUBU sp, sp, t1
> +       move    t2, sp
> +       move    t3, a1
> +       li      t1, -1
> +
> +.Lloop:
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +       lw      t8, 0(t3)
> +       lw      t9, 4(t3)
> +#elif BYTE_ORDER == BIG_ENDIAN
> +       lw      t9, 0(t3)
> +       lw      t8, 4(t3)
> +#else
> +#error BYTE_ORDER
> +#endif
> +       /* if s1 != 0 && s1 != 0xFFFFFFFF */
> +       beqz    t9, .LGoodp
> +       beq     t9, t1, .LGoodp
> +       /* Overwrite bad pointer with stock bad value */
> +       LA      t8, __MIPS_UHI_BAD_POINTER
> +.LGoodp:
> +       sw      t8, 0(t2)
> +
> +       PTR_ADDU t2, t2, 4
> +       PTR_ADDU t3, t3, 8
> +       addiu   t0, t0, -1
> +       bnez    t0, .Lloop
> +
> +       move    a1, sp
> +       PTR_SUBU sp, sp, (NARGSAVE*SZARG)
> +
> +       move    a2, zero
> +.Lend:
> +       jr      ra
> +WEND(__convert_argv_pointers)
> +#endif /* ABI TEST */
> diff --git a/libgloss/mips/hal/mips_excpt_entry.S
> b/libgloss/mips/hal/mips_excpt_entry.S
> new file mode 100644
> index 000000000..ddbd2bf9c
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_entry.S
> @@ -0,0 +1,212 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#define _FUNCTION_SECTIONS_
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +#include <mips/ctx.S>
> +
> +MIPS_NOMIPS16
> +
> +/* Stack adjustment for ABI parameter area.  */
> +#define ADJ (NARGSAVE * SZARG)
> +/*
> + * Round the context size up to a 16-byte boundary which is the maximum
> + * stack alignment required for any supported ABI.
> + */
> +#define CTX_SIZEROUND ((CTX_SIZE + ALSZ) & ALMASK)
> +
> +/*
> + * Exception entry points.  These are designed for use at EBASE when
> + * STATUS.BEV is clear.
> + * The entry points will either chain on to a user-supplied function
> + * or loop indefinitely.
> + */
> +
> +LEAF(__exception_entry)
> +       .set    push
> +       .set    noat
> +.weak   _mips_tlb_refill
> +       _mips_tlb_refill = __exception_save
> +__tlb_refill_loop:
> +       /*
> +        * Support an alternative entry point at the start of the exception
> +        * vector.  Since the exception vector is normally placed first
> +        * in the link map this allows a user to start execution from the
> +        * same address that an executable is loaded to.
> +        */
> +       LA      k1, __first_boot
> +       lw      k1, 0(k1)
> +       beqz    k1, 1f
> +       /*
> +        * The start code is responsible for clearing __first_boot prior
> +        * to installing the exception handlers.
> +        */
> +       LA      k1, _start
> +       jr      k1
> +1:
> +       /* Support the case where no handler is defined.  */
> +       LA      k1, _mips_tlb_refill
> +       beqz    k1, __tlb_refill_loop
> +       jr      k1
> +
> +       .org 0x80
> +.weak   _mips_xtlb_refill
> +       _mips_xtlb_refill = __exception_save
> +__xtlb_refill_loop:
> +       LA      k1, _mips_xtlb_refill
> +       beqz    k1, __xtlb_refill_loop
> +       jr      k1
> +
> +       .org 0x100
> +.weak   _mips_cache_error
> +__cache_error_loop:
> +       LA      k1, _mips_cache_error
> +       beqz    k1, __cache_error_loop
> +       jr      k1
> +
> +       .org 0x180
> +.weak   _mips_general_exception
> +__general_exception_loop:
> +       /*
> +        * Free up k1, defering sp adjustment until later.  Preserving k1
> +        * may be undesirable if an exception occurs due to a corrupt
> +        * stack but since the default handlers use the user-stack to
> +        * store the context then there is nothing to lose.
> +        */
> +       REG_S   k1, (-CTX_SIZEROUND + CTX_K1)(sp)
> +
> +       LA      k1, _mips_general_exception
> +       beqz    k1, __general_exception_loop
> +       jr      k1
> +       .set    pop
> +END(__exception_entry)
> +
> +/*
> + * FUNCTION:   __exception_save
> + *
> + * DESCRIPTION:        Saves the GP context to the stack and invokes
> + *             _mips_handle_exception with appropriate arguments.
> +*/
> +ANESTED(__exception_save, _mips_general_exception, CTX_SIZEROUND + ADJ,
> zero)
> +       .globl  __exception_save;
> +       .set    push
> +       .set    noat
> +
> +       /* Create pointer to gp_ctx.  */
> +       PTR_ADDU k1, sp, -CTX_SIZEROUND
> +
> +       /* Save context.  */
> +       _gpctx_save
> +       /* va0 now holds C0_STATUS.  */
> +
> +       /* Finish storing the rest of the CP0 registers.  */
> +       PTR_MFC0 t0, C0_BADVADDR
> +       REG_S   t0, CTX_BADVADDR(k1)
> +
> +#if __mips_isa_rev < 6
> +       move    t0, zero
> +       move    t1, zero
> +       mfc0    t2, C0_CONFIG3
> +       ext     t3, t2, CFG3_BP_SHIFT, 1
> +       beqz    t3, 1f
> +#else
> +       /* MIPSR6 guarantees all CP0 regs are defined to at
> +          least return zero.  */
> +#endif
> +       mfc0    t0, C0_BADPINSTR
> +#if __mips_isa_rev < 6
> +1:
> +       ext     t2, t2, CFG3_BI_SHIFT, 1
> +       beqz    t2, 1f
> +#endif
> +       mfc0    t1, C0_BADINSTR
> +1:
> +       sw      t0, CTX_BADPINSTR(k1)
> +       sw      t1, CTX_BADINSTR(k1)
> +
> +       /* Get and store the exception cause.  */
> +       mfc0    t0, C0_CR
> +       sw      t0, CTX_CAUSE(k1)
> +
> +       /* Extract the cause code for argument 1.  */
> +       ext     a1, t0, CR_X_SHIFT, CR_X_BITS
> +
> +       /* Create the argument space.  */
> +       addiu   sp, k1, -ADJ
> +
> +       /* Clear EXL.  Exceptions can now nest.  */
> +       ins     va0, zero, SR_EXL_SHIFT, 1
> +       mtc0    va0, C0_SR
> +
> +       /* Move the gp_ctx pointer for argument 0.  */
> +       addiu   a0, sp, ADJ
> +
> +       /* Manually set up the return address to restore the context
> below.  */
> +       LA      ra, __exception_restore
> +
> +       /* Call the handler, indirect through t9 albeit not for any
> specific
> +          reason.  */
> +       LA      t9, _mips_handle_exception
> +       jr      t9
> +
> +       .set pop
> +END(__exception_save)
> +
> +/*
> + * FUNCTION:   __exception_restore
> + *
> + * DESCRIPTION:  Load the GP context from immediately above the stack
> + *              pointer and eret.
> + */
> +LEAF(__exception_restore)
> +       .set    push
> +       .set    noat
> +
> +       /* Skip past the argument save area and fall through.  */
> +       addiu   a0, sp, ADJ
> +
> +/*
> + * FUNCTION:   __gpctx_load_eret
> + *
> + * DESCRIPTION:  Load the GP context from the address in register a0
> + *              and eret.
> + */
> +AENT(__gpctx_load_eret)
> +
> +       _gpctx_load
> +
> +       /* Return from exception.  */
> +       eret
> +       .set    pop
> +END(__exception_restore)
> diff --git a/libgloss/mips/hal/mips_excpt_handler.c
> b/libgloss/mips/hal/mips_excpt_handler.c
> new file mode 100644
> index 000000000..4c83c9b0a
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_handler.c
> @@ -0,0 +1,308 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <mips/cpu.h>
> +#include <mips/fpa.h>
> +#include <mips/hal.h>
> +#include <mips/uhi_syscalls.h>
> +
> +/* Defined in .ld file */
> +extern char __use_excpt_boot[];
> +extern char __attribute__((weak)) __flush_to_zero[];
> +
> +#ifdef VERBOSE_EXCEPTIONS
> +/*
> + * Write a string, a formatted number, then a string.
> + */
> +static void
> +putsnds (const char *pre, reg_t value, int digits, const char *post)
> +{
> +  char buf[digits];
> +  int shift;
> +  int idx = 0;
> +
> +  if (pre != NULL)
> +    write (1, pre, strlen (pre));
> +
> +  for (shift = ((digits - 1) * 4) ; shift >= 0 ; shift -= 4)
> +    buf[idx++] = "0123456789ABCDEF"[(value >> shift) & 0xf];
> +  write (1, buf, digits);
> +
> +  if (post != NULL)
> +    write (1, post, strlen (post));
> +}
> +
> +static void
> +putsns (const char *pre, reg_t value, const char *post)
> +{
> +  putsnds (pre, value, sizeof (reg_t) * 2, post);
> +}
> +
> +# define WRITE(MSG) write (1, (MSG), strlen (MSG))
> +# define PUTSNDS(PRE, VALUE, DIGITS, POST) \
> +    putsnds ((PRE), (VALUE), (DIGITS), (POST))
> +# define PUTSNS(PRE, VALUE, POST) \
> +    putsns ((PRE), (VALUE), (POST))
> +
> +#else
> +
> +# define WRITE(MSG)
> +# define PUTSNDS(PRE, VALUE, DIGITS, POST)
> +# define PUTSNS(PRE, VALUE, POST)
> +
> +#endif // !VERBOSE_EXCEPTIONS
> +
> +/* Handle an exception */
> +#ifdef VERBOSE_EXCEPTIONS
> +void _MIPS_HAL_NOMIPS16
> +__exception_handle_verbose (struct gpctx *ctx, int exception)
> +#else
> +void _MIPS_HAL_NOMIPS16
> +__exception_handle_quiet (struct gpctx *ctx, int exception)
> +#endif
> +{
> +  switch (exception)
> +    {
> +   case EXC_MOD:
> +      WRITE ("TLB modification exception\n");
> +      break;
> +    case EXC_TLBL:
> +      PUTSNS ("TLB error on load from 0x", ctx->badvaddr, NULL);
> +      PUTSNS (" @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_TLBS:
> +      PUTSNS ("TLB error on store to 0x", ctx->badvaddr, NULL);
> +      PUTSNS (" @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_ADEL:
> +      PUTSNS ("Address error on load from 0x", ctx->badvaddr, NULL);
> +      PUTSNS (" @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_ADES:
> +      PUTSNS ("Address error on store to 0x", ctx->badvaddr, NULL);
> +      PUTSNS (" @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_IBE:
> +      WRITE ("Instruction bus error\n");
> +      break;
> +    case EXC_DBE:
> +      WRITE ("Data bus error\n");
> +      break;
> +    case EXC_SYS:
> +      /* Process a UHI SYSCALL, all other SYSCALLs should have been
> processed
> +        by our caller.  __use_excpt_boot has following values:
> +        0 = Do not use exception handler present in boot.
> +        1 = Use exception handler present in boot if BEV
> +            is 0 at startup.
> +        2 = Always use exception handler present in boot.   */
> +
> +      /* Special handling for boot/low level failures.  */
> +      if (ctx->t2[1] == __MIPS_UHI_BOOTFAIL)
> +       {
> +         switch (ctx->a[0])
> +           {
> +           case __MIPS_UHI_BF_CACHE:
> +             WRITE ("L2 cache configuration error\n");
> +             break;
> +           default:
> +             WRITE ("Unknown boot failure error\n");
> +             break;
> +           }
> +
> +         /* These are unrecoverable.  Abort.  */
> +         ctx->epc = (sreg_t)(long)&__exit;
> +         /* Exit code of 255 */
> +         ctx->a[0] = 0xff;
> +         return;
> +       }
> +
> +      if (((long) __use_excpt_boot == 2
> +          || ((long) __use_excpt_boot == 1
> +              && __get_startup_BEV
> +              && __get_startup_BEV () == 0))
> +         && __chain_uhi_excpt)
> +       /* This will not return.  */
> +       __chain_uhi_excpt (ctx);
> +      else
> +       __uhi_indirect (ctx);
> +      return;
> +    case EXC_BP:
> +      PUTSNS ("Breakpoint @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_RI:
> +      PUTSNS ("Illegal instruction @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_CPU:
> +      PUTSNS ("Coprocessor unusable @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_OVF:
> +      WRITE ("Overflow\n");
> +      break;
> +    case EXC_TRAP:
> +      WRITE ("Trap\n");
> +      break;
> +    case EXC_MSAFPE:
> +#if MIPS_MSA_USABLE
> +      if (__flush_to_zero
> +         && (msa_getsr () & FPA_CSR_UNI_X)
> +         && (msa_getsr () & FPA_CSR_FS) == 0)
> +       {
> +         unsigned int sr = msa_getsr ();
> +         sr &= ~FPA_CSR_UNI_X;
> +         sr |= FPA_CSR_FS;
> +         msa_setsr (sr);
> +         return;
> +       }
> +#endif
> +      WRITE ("MSA Floating point error\n");
> +      break;
> +    case EXC_FPE:
> +      /* Turn on flush to zero the first time we hit an unimplemented
> +        operation.  If we hit it again then stop.  */
> +      if (__flush_to_zero
> +         && (fpa_getsr () & FPA_CSR_UNI_X)
> +         && (fpa_getsr () & FPA_CSR_FS) == 0)
> +       {
> +         unsigned int sr = fpa_getsr ();
> +         sr &= ~FPA_CSR_UNI_X;
> +         sr |= FPA_CSR_FS;
> +         fpa_setsr (sr);
> +
> +         return;
> +       }
> +      WRITE ("Floating point error\n");
> +      break;
> +    case EXC_IS1:
> +      WRITE ("Implementation specific exception (16)\n");
> +      break;
> +    case EXC_IS2:
> +      WRITE ("Implementation specific exception (17)\n");
> +      break;
> +    case EXC_C2E:
> +      WRITE ("Precise Coprocessor 2 exception\n");
> +      break;
> +    case EXC_TLBRI:
> +      WRITE ("TLB read inhibit exception\n");
> +      break;
> +    case EXC_TLBXI:
> +      WRITE ("TLB execute inhibit exception\n");
> +      break;
> +    case EXC_MSAU:
> +      PUTSNS ("MSA unusable @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_MDMX:
> +      PUTSNS ("MDMX exception @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_WATCH:
> +      PUTSNS ("Watchpoint @0x", ctx->epc, "\n");
> +      break;
> +    case EXC_MCHECK:
> +      WRITE ("Machine check error\n");
> +      break;
> +    case EXC_THREAD:
> +      WRITE ("Thread exception\n");
> +      break;
> +    case EXC_DSPU:
> +      WRITE ("DSP unusable\n");
> +      break;
> +    case EXC_RES30:
> +      WRITE ("Cache error\n");
> +      break;
> +    default:
> +      PUTSNS ("Unhandled exception ", exception, "\n");
> +    }
> +
> +  /* Dump registers */
> +  PUTSNS (" 0:\t", 0, "\t");
> +  PUTSNS ("at:\t", ctx->at, "\t");
> +  PUTSNS ("v0:\t", ctx->v[0], "\t");
> +  PUTSNS ("v1:\t", ctx->v[1], "\n");
> +
> +  PUTSNS ("a0:\t", ctx->a[0], "\t");
> +  PUTSNS ("a1:\t", ctx->a[1], "\t");
> +  PUTSNS ("a2:\t", ctx->a[2], "\t");
> +  PUTSNS ("a3:\t", ctx->a[3], "\n");
> +
> +  PUTSNS ("t0:\t", ctx->t[0], "\t");
> +  PUTSNS ("t1:\t", ctx->t[1], "\t");
> +  PUTSNS ("t2:\t", ctx->t[2], "\t");
> +  PUTSNS ("t3:\t", ctx->t[3], "\n");
> +
> +  PUTSNS ("t4:\t", ctx->t[4], "\t");
> +  PUTSNS ("t5:\t", ctx->t[5], "\t");
> +  PUTSNS ("t6:\t", ctx->t[6], "\t");
> +  PUTSNS ("t7:\t", ctx->t[7], "\n");
> +
> +  PUTSNS ("s0:\t", ctx->s[0], "\t");
> +  PUTSNS ("s1:\t", ctx->s[1], "\t");
> +  PUTSNS ("s2:\t", ctx->s[2], "\t");
> +  PUTSNS ("s3:\t", ctx->s[3], "\n");
> +
> +  PUTSNS ("s4:\t", ctx->s[4], "\t");
> +  PUTSNS ("s5:\t", ctx->s[5], "\t");
> +  PUTSNS ("s6:\t", ctx->s[6], "\t");
> +  PUTSNS ("s7:\t", ctx->s[7], "\n");
> +
> +  PUTSNS ("t8:\t", ctx->t2[0], "\t");
> +  PUTSNS ("t9:\t", ctx->t2[1], "\t");
> +  PUTSNS ("k0:\t", ctx->k[0], "\t");
> +  PUTSNS ("k1:\t", ctx->k[1], "\n");
> +
> +  PUTSNS ("gp:\t", ctx->gp, "\t");
> +  PUTSNS ("sp:\t", ctx->sp, "\t");
> +  PUTSNS ("fp:\t", ctx->fp, "\t");
> +  PUTSNS ("ra:\t", ctx->ra, "\n");
> +
> +#if __mips_isa_rev < 6
> +  PUTSNS ("hi:\t", ctx->hi, "\t");
> +  PUTSNS ("lo:\t", ctx->lo, "\n");
> +#endif
> +
> +  PUTSNS ("epc:     \t", ctx->epc, "\n");
> +  PUTSNS ("BadVAddr:\t", ctx->badvaddr, "\n");
> +
> +  PUTSNDS ("Status:   \t", ctx->status, 8, "\n");
> +  PUTSNDS ("Cause:    \t", ctx->cause, 8, "\n");
> +  PUTSNDS ("BadInstr: \t", ctx->badinstr, 8, "\n");
> +  PUTSNDS ("BadPInstr:\t", ctx->badpinstr, 8, "\n");
> +
> +  /* Raise UHI exception which may or may not return.  */
> +  if (__uhi_exception (ctx, UHI_ABI) != 0)
> +    {
> +      /* The exception was acknowledged but not handled.  Abort.  */
> +      ctx->epc = (sreg_t)(long)&__exit;
> +      /* Exit code of 255 */
> +      ctx->a[0] = 0xff;
> +    }
> +}
> diff --git a/libgloss/mips/hal/mips_excpt_isr_fallback.S
> b/libgloss/mips/hal/mips_excpt_isr_fallback.S
> new file mode 100644
> index 000000000..d3afce8ec
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_isr_fallback.S
> @@ -0,0 +1,52 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#define _FUNCTION_SECTIONS_
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +
> +.set   noat
> +MIPS_NOMIPS16
> +
> +_TEXT_SECTION_NAMED(__isr_vec_fallback)
> +
> +       /* The alignment used here must match __isr_vec_space.  */
> +       .balign (SZPTR * 8);
> +       .globl  __isr_vec_fallback;
> +       .ent    __isr_vec_fallback;
> +__isr_vec_fallback:
> +.weak   _mips_interrupt
> +1:
> +       LA      k1, _mips_interrupt
> +       beqz    k1, 1b
> +       jr      k1
> +END(__isr_vec_fallback)
> diff --git a/libgloss/mips/hal/mips_excpt_isr_fragment.S
> b/libgloss/mips/hal/mips_excpt_isr_fragment.S
> new file mode 100644
> index 000000000..b7c50de3e
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_isr_fragment.S
> @@ -0,0 +1,73 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#define _FUNCTION_SECTIONS_
> +
> +#include <mips/regdef.h>
> +#include <mips/asm.h>
> +#include <mips/cpu.h>
> +
> +.set   noat
> +MIPS_NOMIPS16
> +
> +.extern        __isr_vec_fallback
> +
> +/* For the vectors shared between VINT and VEIC we rename the numeric
> + * vector indices to the named form instead.  */
> +
> +#define        _mips_isr_000 _mips_isr_sw0
> +#define        _mips_isr_001 _mips_isr_sw1
> +#define        _mips_isr_002 _mips_isr_hw0
> +#define        _mips_isr_003 _mips_isr_hw1
> +#define        _mips_isr_004 _mips_isr_hw2
> +#define        _mips_isr_005 _mips_isr_hw3
> +#define        _mips_isr_006 _mips_isr_hw4
> +#define        _mips_isr_007 _mips_isr_hw5
> +
> +.extern        REF
> +.weak  ISR
> +
> +#ifdef __mips_micromips
> +# define NOP nop32
> +#else
> +# define NOP nop
> +#endif
> +
> +_TEXT_SECTION_NAMED(DEF);
> +/* The alignment used here must match __isr_vec_space.  */
> +       .balign (SZPTR * 8);
> +       .globl  DEF;
> +       .ent    DEF;
> +DEF:
> +       NOP               /* May become: mtc0 k1, C0_KSCRATCH1 */
> +       LA      k1, ISR
> +       beqz    k1, __isr_vec_fallback
> +       jr      k1
> +END(DEF)
> diff --git a/libgloss/mips/hal/mips_excpt_register.S
> b/libgloss/mips/hal/mips_excpt_register.S
> new file mode 100644
> index 000000000..1c6bdc04c
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_register.S
> @@ -0,0 +1,147 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +
> +MIPS_NOMIPS16
> +
> +/*
> + * Used to support an alternate entry point that overlays the TLB refill
> + * exception entry point.  This flag must be cleared before exceptions
> + * are ready to be handled.
> + */
> +.data
> +EXPORTS(__first_boot, 4)
> +       .word   0x1
> +
> +_TEXT_SECTION
> +
> +/*
> + * FUNCTION:   __register_excpt_handler
> + *
> + * DESCRIPTION: Register __exception_entry at EBASE+0x180. Return the new
> + *             value for C0_SR.
> + */
> +WLEAF(__register_excpt_handler)
> +       .set    push
> +       .set    noat
> +
> +       /* Fetch initial status */
> +       mfc0    a1, C0_SR
> +
> +       /*
> +        * Get into a clean state.
> +        * Important things: base mode is kernel and ERL, ESL, IE are clear
> +        * Set BEV=1 to allow changing EBASE later.
> +        */
> +       li      t0, SR_BEV
> +       mtc0    t0, C0_SR
> +       ehb
> +
> +       /*
> +        * Enable use of a boot state hook
> +        * a0 = Boot time RA
> +        * a1 = Boot time SR
> +        * a2 = Current RA. There is no stack so get the callee to pass
> this
> +        *      back.
> +        */
> +.weak  __register_excpt_boot
> +       LA      t0, __register_excpt_boot
> +       beqz    t0, 1f
> +       move    a2, ra
> +       jalr    t0
> +       move    ra, va0
> +1:
> +       /* Clear first boot flag */
> +       LA      t0, __first_boot
> +       sw      zero, 0(t0)
> +
> +       mfc0    t3, C0_CONFIG3
> +#if defined (__mips_micromips)
> +       /* Set Config3.ISAOnExc for microMIPS */
> +       li      t0, CFG3_IOE
> +       or      t0, t0, t3
> +       mtc0    t0, C0_CONFIG3
> +#endif
> +
> +       /* Set desired EBASE */
> +       LA      t0, __excpt_ebase
> +       /*
> +        * Always set the write gate as the requested EBASE may not be in
> kseg0.
> +        * This may or may not exist in hardware but if it doesn't then the
> +        * ebase address will simply get masked with inevitable
> consequences.
> +        */
> +       ori     t0, t0, EBASE_WG
> +       PTR_MTC0 t0, C0_EBASE
> +       ehb
> +
> +       /* Set up new empty status value */
> +       move    va0, zero
> +
> +       /* Set up vector spacing */
> +       LA      t0, __isr_vec_space
> +
> +       /* Check for vectored interrupt support */
> +       andi    t1, t3, CFG3_VI | CFG3_VEIC
> +       /* Skip vector spacing setup if neither VINT nor VEIC is present */
> +       beqz    t1, 1f
> +
> +       /* Set vector spacing */
> +       mfc0    t1, C0_INTCTL
> +       srl     t0, t0, 5
> +       ins     t1, t0, INTCTL_VS_SHIFT, INTCTL_VS_BITS
> +       mtc0    t1, C0_INTCTL
> +       b       2f
> +1:
> +       /*
> +        * Check non-zero vector spacing without vectored interrupt
> support.
> +        * If so, do not enable interrupts.
> +        */
> +       bnez    t0, 3f
> +2:
> +       /* Turn on use of the special exception vector and enable
> interrupts */
> +       li      t0, CR_IV
> +       mtc0    t0, C0_CAUSE
> +       ehb
> +
> +       /* Check for VEIC and do not enable interrupts if EIC is active */
> +       ext     t0, t3, CFG3_VEIC_SHIFT, 1
> +       bnez    t0, 3f
> +
> +       /* Enable interrupts in the new status value */
> +       ori     va0, va0, SR_IE
> +3:
> +       jr      ra
> +
> +       .set    pop
> +WEND(__register_excpt_handler)
> diff --git a/libgloss/mips/hal/mips_excpt_timer.S
> b/libgloss/mips/hal/mips_excpt_timer.S
> new file mode 100644
> index 000000000..faccb4185
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_excpt_timer.S
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +
> +MIPS_NOMIPS16
> +
> +EXPORTS(_count_wrap, 4)
> +       .word   0x0
> +
> +#
> +# FUNCTION:
> +#
> +# DESCRIPTION:
> +#
> +LEAF(mips_start_minimal_counter)
> +       di      $8
> +       ehb
> +       ori     $8, $8, SR_HINT5
> +       ori     $8, $8, SR_IE
> +       LA      $9, _count_wrap
> +       sw      $0, 0($9)
> +       li      $9, 1
> +       mtc0    $9, C0_COUNT
> +       mtc0    $0, C0_COMPARE
> +       mtc0    $8, C0_SR
> +       ehb
> +       jr      $31
> +END(mips_start_minimal_counter)
> +
> +LEAF(_mips_isr_sw0)
> +       .set push
> +       .set noreorder
> +       .set noat
> +       LA      $k0, _count_wrap
> +       lw      $k1, 0($k0)
> +       addiu   $k1, $k1, 1
> +       sw      $k1, 0($k0)
> +       mtc0    $0, C0_COMPARE
> +       eret
> +       .set pop
> +END(_mips_isr_sw0)
> +
> +LEAF(_mips_interrupt)
> +       .set push
> +       .set noreorder
> +       .set noat
> +       LA      $k0, _count_wrap
> +       lw      $k1, 0($k0)
> +       addiu   $k1, $k1, 1
> +       sw      $k1, 0($k0)
> +       mtc0    $0, C0_COMPARE
> +       eret
> +       .set pop
> +END(_mips_interrupt)
> +
> +LEAF(mips_stop_minimal_counter)
> +       LA      $11, _count_wrap
> +       mfc0    $9, C0_COUNT
> +       di      $8
> +       ehb
> +       lw      $11, 0($11)
> +       li      $12, ~SR_HINT5
> +       and     $8, $8, $12
> +       mfc0    $10, C0_COUNT
> +       sltu    $9, $10, $9
> +       ori     $8, $8, SR_IE
> +       beqz    $9, 1f
> +       addiu   $11, $11, 1
> +1:
> +       sw      $11, 0($4)
> +       sw      $10, 0($5)
> +       mtc0    $8, C0_SR
> +       jr      $31
> +END(mips_stop_minimal_counter)
> diff --git a/libgloss/mips/hal/mips_flush_cache.c
> b/libgloss/mips/hal/mips_flush_cache.c
> new file mode 100644
> index 000000000..f651e6d51
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_flush_cache.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +
> +/* Writeback and invalidate all caches */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_flush_cache (void)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If D-cache is present */
> +  if (mips_dcache_size > 0)
> +    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_dcache_size,
> +                  mips_dcache_linesize, Index_Writeback_Inv_D);
> +
> +  /* If I-cache is present */
> +  if (mips_icache_size > 0)
> +    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_icache_size,
> +                  mips_icache_linesize, Index_Invalidate_I);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_size > 0)
> +    {
> +      mips_sync ();
> +      mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size,
> +                    mips_scache_linesize, Index_Writeback_Inv_S);
> +    }
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/* Writeback and invalidate D-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_flush_dcache (void)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If D-cache is present */
> +  if (mips_dcache_size > 0)
> +    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_dcache_size,
> +                  mips_dcache_linesize, Index_Writeback_Inv_D);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_size > 0)
> +    {
> +      mips_sync ();
> +      mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size,
> +                    mips_scache_linesize, Index_Writeback_Inv_S);
> +    }
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/* Writeback and invalidate I-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_flush_icache (void)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If I-cache is present */
> +  if (mips_icache_size > 0)
> +    mips_cache_op ((vaddr_t) KSEG0_BASE, mips_icache_size,
> +                  mips_icache_linesize, Index_Invalidate_I);
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_size > 0)
> +    {
> +      mips_sync ();
> +      mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size,
> +                    mips_scache_linesize, Index_Writeback_Inv_S);
> +    }
> +
> +  mips_sync ();
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_fp.S b/libgloss/mips/hal/mips_fp.S
> new file mode 100644
> index 000000000..801ba79e2
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_fp.S
> @@ -0,0 +1,184 @@
> +/*
> + * Copyright 2015-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +.module hardfloat
> +.module doublefloat
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +
> +MIPS_NOMIPS16
> +
> +#undef fp
> +
> +/*
> + * FUNCTION:   _fpctx_save
> + * DESCRIPTION:        save floating point registers to memory starting
> at a0
> + * RETURNS:    int
> + *             0:      No context saved
> + *             CTX_*:  Type of context stored
> + */
> +LEAF(_fpctx_save)
> +       move    a1, a0
> +       PTR_S   zero, LINKCTX_NEXT(a1)
> +       mfc0    t0, C0_STATUS
> +       li      t1, SR_CU1
> +       and     t1, t0, t1
> +       bnez    t1, 1f
> +       /* FP not enabled, bail out */
> +       move    va0, zero
> +       jr      ra
> +
> +1:     /* Save FP32 base */
> +       li      t1, SR_FR
> +       and     t0, t0, t1
> +       cfc1    t2, $31
> +       REG_S   t2, FP32CTX_CSR(a1)
> +       sdc1    $f0, FP32CTX_0(a1)
> +       sdc1    $f2, FP32CTX_2(a1)
> +       sdc1    $f4, FP32CTX_4(a1)
> +       sdc1    $f6, FP32CTX_6(a1)
> +       sdc1    $f8, FP32CTX_8(a1)
> +       sdc1    $f10, FP32CTX_10(a1)
> +       sdc1    $f12, FP32CTX_12(a1)
> +       sdc1    $f14, FP32CTX_14(a1)
> +       sdc1    $f16, FP32CTX_16(a1)
> +       sdc1    $f18, FP32CTX_18(a1)
> +       sdc1    $f20, FP32CTX_20(a1)
> +       sdc1    $f22, FP32CTX_22(a1)
> +       sdc1    $f24, FP32CTX_24(a1)
> +       sdc1    $f26, FP32CTX_26(a1)
> +       sdc1    $f28, FP32CTX_28(a1)
> +       sdc1    $f30, FP32CTX_30(a1)
> +       bnez    t0, 2f
> +       li      va0, LINKCTX_TYPE_FP32
> +       REG_S   va0, LINKCTX_ID(a1)
> +       jr      ra
> +
> +2:     /* Save FP64 extra */
> +.set   push
> +.set   fp=64
> +       sdc1    $f1, FP64CTX_1(a1)
> +       sdc1    $f3, FP64CTX_3(a1)
> +       sdc1    $f5, FP64CTX_5(a1)
> +       sdc1    $f7, FP64CTX_7(a1)
> +       sdc1    $f9, FP64CTX_9(a1)
> +       sdc1    $f11, FP64CTX_11(a1)
> +       sdc1    $f13, FP64CTX_13(a1)
> +       sdc1    $f15, FP64CTX_15(a1)
> +       sdc1    $f17, FP64CTX_17(a1)
> +       sdc1    $f19, FP64CTX_19(a1)
> +       sdc1    $f21, FP64CTX_21(a1)
> +       sdc1    $f23, FP64CTX_23(a1)
> +       sdc1    $f25, FP64CTX_25(a1)
> +       sdc1    $f27, FP64CTX_27(a1)
> +       sdc1    $f29, FP64CTX_29(a1)
> +       sdc1    $f31, FP64CTX_31(a1)
> +.set   pop
> +       li      va0, LINKCTX_TYPE_FP64
> +       REG_S   va0, LINKCTX_ID(a0)
> +       jr      ra
> +END(_fpctx_save)
> +
> +/*
> + * FUNCTION:   _fpctx_load
> + * DESCRIPTION:        load floating point registers from context chain
> starting at a0
> + * RETURNS:    int
> + *             0:      Unrecognised context
> + *             CTX_*:  Type of context restored
> + */
> +LEAF(_fpctx_load)
> +       move    a1, a0
> +       REG_L   va0, LINKCTX_ID(a1)
> +       /* Detect type */
> +       li      t0, LINKCTX_TYPE_FP64
> +       li      t1, LINKCTX_TYPE_FP32
> +       li      t2, SR_CU1
> +       beq     va0, t0, 0f
> +       beq     va0, t1, 1f
> +       /* Don't recognise this context, fail */
> +       move    va0, zero
> +       jr      ra
> +
> +0:     /* FP64 context - Enable CU1 */
> +       di      t3
> +       ehb
> +       or      t3, t3, t2
> +       mtc0    t3, C0_STATUS
> +       ehb
> +       /* Load FP64 extra */
> +.set   push
> +.set   fp=64
> +       ldc1    $f1, FP64CTX_1(a1)
> +       ldc1    $f3, FP64CTX_3(a1)
> +       ldc1    $f5, FP64CTX_5(a1)
> +       ldc1    $f7, FP64CTX_7(a1)
> +       ldc1    $f9, FP64CTX_9(a1)
> +       ldc1    $f11, FP64CTX_11(a1)
> +       ldc1    $f13, FP64CTX_13(a1)
> +       ldc1    $f15, FP64CTX_15(a1)
> +       ldc1    $f17, FP64CTX_17(a1)
> +       ldc1    $f19, FP64CTX_19(a1)
> +       ldc1    $f21, FP64CTX_21(a1)
> +       ldc1    $f23, FP64CTX_23(a1)
> +       ldc1    $f25, FP64CTX_25(a1)
> +       ldc1    $f27, FP64CTX_27(a1)
> +       ldc1    $f29, FP64CTX_29(a1)
> +       ldc1    $f31, FP64CTX_31(a1)
> +.set   pop
> +1:     /* FP32 context - Enable CU1 */
> +       di      t3
> +       ehb
> +       or      t3, t3, t2
> +       mtc0    t3, C0_STATUS
> +       ehb
> +       /* Load FP32 base */
> +       REG_L   t1, FP32CTX_CSR(a1)
> +       ctc1    t1, $31
> +       ldc1    $f0, FP32CTX_0(a1)
> +       ldc1    $f2, FP32CTX_2(a1)
> +       ldc1    $f4, FP32CTX_4(a1)
> +       ldc1    $f6, FP32CTX_6(a1)
> +       ldc1    $f8, FP32CTX_8(a1)
> +       ldc1    $f10, FP32CTX_10(a1)
> +       ldc1    $f12, FP32CTX_12(a1)
> +       ldc1    $f14, FP32CTX_14(a1)
> +       ldc1    $f16, FP32CTX_16(a1)
> +       ldc1    $f18, FP32CTX_18(a1)
> +       ldc1    $f20, FP32CTX_20(a1)
> +       ldc1    $f22, FP32CTX_22(a1)
> +       ldc1    $f24, FP32CTX_24(a1)
> +       ldc1    $f26, FP32CTX_26(a1)
> +       ldc1    $f28, FP32CTX_28(a1)
> +       ldc1    $f30, FP32CTX_30(a1)
> +       /* Return CTX_FP32/64 */
> +       jr      ra
> +END(_fpctx_load)
> diff --git a/libgloss/mips/hal/mips_intctrl.c
> b/libgloss/mips/hal/mips_intctrl.c
> new file mode 100644
> index 000000000..e1e55b48b
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_intctrl.c
> @@ -0,0 +1,151 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                 affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <mips/cpu.h>
> +#include <mips/hal.h>
> +#include <mips/endian.h>
> +#include <mips/intctrl.h>
> +
> +#define  _mips_intpatch_kscratch1 0x00
> +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined (__mips_micromips)
> +# define  _mips_intpatch_isroff1  0x06
> +# define  _mips_intpatch_isroff2  0x0a
> +# define  _mips_intpatch_isroff3  0x12
> +# define  _mips_intpatch_isroff4  0x1a
> +#else
> +# define  _mips_intpatch_isroff1  0x04
> +# define  _mips_intpatch_isroff2  0x08
> +# define  _mips_intpatch_isroff3  0x10
> +# define  _mips_intpatch_isroff4  0x1c
> +#endif
> +
> +extern void m32_sync_icache(unsigned kva, size_t n);
> +
> +void _MIPS_HAL_NOMIPS16
> +_mips_intpatch (const reg_t index, uintptr_t handler, bool
> k1_to_kscratch1)
> +{
> +  extern void *__isr_vec_space;
> +  uint16_t *patch;
> +  uint32_t *patch32;
> +  uintptr_t isrbase = (uintptr_t) (mips32_getebase() & EBASE_BASE)
> +                     + 0x200 + (index * ((uintptr_t) &__isr_vec_space));
> +  if (k1_to_kscratch1)
> +    {
> +#ifdef __mips_micromips
> +      patch = (uint16_t *) (isrbase + _mips_intpatch_kscratch1);
> +      *(patch++) = 0x037f;
> +      *(patch) = 0x12fc;
> +#else
> +      patch32 = (uint32_t *) (isrbase + _mips_intpatch_kscratch1);
> +      *patch32 = 0x409bf802;
> +#endif
> +    }
> +#if SZPTR==4
> +  handler += (handler & 0x8000) << 1;
> +  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff1);
> +  *patch = (uint16_t) (handler >> 16);         /* %hi */
> +  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff2);
> +  *patch = (uint16_t) (handler & 0xffff);      /* %lo */
> +  m32_sync_icache (isrbase, 32);
> +#elif SZPTR==8
> +  handler += (handler & 0x800080008000) << 1;
> +  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff1);
> +  *patch = (uint16_t) (handler >> 48);                 /* %highest */
> +  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff2);
> +  *patch = (uint16_t) ((handler >> 32) & 0xffff);      /* %higher */
> +  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff3);
> +  *patch = (uint16_t) ((handler >> 16) & 0xffff);      /* %hi */
> +  patch = (uint16_t *) (isrbase + _mips_intpatch_isroff4);
> +  *patch = (uint16_t) (handler & 0xffff);              /* %lo */
> +  m32_sync_icache (isrbase, 64);
> +#else
> +# error "Unknown pointer size"
> +#endif
> +}
> +
> +/*
> + * Interrupt masking and acknowledging functions - these are weak so they
> can
> + * be replaced with versions that understand more complex interrupt
> models.
> + */
> +
> +reg_t __attribute__ ((weak)) _MIPS_HAL_NOMIPS16
> +_mips_intmask (const reg_t index, const reg_t enable)
> +{
> +  register reg_t enbefore, valbefore = 0, indexedbit;
> +
> +  /*
> +   * Calculate which bit upfront to minimise critical section.
> +   * Note that this function supports the MCU ASE, unlike the .h files.
> +   */
> +  if ((index >= 0) && (index <= 8))
> +    /* Traditional/1st MCU ASE interrupt.  */
> +    indexedbit = SR_IM0 << index;
> +  else if (index == 9)
> +    /* 2nd MCU ASE interrupt.  */
> +    indexedbit = SR_IM7 << 2;
> +
> +  /* Make sure we can safely adjust the mask.  */
> +  enbefore = _mips_intdisable ();
> +
> +  /* Make the change.  */
> +  valbefore = mips32_bcssr (indexedbit, enable ? indexedbit : 0);
> +
> +  /* Go live again.  */
> +  _mips_intrestore (enbefore);
> +
> +  /* Return true if it was enabled, again outside critical section.  */
> +  return (valbefore & indexedbit) != 0;
> +}
> +
> +reg_t __attribute__ ((weak)) _MIPS_HAL_NOMIPS16
> +_mips_intack (const reg_t index)
> +{
> +  reg_t enbefore, indexedbit;
> +  reg_t valbefore = 0;
> +
> +  /* We only handle software interrupts - bail out otherwise.  */
> +  if ((index < 0) && (index > 1))
> +    return 0;
> +
> +  /* Calculate which bit upfront to minimise critical section.  */
> +  indexedbit = CR_IP0 << index;
> +
> +  /* Make sure we can safely adjust the state.  */
> +  enbefore = _mips_intdisable ();
> +
> +  /* Make the change. */
> +  valbefore = mips32_bicsr (indexedbit);
> +
> +  /* Go live again.  */
> +  _mips_intrestore (enbefore);
> +
> +  /* Return true if it was enabled, again outside critical section.  */
> +  return (valbefore & indexedbit) != 0;
> +}
> diff --git a/libgloss/mips/hal/mips_l2size.c
> b/libgloss/mips/hal/mips_l2size.c
> new file mode 100644
> index 000000000..960205ba3
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_l2size.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +#include <mips/uhi_syscalls.h>
> +
> +static void __attribute__ ((noreturn)) _MIPS_HAL_NOMIPS16
> +__boot_fail (void)
> +{
> +  register long arg1 asm ("$4") = __MIPS_UHI_BF_CACHE; /* L2 cache
> configuration error */
> +  register long op asm ("$25") = __MIPS_UHI_BOOTFAIL;
> +  register long ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM;
> +
> +  __asm__ volatile (" # %0 = bootfail(%0, %1) op=%2\n"
> +                   SYSCALL (__MIPS_UHI_SYSCALL_NUM)
> +                   : "+r" (ret)
> +                   : "r" (arg1), "r" (op));
> +
> +  __boot_fail ();
> +}
> +
> +/*
> + * Internal routine to determine cache sizes by looking at config
> + * registers.  Sizing information is stored directly to memory.
> +*/
> +void _MIPS_HAL_NOMIPS16
> +__def_cache_size_hook (void)
> +{
> +  /*
> +   * Fall back to Config2 based L2 if Config3[M] or Config4[M]
> +   * or Config5[L2C] is not present.
> +  */
> +  if ((mips32_getconfig3 () & CFG3_M) == 0
> +      || (mips32_getconfig4 () & CFG4_M) == 0
> +      || (mips32_getconfig5 () & CFG5_L2C) == 0)
> +    {
> +      unsigned int cfg, tmp1, tmp2;
> +
> +      cfg = mips32_getconfig2 ();
> +
> +      /* Get S-cache line size (log2) */
> +      tmp1 = (cfg & CFG2_SL_MASK) >> CFG2_SL_SHIFT;
> +      if (tmp1 == 0)
> +       return; /* No S-cache */
> +
> +      tmp1++;
> +
> +      /* Get number of S-cache ways */
> +      mips_scache_ways = ((cfg & CFG2_SA_MASK) >> CFG2_SA_SHIFT) + 1;
> +
> +      /* Total scache size = lines/way * linesize * ways */
> +      mips_scache_linesize = 1 << tmp1;
> +      tmp2 = mips_scache_ways << tmp1;
> +
> +      /* Get scache lines per way */
> +      tmp1 = ((cfg & CFG2_SS_MASK) >> CFG2_SS_SHIFT) + 6;
> +      mips_scache_size = tmp2 << tmp1;
> +
> +      return;
> +    }
> +
> +  /*
> +   * No CM3 code supplied but we have a memory mapped L2 config.
> +   * Report a boot failure through UHI.
> +  */
> +  __boot_fail ();
> +}
> +
> +void __cache_size_hook (void) __attribute__ ((weak, alias
> ("__def_cache_size_hook")));
> diff --git a/libgloss/mips/hal/mips_lock_cache.c
> b/libgloss/mips/hal/mips_lock_cache.c
> new file mode 100644
> index 000000000..475e2e84c
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_lock_cache.c
> @@ -0,0 +1,83 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +
> +/*
> + * The MIPS32 cache architecture does support per-line cache locking.
> + * If you lock any cache lines, then don't call the mips_flush_cache
> + * routine, because these will flush the locked data out of the cache
> + * too; use only mips_clean_xcache routines.
> +*/
> +
> +/* Load and lock a block of data into the D-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_lock_dcache (vaddr_t data, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If D-cache is present */
> +  if (mips_dcache_linesize > 0)
> +    mips_cache_op (data, n, mips_dcache_linesize, Fetch_Lock_D);
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/* Load and lock a block of instructions into the I-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_lock_icache (vaddr_t code, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If I-cache is present */
> +  if (mips_icache_linesize > 0)
> +    mips_cache_op (code, n, mips_icache_linesize, Fetch_Lock_I);
> +
> +  mips_sync ();
> +  return;
> +}
> +
> +/* Load and lock a block of data into the L2-cache */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_lock_scache (vaddr_t data, size_t n)
> +{
> +  /* Calculate cache sizes */
> +  mips_size_cache ();
> +
> +  /* If L2-cache is present */
> +  if (mips_scache_linesize > 0)
> +    mips_cache_op (data, n, mips_scache_linesize, Fetch_Lock_S);
> +
> +  mips_sync ();
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_msa.S b/libgloss/mips/hal/mips_msa.S
> new file mode 100644
> index 000000000..3d59fa179
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_msa.S
> @@ -0,0 +1,183 @@
> +/*
> + * Copyright 2015-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#if __mips_isa_rev < 6 || !defined(__mips_micromips)
> +.module hardfloat
> +.module doublefloat
> +#undef fp
> +.module fp=64
> +.module msa
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +
> +MIPS_NOMIPS16
> +
> +/*
> + * FUNCTION:   _msactx_save
> + * DESCRIPTION:        save MSA registers to memory starting at a0
> + * RETURNS:    int
> + *             0:      No context saved
> + *             CTX_*:  Type of context stored
> + */
> +LEAF(_msactx_save)
> +       move    a1, a0
> +       PTR_S   zero, LINKCTX_NEXT(a1)
> +       mfc0    t0, C0_CONFIG5
> +       ext     t0, t0, CFG5_MSAEN_SHIFT, 1
> +       bnez    t0, 1f
> +       /* MSA not enabled, bail out */
> +       move    va0, zero
> +       jr      ra
> +
> +       /* Save FCSR if necessary */
> +1:     mfc0    t0, C0_STATUS
> +       ext     t1, t0, SR_CU1_SHIFT, 1
> +       lui     va0, %hi(LINKCTX_TYPE_MSA)
> +       beqz    t1, 2f
> +       lui     va0, %hi(LINKCTX_TYPE_FMSA)
> +       cfc1    t2, $31
> +       REG_S   t2, MSACTX_FCSR(a1)
> +       /* Save MSA */
> +2:     ori     va0, va0, %lo(LINKCTX_TYPE_MSA)
> +       cfcmsa  t0, $1
> +       REG_S   t0, MSACTX_MSACSR(a1)
> +       st.d     $w0, MSACTX_0(a1)
> +       st.d     $w1, MSACTX_1(a1)
> +       st.d     $w2, MSACTX_2(a1)
> +       st.d     $w3, MSACTX_3(a1)
> +       st.d     $w4, MSACTX_4(a1)
> +       st.d     $w5, MSACTX_5(a1)
> +       st.d     $w6, MSACTX_6(a1)
> +       st.d     $w7, MSACTX_7(a1)
> +       st.d     $w8, MSACTX_8(a1)
> +       st.d     $w9, MSACTX_9(a1)
> +       st.d    $w10, MSACTX_10(a1)
> +       st.d    $w11, MSACTX_11(a1)
> +       st.d    $w12, MSACTX_12(a1)
> +       st.d    $w13, MSACTX_13(a1)
> +       st.d    $w14, MSACTX_14(a1)
> +       st.d    $w15, MSACTX_15(a1)
> +       st.d    $w16, MSACTX_16(a1)
> +       st.d    $w17, MSACTX_17(a1)
> +       st.d    $w18, MSACTX_18(a1)
> +       st.d    $w19, MSACTX_19(a1)
> +       st.d    $w20, MSACTX_20(a1)
> +       st.d    $w21, MSACTX_21(a1)
> +       st.d    $w22, MSACTX_22(a1)
> +       st.d    $w23, MSACTX_23(a1)
> +       st.d    $w24, MSACTX_24(a1)
> +       st.d    $w25, MSACTX_25(a1)
> +       st.d    $w26, MSACTX_26(a1)
> +       st.d    $w27, MSACTX_27(a1)
> +       st.d    $w28, MSACTX_28(a1)
> +       st.d    $w29, MSACTX_29(a1)
> +       st.d    $w30, MSACTX_30(a1)
> +       st.d    $w31, MSACTX_31(a1)
> +       REG_S   va0, LINKCTX_ID(a1)
> +       jr      ra
> +END(_msactx_save)
> +
> +/*
> + * FUNCTION:   _msactx_load
> + * DESCRIPTION:        load MSA/floating point registers from memory
> starting at a0
> + * RETURNS:    int
> + *             0:      Unrecognised context
> + *             CTX_*:  Type of context restored
> + */
> +LEAF(_msactx_load)
> +       move    a1, a0
> +       REG_L   va0, LINKCTX_ID(a1)
> +       /* Detect type */
> +       li      t0, LINKCTX_TYPE_FMSA
> +       li      t1, LINKCTX_TYPE_MSA
> +       li      t2, SR_CU1
> +       beq     va0, t0, 0f
> +       beq     va0, t1, 1f
> +       /* Don't recognise this context, fail */
> +       move    va0, zero
> +       jr      ra
> +
> +0:     /* FPU+MSA context - Enable CU1 */
> +       di      t3
> +       ehb
> +       or      t3, t3, t2
> +       mtc0    t3, C0_STATUS
> +       ehb
> +       REG_L   t1, MSACTX_FCSR(a1)
> +       ctc1    t1, $31
> +1:     /* MSA context - Enable MSA */
> +       li      t3, CFG5_MSAEN
> +       mfc0    t2, C0_CONFIG5
> +       or      t2, t3, t2
> +       mtc0    t2, C0_CONFIG5
> +       ehb
> +       /* Load MSA */
> +       lw      t3, MSACTX_MSACSR(a1)
> +       ctcmsa  $1, t3
> +       ld.d     $w0, MSACTX_0(a1)
> +       ld.d     $w1, MSACTX_1(a1)
> +       ld.d     $w2, MSACTX_2(a1)
> +       ld.d     $w3, MSACTX_3(a1)
> +       ld.d     $w4, MSACTX_4(a1)
> +       ld.d     $w5, MSACTX_5(a1)
> +       ld.d     $w6, MSACTX_6(a1)
> +       ld.d     $w7, MSACTX_7(a1)
> +       ld.d     $w8, MSACTX_8(a1)
> +       ld.d     $w9, MSACTX_9(a1)
> +       ld.d    $w10, MSACTX_10(a1)
> +       ld.d    $w11, MSACTX_11(a1)
> +       ld.d    $w12, MSACTX_12(a1)
> +       ld.d    $w13, MSACTX_13(a1)
> +       ld.d    $w14, MSACTX_14(a1)
> +       ld.d    $w15, MSACTX_15(a1)
> +       ld.d    $w16, MSACTX_16(a1)
> +       ld.d    $w17, MSACTX_17(a1)
> +       ld.d    $w18, MSACTX_18(a1)
> +       ld.d    $w19, MSACTX_19(a1)
> +       ld.d    $w20, MSACTX_20(a1)
> +       ld.d    $w21, MSACTX_21(a1)
> +       ld.d    $w22, MSACTX_22(a1)
> +       ld.d    $w23, MSACTX_23(a1)
> +       ld.d    $w24, MSACTX_24(a1)
> +       ld.d    $w25, MSACTX_25(a1)
> +       ld.d    $w26, MSACTX_26(a1)
> +       ld.d    $w27, MSACTX_27(a1)
> +       ld.d    $w28, MSACTX_28(a1)
> +       ld.d    $w29, MSACTX_29(a1)
> +       ld.d    $w30, MSACTX_30(a1)
> +       ld.w    $w31, MSACTX_31(a1)
> +       /* Return CTX_(F)MSA */
> +       jr      ra
> +END(_msactx_load)
> +
> +#endif // __mips_isa_rev < 6 || !defined(__micromips__)
> diff --git a/libgloss/mips/hal/mips_size_cache.c
> b/libgloss/mips/hal/mips_size_cache.c
> new file mode 100644
> index 000000000..74a2c49f0
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_size_cache.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +
> +int mips_icache_size = -1;
> +int mips_icache_linesize = -1;
> +int mips_icache_ways = 1;
> +
> +int mips_dcache_size = -1;
> +int mips_dcache_linesize = -1;
> +int mips_dcache_ways = 1;
> +
> +int mips_scache_size = -1;
> +int mips_scache_linesize = -1;
> +int mips_scache_ways = 1;
> +
> +int mips_tcache_size = -1;
> +int mips_tcache_linesize = -1;
> +int mips_tcache_ways = 1;
> +
> +extern void __cache_size_hook (void);
> +
> +/*
> + * Size caches without reinitialising and losing dirty cache lines.
> + * Update mips_icache_* and mips_dcache_* global variables.
> +*/
> +void _MIPS_HAL_NOMIPS16
> +mips_size_cache (void)
> +{
> +  int lsize, ways;
> +  unsigned int cfg;
> +
> +  /* Return if sizes are already known */
> +  if (mips_icache_size > 0)
> +    return;
> +
> +  /* Check presence of Config1 */
> +  cfg = mips32_getconfig0 ();
> +  if ((cfg & CFG0_M))
> +    {
> +      /* Check if I-cache is present */
> +      cfg = mips32_getconfig1 ();
> +      lsize = (cfg & CFG1_IL_MASK) >> CFG1_IL_SHIFT;
> +      if (lsize)
> +       {
> +         lsize++;
> +
> +         /* Get number of I-cache ways */
> +         ways = ((cfg & CFG1_IA_MASK) >> CFG1_IA_SHIFT) + 1;
> +         mips_icache_ways = ways;
> +         mips_icache_linesize = 1 << lsize;
> +         ways = ways << lsize;
> +
> +         /* Get I-cache lines per way */
> +         lsize = ((((cfg & CFG1_IS_MASK) >> CFG1_IS_SHIFT) + 1) & 7) + 5;
> +         mips_icache_size = ways << lsize;
> +       }
> +
> +      /* Check if D-cache is present */
> +      lsize = (cfg & CFG1_DL_MASK) >> CFG1_DL_SHIFT;
> +      if (lsize)
> +       {
> +         lsize++;
> +
> +         /* Get number of D-cache ways */
> +         ways = ((cfg & CFG1_DA_MASK) >> CFG1_DA_SHIFT) + 1;
> +         mips_dcache_ways = ways;
> +         mips_dcache_linesize = 1 << lsize;
> +         ways = ways << lsize;
> +
> +         /* Get D-cache lines per way */
> +         lsize = ((((cfg & CFG1_DS_MASK) >> CFG1_DS_SHIFT) + 1) & 7) + 5;
> +         mips_dcache_size = ways << lsize;
> +       }
> +    }
> +
> +  __cache_size_hook ();
> +
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_sync_cache.c
> b/libgloss/mips/hal/mips_sync_cache.c
> new file mode 100644
> index 000000000..69425fa46
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_sync_cache.c
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +
> +/* Synchronise I-cache for virtual address range */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_sync_icache (vaddr_t kva, size_t n)
> +{
> +  int step;
> +  vaddr_t addr, maxaddr, mask;
> +
> +  /* Check for bad size */
> +  if (n <= 0)
> +    return;
> +
> +  /* Get synci step and skip if not required */
> +  step = mips_synci_step ();
> +  if (step == 0)
> +    return;
> +
> +  mips_sync ();
> +
> +  mask = ~ (step - 1);
> +  addr = (kva & mask) - step;
> +  maxaddr = ((kva + n) - 1) & mask;
> +
> +  do
> +    {
> +      addr = addr + step;
> +      mips_synci (addr);
> +    }
> +  while (addr != maxaddr);
> +
> +  mips_sync ();
> +  return;
> +}
> diff --git a/libgloss/mips/hal/mips_tlb.c b/libgloss/mips/hal/mips_tlb.c
> new file mode 100644
> index 000000000..eb43c0483
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_tlb.c
> @@ -0,0 +1,479 @@
> +/*
> + * Copyright 2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include "cache.h"
> +#include <mips/hal.h>
> +#include <mips/m32tlb.h>
> +
> +/* Writes hi, lo0, lo1 and mask into the TLB entry specified by index */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_tlbwi2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask,
> +                 int index)
> +{
> +  mips32_setentryhi (hi);
> +  mips32_setentrylo0 (lo0);
> +  mips32_setentrylo1 (lo1);
> +  mips32_setpagemask (mask);
> +  mips32_setindex (index);
> +  mips_ehb ();
> +  mips_tlbwi ();
> +  return;
> +}
> +
> +/*
> + * Writes hi, lo0, lo1 and mask into the TLB entry specified by the
> + * random register.
> +*/
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_tlbwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask)
> +{
> +  mips32_setentryhi (hi);
> +  mips32_setentrylo0 (lo0);
> +  mips32_setentrylo1 (lo1);
> +  mips32_setpagemask (mask);
> +  mips_ehb ();
> +  mips_tlbwr ();
> +  return;
> +}
> +
> +/*
> + * Probes the TLB for an entry matching hi and if present rewrites that
> entry,
> + * otherwise updates a random entry.  A safe way to update the TLB.
> +*/
> +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_tlbrwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask)
> +{
> +  int index;
> +  tlbhi_t prev_hi;
> +
> +  prev_hi = mips32_getentryhi ();
> +  mips32_setentryhi (hi);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbp ();
> +  mips_ehb (); /* tlbp hazard on mfc0 */
> +
> +  index = mips32_getindex ();
> +  mips32_setentrylo0 (lo0);
> +  mips32_setentrylo1 (lo1);
> +  mips32_setpagemask (mask);
> +  mips_ehb (); /* mtc0 hazard on tlbwi/tlbwr */
> +
> +  /* Check if entry matches */
> +  if (index >= 0)
> +    mips_tlbwi ();
> +  else
> +    mips_tlbwr ();
> +
> +  mips32_setentryhi (prev_hi);
> +
> +  return index;
> +}
> +
> +/*
> + * Reads the TLB entry specified by index, and returns the EntryHi,
> + * EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmask
> + * respectively.
> +*/
> +void _MIPS_HAL_NOMIPS16
> +mips_tlbri2 (tlbhi_t *phi, tlblo_t *plo0, tlblo_t *plo1,
> +            unsigned int *pmask, int index)
> +{
> +  mips32_setindex (index);
> +  mips_ehb (); /* mtc0 hazard on tlbr */
> +  mips_tlbr ();
> +  mips_ehb (); /* tlbr hazard on mfc0 */
> +  *phi = mips32_getentryhi ();
> +  *plo0 = mips32_getentrylo0 ();
> +  *plo1 = mips32_getentrylo1 ();
> +  *pmask = mips32_getpagemask ();
> +  return;
> +}
> +
> +/*
> + * Probes the TLB for an entry matching hi and return its index, or -1 if
> + * not found. If found, the EntryLo0, EntryLo1 and PageMask parts of the
> + * entry are also returned in *plo0, *plo1 and *pmask respectively.
> +*/
> +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_tlbprobe2 (tlbhi_t hi, tlblo_t *plo0, tlblo_t *plo1,
> +               unsigned int *pmask)
> +{
> +  int index;
> +  tlbhi_t prev_hi;
> +
> +  prev_hi = mips32_getentryhi ();
> +  mips32_setentryhi (hi);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbp ();
> +  mips_ehb (); /* tlbp hazard on mfc0 */
> +
> +  index = mips32_getindex ();
> +
> +  if (index >= 0)
> +    {
> +      mips_tlbr ();
> +      mips_ehb ();     /* tlbr hazard on mfc0 */
> +      *plo0 = mips32_getentrylo0 ();
> +      *plo1 = mips32_getentrylo1 ();
> +      *pmask = mips32_getpagemask ();
> +    }
> +  else
> +     index = -1;
> +
> +  mips32_setentryhi (prev_hi); /* restore EntryHi */
> +
> +  return index;
> +}
> +
> +/* Probes the TLB for an entry matching hi, and if present invalidates it
> */
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_tlbinval (tlbhi_t hi)
> +{
> +  int index, tmp_idx;
> +  tlbhi_t prev_hi, tmp_hi = 0;
> +  register const int zero = 0;
> +  unsigned int cfg;
> +
> +  prev_hi = mips32_getentryhi ();
> +  mips32_setentryhi (hi);
> +
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbp ();
> +  mips_ehb (); /* tlbp hazard on mfc0 */
> +
> +  index = mips32_getindex ();
> +
> +  if (index < 0)
> +    goto restore;
> +
> +  mips32_setentrylo0 (zero);
> +  mips32_setentrylo1 (zero);
> +
> +  /* Check if Config4 is implemented */
> +  cfg = mips32_getconfig3 ();
> +  if ((cfg & CFG3_M) != 0)
> +    {
> +      cfg = mips32_getconfig4 ();
> +      if ((cfg & CFG4_IE_MASK) != 0)
> +       {
> +         tmp_hi = C0_ENTRYHI_EHINV_MASK;
> +         goto do_tlbwi;
> +       }
> +    }
> +
> +  tmp_hi = (tlbhi_t) ((unsigned long) KSEG0_BASE - 0x4000);
> +
> +  do
> +    {
> +      tmp_hi = tmp_hi + 0x4000;
> +      mips32_setentryhi (tmp_hi);
> +      mips_ehb ();             /* mtc0 hazard on tlbp */
> +      mips_tlbp ();
> +      mips_ehb ();             /* tlbp hazard on mfc0 */
> +      tmp_idx = mips32_getindex ();
> +    }
> +  while (tmp_idx >= 0);
> +
> +  mips32_setindex (index);     /* restore Index */
> +
> +do_tlbwi:
> +  mips32_setentryhi (tmp_hi);
> +  mips_ehb (); /* mtc0 hazard on tlbp */
> +  mips_tlbwi ();
> +  mips_ehb (); /* tlbwi hazard on mfc0 */
> +
> +restore:
> +  mips32_setentryhi (prev_hi); /* restore EntryHi */
> +
> +  return;
> +}
> +
> +/*
> + * Return number of entries and sets in TLB.
> + * Return number of entries in *pentries and
> + * sets in *psets
> +*/
> +static void _MIPS_HAL_NOMIPS16
> +mips_tlb_entries_sets (int *pentries, int *psets)
> +{
> +  int entries = 0, sets = 0, ways = 0;
> +  unsigned int cfg, cfg1, tcfg, tmp;
> +
> +  cfg = mips32_getconfig ();
> +  cfg = (cfg & CFG0_MT_MASK) >> CFG0_MT_SHIFT;
> +  if ((cfg == 0) /* No MMU */
> +      || (cfg == (CFG0_MT_FIXED >> CFG0_MT_SHIFT)) /* fixed address
> translation */
> +      || (cfg == (CFG0_MT_BAT >> CFG0_MT_SHIFT)) /* block address
> translator */
> +      || ((cfg & ((CFG0_MT_TLB | CFG0_MT_DUAL) >> CFG0_MT_SHIFT)) == 0))
> /* presence of TLB */
> +    {
> +      *pentries = 0;
> +      *psets = 0;
> +      return;
> +    }
> +
> +  cfg1 = mips32_getconfig1 ();
> +
> +  /*
> +   * As per PRA, field holds number of entries - 1
> +   * Standard TLBs and dual TLBs have extension fields.
> +  */
> +  entries = ((cfg1 & CFG1_MMUS_MASK) >> CFG1_MMUSSHIFT) + 1;
> +
> +  tcfg = mips32_getconfig3 ();
> +  if ((tcfg & CFG3_M) == 0)
> +    goto doReturn;
> +
> +  tcfg = mips32_getconfig4 ();
> +
> +#if (__mips_isa_rev < 6)
> +  tmp = (tcfg & CFG4_MMUED) >> CFG4_MMUED_SHIFT;
> +
> +  /* MMU Extension Definition */
> +  if (tmp == (CFG4_MMUED_FTLBVEXT >> CFG4_MMUED_SHIFT))
> +    goto doFTLBVTLB;
> +
> +  /* MMUSizeExt */
> +  if (tmp == (CFG4_MMUED_SIZEEXT >> CFG4_MMUED_SHIFT))
> +    goto doSizeExt;
> +
> +  if (tmp == 0)
> +    goto doReturn;
> +
> +  goto doFTLBSize;
> +
> +doSizeExt:
> +  entries += ((tcfg & CFG4_MMUSE_MASK) >> CFG4_MMUSE_SHIFT)
> +             << CFG1_MMUS_BITS;
> +  goto doReturn;
> +#endif
> +
> +doFTLBVTLB:
> +  entries += ((tcfg & CFG4_VTLBSEXT_MASK) >> CFG4_VTLBSEXT_SHIFT)
> +             << CFG1_MMUS_BITS;
> +
> +doFTLBSize:
> +  /* Skip FTLB size calculations if Config:MT != 4 */
> +  if (cfg != (CFG0_MT_DUAL >> CFG0_MT_SHIFT))
> +    goto doReturn;
> +
> +  /* Ways */
> +  ways = 2 + ((tcfg & CFG4_FTLBW_MASK) >> CFG4_FTLBW_SHIFT);
> +
> +  /* Sets per way */
> +  tmp = ((tcfg & CFG4_FTLBS_MASK) >> CFG4_FTLBS_SHIFT);
> +  sets = 1 << tmp;
> +
> +  /* Total sets */
> +  entries += ways << tmp;
> +
> +doReturn:
> +  *pentries = entries;
> +  *psets = sets;
> +
> +  return;
> +}
> +
> +/*
> + * Return number of entries in TLB
> + * This function is used for both mips64 and mips32
> +*/
> +int _MIPS_HAL_NOMIPS16
> +mips_tlb_size (void)
> +{
> +  int entries = 0, sets = 0;
> +  mips_tlb_entries_sets (&entries, &sets);
> +  (void) sets;
> +  return entries;
> +}
> +
> +/*
> + * Invalidate the whole TLB.
> + * This function is used for both mips64 and mips32
> +*/
> +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16
> +mips_tlbinvalall (void)
> +{
> +  unsigned int cfg0, cfg;
> +  unsigned long tmp_hi, tmp_hi2;
> +  int entries = 0, sets = 0, tlb_stride = 0;
> +  int end_ptr = 0, index = 0;
> +  register const unsigned long zero = 0;
> +  extern void *__tlb_stride_length;
> +
> +  cfg0 = mips32_getconfig ();
> +  cfg0 = (cfg0 & CFG0_MT_MASK) >> CFG0_MT_SHIFT;
> +  if ((cfg0 == 0) /* No MMU */
> +      || (cfg0 == (CFG0_MT_FIXED >> CFG0_MT_SHIFT)) /* fixed address
> translation */
> +      || (cfg0 == (CFG0_MT_BAT >> CFG0_MT_SHIFT))) /* block address
> translator */
> +    goto doReturn;
> +
> +  mips_setentrylo0 (zero);
> +  mips_setentrylo1 (zero);
> +  mips_setpagemask (zero);
> +
> +  /* Fetch size & number of sets */
> +  mips_tlb_entries_sets (&entries, &sets);
> +
> +  cfg = mips32_getconfig3 ();
> +  if ((cfg & CFG3_M) == 0)
> +    goto doBasicInval;
> +
> +  cfg = mips32_getconfig4 ();
> +  cfg = (cfg & CFG4_IE_MASK) >> CFG4_IE_SHIFT;
> +
> +  /* If Config4[IE] = 0, use old method for invalidation */
> +  if (cfg == 0)
> +    goto doBasicInval;
> +
> +  /* If Config4[IE] = 1, EHINV loop */
> +  if (cfg == (CFG4_IE_EHINV >> CFG4_IE_SHIFT))
> +    goto doEHINV;
> +
> +  /* If Config[MT] = 1, one instruction required */
> +  if (cfg0 == (CFG0_MT_TLB >> CFG0_MT_SHIFT)
> +      || cfg == (CFG4_IE_INVALL >> CFG4_IE_SHIFT))
> +    {
> +      /* TLB walk done by hardware, Config4[IE] = 3 or Config[MT] = 1 */
> +      mips32_setindex (zero);
> +      mips_ehb ();
> +      mips_eva_tlbinvf ();
> +      goto doReturn;
> +    }
> +
> +  /*
> +   * TLB walk done by software, Config4[IE] = 2, Config[MT] = 4
> +   *
> +   * One TLBINVF is executed with an index in VTLB range to
> +   * invalidate all VTLB entries.
> +   *
> +   * One TLBINVF is executed per FTLB set.
> +   *
> +   * We'll clean out the TLB by computing the Size of the VTLB
> +   * but not add the 1. This will give us a finger that points
> +   * at the last VTLB entry.
> +  */
> +
> +  /* Clear VTLB */
> +  mips32_setindex (zero);
> +  mips_ehb ();
> +  mips_eva_tlbinvf ();
> +
> +  tlb_stride = (int) ((unsigned long) &__tlb_stride_length);
> +  sets = sets * tlb_stride;
> +  end_ptr = entries - sets;
> +
> +  do
> +    {
> +      entries = entries - tlb_stride;
> +      mips32_setindex (entries);
> +      mips_ehb ();
> +      mips_eva_tlbinvf ();
> +    }
> +  while (entries != end_ptr);
> +
> +  goto doReturn;
> +
> +doEHINV:
> +  /*
> +   * Config4[IE] = 1. EHINV supported, but not tlbinvf.
> +   *
> +   * Invalidate the TLB for R3 onwards by loading EHINV and writing to all
> +   * TLB entries.
> +  */
> +  index = 0;
> +  tmp_hi = C0_ENTRYHI_EHINV_MASK;
> +  mips_setentryhi (tmp_hi);
> +  do
> +    {
> +      mips32_setindex (index);
> +      mips_ehb ();             /* mtc0 hazard on tlbwi */
> +      mips_tlbwi ();
> +      index++;
> +    }
> +  while (entries != index);
> +
> +  goto doReturn;
> +
> +doBasicInval:
> +  /*
> +   * Perform a basic invalidation of the TLB for R1 onwards by loading
> +   * 0x(FFFFFFFF)KSEG0_BASE into EntryHi and writing it into index 0
> +   * incrementing by a pagesize, writing into index 1, etc.
> +   * If large physical addressing is enabled, load 0xFFFFFFFF
> +   * into the top half of EntryHi.
> +  */
> +  tmp_hi = 0;
> +  cfg = mips32_getconfig3 ();
> +
> +  /* If XPA is present */
> +  if ((cfg & CFG3_LPA) != 0)
> +    {
> +      cfg = mips32_getpagegrain ();
> +      if ((cfg & PAGEGRAIN_ELPA) == 0)
> +       tmp_hi = 0xFFFFFFFF;
> +    }
> +
> +  tmp_hi2 = (unsigned long) KSEG0_BASE - 0x4000;
> +  index = 0;
> +
> +  do
> +    {
> +      tmp_hi2 += 0x4000;
> +      mips_setentryhi (tmp_hi2);
> +      if (tmp_hi != 0)
> +       mips32_sethientryhi (tmp_hi);
> +      mips_ehb ();             /* mtc0 hazard on tlbp */
> +      mips_tlbp ();
> +      mips_ehb ();             /* tlbp hazard on mfc0 */
> +      if (mips32_getindex () == 0)
> +       continue;
> +      mips32_setindex (index);
> +      mips_ehb ();             /* mtc0 hazard on tlbwi */
> +      mips_tlbwi ();
> +      index++;
> +    }
> +  while (entries != index);
> +
> +doReturn:
> +  /*
> +   * Clear EntryHI. The upper half is cleared
> +   * autmatically as mtc0 writes zeroes.
> +  */
> +  mips_setentryhi (zero);
> +
> +  return;
> +}
> +
> +_MIPS_HAL_NOMIPS16
> +int m64_tlb_size (void) __attribute__ ((alias ("mips_tlb_size")));
> +_MIPS_HAL_NOMIPS16
> +void m64_tlbinvalall (void) __attribute__ ((alias ("mips_tlbinvalall")));
> diff --git a/libgloss/mips/hal/mips_xpa.S b/libgloss/mips/hal/mips_xpa.S
> new file mode 100644
> index 000000000..5f47e8ff3
> --- /dev/null
> +++ b/libgloss/mips/hal/mips_xpa.S
> @@ -0,0 +1,78 @@
> +/*
> + * Copyright 2015-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <mips/regdef.h>
> +#include <mips/cpu.h>
> +#include <mips/asm.h>
> +#include <mips/hal.h>
> +#include <mips/endian.h>
> +
> +MIPS_NOMIPS16
> +
> +/*
> + * FUNCTION:   _xpa_save
> + * DESCRIPTION:        save the XPA version of badvaddr.
> + * RETURNS:    int
> + *             0:      No context saved
> + *             CTX_*:  Type of conext stored
> + */
> +LEAF(_xpa_save)
> +       move    a1, a0
> +       PTR_S   zero, LINKCTX_NEXT(a1)
> +       /* Test for LPA support */
> +       mfc0    t0, C0_CONFIG3
> +       ext     t0, t0, CFG3_LPA_SHIFT, 1
> +       beqz    t0, 1f
> +       /* Test for LPA enabled */
> +       mfc0    t0, C0_PAGEGRAIN
> +       ext     t0, t0, PAGEGRAIN_ELPA_SHIFT, PAGEGRAIN_ELPA_BITS
> +       bnez    t0, 2f
> +
> +       /* LPA either unavailable or not enabled - return 0 */
> +1:     move    va0, zero
> +       jr      ra
> +
> +2:     lui     va0, %hi(LINKCTX_TYPE_XPA)
> +       addiu   va0, va0, %lo(LINKCTX_TYPE_XPA)
> +       mfc0    t0, C0_BADVADDR
> +       .set push
> +       .set xpa
> +       mfhc0   t1, C0_BADVADDR
> +       .set pop
> +#if BYTE_ORDER == BIG_ENDIAN
> +       sw      t0, XPACTX_BADVADDR(a1)
> +       sw      t1, (XPACTX_BADVADDR+4)(a1)
> +#else /* BYTE ORDER == LITTLE_ENDIAN */
> +       sw      t1, XPACTX_BADVADDR(a1)
> +       sw      t0, (XPACTX_BADVADDR+4)(a1)
> +#endif
> +       REG_S   va0, LINKCTX_ID(a1)
> +       jr ra
> +END(_xpa_save)
> diff --git a/libgloss/mips/hal/syscalls.c b/libgloss/mips/hal/syscalls.c
> new file mode 100644
> index 000000000..d296f538f
> --- /dev/null
> +++ b/libgloss/mips/hal/syscalls.c
> @@ -0,0 +1,51 @@
> +#include <_ansi.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <mips/hal.h>
> +
> +extern char _end[];
> +
> +/* FIXME: This is not ideal, since we do a get_ram_range() call for
> +   every sbrk() call. */
> +char *
> +sbrk (int nbytes)
> +{
> +  static char *heap_ptr = NULL;
> +  static char *heap_start = NULL;
> +  static unsigned long heap_size = 0;
> +  char        *base;
> +  unsigned int avail = 0;
> +  void *ram_base;
> +  void *ram_extent;
> +
> +  if (heap_start == NULL)
> +    {
> +      _get_ram_range (&ram_base, &ram_extent);
> +
> +      /* If the _end symbol is within the RAM then use _end.  */
> +      if ((void*)_end > ram_base && (void*)_end < ram_extent)
> +       {
> +         heap_start = _end;
> +         heap_ptr = _end;
> +         heap_size = ram_extent - (void*)_end;
> +       }
> +      else
> +       {
> +         heap_start = ram_base;
> +         heap_ptr = ram_base;
> +         heap_size = ram_extent - ram_base;
> +       }
> +    }
> +
> +  if ((heap_ptr >= heap_start) && (heap_ptr < (heap_start + heap_size))) {
> +    avail = (heap_start + heap_size) - heap_ptr;
> +    base = heap_ptr;
> +  } /* else will fail since "nbytes" will be greater than zeroed "avail"
> value */
> +
> +  if ((nbytes > avail) || (heap_ptr + nbytes < heap_start))
> +   base = (char *)-1;
> +  else
> +   heap_ptr += nbytes;
> +
> +  return base;
> +}
> diff --git a/libgloss/mips/include/mips/asm.h
> b/libgloss/mips/include/mips/asm.h
> new file mode 100644
> index 000000000..ac9157511
> --- /dev/null
> +++ b/libgloss/mips/include/mips/asm.h
> @@ -0,0 +1,356 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_ASM_H_
> +#define _MIPS_ASM_H_
> +
> +/*
> + * asm.h: various macros to help assembly language writers
> + */
> +
> +/* ABI specific stack frame layout and manipulation. */
> +#if _MIPS_SIM==_ABIO32
> +/* Standard O32 */
> +#define SZREG          4       /* saved register size */
> +#define        REG_S           sw      /* store saved register */
> +#define        REG_L           lw      /* load saved register */
> +#define SZARG          4       /* argument register size */
> +#define        NARGSAVE        4       /* arg register space on caller
> stack */
> +#define ALSZ           7       /* stack alignment - 1 */
> +#define ALMASK         (~7)    /* stack alignment mask */
> +#define LOG2_STACK_ALGN        3       /* log2(8) */
> +#define SZPTR          4       /* pointer size */
> +#define LOG2_SZPTR     2       /* log2(4) */
> +#define PTR_S          sw      /* store pointer */
> +#define PTR_L          lw      /* load pointer */
> +#define PTR_SUBU       subu    /* decrement pointer */
> +#define PTR_ADDU       addu    /* increment pointer */
> +#define PTR_MFC0       mfc0    /* access CP0 pointer width register */
> +#define PTR_MTC0       mtc0    /* access CP0 pointer width register */
> +#define LA             la      /* load an address */
> +#define PTR            .word   /* pointer type pseudo */
> +#elif _MIPS_SIM==_ABIO64
> +/* Cygnus O64 */
> +#define SZREG          8       /* saved register size */
> +#define        REG_S           sd      /* store saved register */
> +#define        REG_L           ld      /* load saved register */
> +#define SZARG          8       /* argument register size */
> +#define        NARGSAVE        4       /* arg register space on caller
> stack */
> +#define ALSZ           7       /* stack alignment - 1 */
> +#define ALMASK         (~7)    /* stack alignment mask */
> +#define LOG2_STACK_ALGN        3       /* log2(8) */
> +#define SZPTR          4       /* pointer size */
> +#define LOG2_SZPTR     2       /* log2(4) */
> +#define PTR_S          sw      /* store pointer */
> +#define PTR_L          lw      /* load pointer */
> +#define PTR_SUBU       subu    /* decrement pointer */
> +#define PTR_ADDU       addu    /* increment pointer */
> +#define PTR_MFC0       dmfc0   /* access CP0 pointer width register */
> +#define PTR_MTC0       mtc0    /* access CP0 pointer width register */
> +#define LA             la      /* load an address */
> +#define PTR            .word   /* pointer type pseudo */
> +#elif _MIPS_SIM==_ABIN32
> +/* Standard N32 */
> +#define SZREG          8       /* saved register size */
> +#define        REG_S           sd      /* store saved register */
> +#define        REG_L           ld      /* load saved register */
> +#define SZARG          8       /* argument register size */
> +#define        NARGSAVE        0       /* arg register space on caller
> stack */
> +#define ALSZ           15      /* stack alignment - 1 */
> +#define ALMASK         (~15)   /* stack alignment mask */
> +#define LOG2_STACK_ALGN        4       /* log2(16) */
> +#define SZPTR          4       /* pointer size */
> +#define LOG2_SZPTR     2       /* log2(4) */
> +#define PTR_S          sw      /* store pointer */
> +#define PTR_L          lw      /* load pointer */
> +#define PTR_SUBU       subu    /* decrement pointer (SGI uses sub) */
> +#define PTR_ADDU       addu    /* increment pointer (SGI uses add) */
> +#define PTR_MFC0       mfc0    /* access CP0 pointer width register */
> +#define PTR_MTC0       mtc0    /* access CP0 pointer width register */
> +#define LA             la      /* load an address */
> +#define PTR            .word   /* pointer type pseudo */
> +#elif _MIPS_SIM==_ABI64
> +/* Standard N64 */
> +#define SZREG          8       /* saved register size */
> +#define        REG_S           sd      /* store saved register */
> +#define        REG_L           ld      /* load saved register */
> +#define SZARG          8       /* argument register size */
> +#define        NARGSAVE        0       /* arg register space on caller
> stack */
> +#define ALSZ           15      /* stack alignment - 1 */
> +#define ALMASK         (~15)   /* stack alignment mask */
> +#define LOG2_STACK_ALGN        4       /* log2(16) */
> +#define SZPTR          8       /* pointer size */
> +#define LOG2_SZPTR     3       /* log2(8) */
> +#define PTR_S          sd      /* store pointer */
> +#define PTR_L          ld      /* load pointer */
> +#define PTR_SUBU       dsubu   /* decrement pointer */
> +#define PTR_ADDU       daddu   /* increment pointer */
> +#define PTR_MFC0       dmfc0   /* access CP0 pointer width register */
> +#define PTR_MTC0       dmtc0   /* access CP0 pointer width register */
> +#define LA             dla     /* load an address */
> +#define PTR            .dword  /* pointer type pseudo */
> +#else
> +#error Unknown ABI
> +#endif
> +
> +#ifdef __ASSEMBLER__
> +
> +/* Concatenate two names. */
> +#ifdef __STDC__
> +# define _ASMCONCAT(A, B) A ## B
> +#else
> +# define _ASMCONCAT(A, B) A/**/B
> +#endif
> +
> +/* Name of reset code section. */
> +#ifndef _RESET_SECTION
> +# define _RESET_SECTION .section .reset, "ax", @progbits
> +#endif
> +
> +#ifndef _RESET_SECTION_NAMED
> +/* No function section support for now, since binutils fails to cope with
> +   external branches. */
> +# define _RESET_SECTION_NAMED(name) .pushsection .reset, "ax", @progbits
> +#endif
> +
> +/* Name of boot code section. */
> +#ifndef _BOOT_SECTION
> +# define _BOOT_SECTION .section .boot, "ax", @progbits
> +#endif
> +
> +#ifndef _BOOT_SECTION_NAMED
> +/* No function section support for now, since binutils fails to cope with
> +   external branches. */
> +# define _BOOT_SECTION_NAMED(name) .pushsection .boot, "ax", @progbits
> +#endif
> +
> +/* Name of standard code section. */
> +#ifndef _NORMAL_SECTION_UNNAMED
> +# define _NORMAL_SECTION_UNNAMED .section .text, "ax", @progbits
> +#endif
> +
> +#ifndef _NORMAL_SECTION_NAMED
> +# ifdef _FUNCTION_SECTIONS_
> +#  define _NORMAL_SECTION_NAMED(name) .pushsection .text ##.name, "ax",
> @progbits
> +# else
> +#  define _NORMAL_SECTION_NAMED(name) .pushsection .text, "ax", @progbits
> +# endif
> +#endif
> +
> +/* Default code section. */
> +#ifndef _TEXT_SECTION_NAMED
> +# if defined(_RESETCODE)
> +#  define _TEXT_SECTION_NAMED _RESET_SECTION_NAMED
> +# elif defined(_BOOTCODE)
> +#  define _TEXT_SECTION_NAMED _BOOT_SECTION_NAMED
> +# else
> +#  define _TEXT_SECTION_NAMED _NORMAL_SECTION_NAMED
> +# endif
> +#endif
> +
> +#ifndef _TEXT_SECTION
> +# if defined(_RESETCODE)
> +#  define _TEXT_SECTION _RESET_SECTION
> +# elif defined(_BOOTCODE)
> +#  define _TEXT_SECTION _BOOT_SECTION
> +# else
> +#  define _TEXT_SECTION _NORMAL_SECTION_UNNAMED
> +# endif
> +       _TEXT_SECTION
> +#endif
> +
> +/*
> + * Leaf functions declarations.
> + */
> +
> +/* Global leaf function. */
> +#define LEAF(name)                     \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .globl  name;                   \
> +       .ent    name;                   \
> +name:
> +
> +/* Static/Local leaf function. */
> +#define SLEAF(name)                    \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .ent    name;                   \
> +name:
> +
> +/* Weak leaf function. */
> +#define WLEAF(name)                    \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .weak   name;                   \
> +       .ent    name;                   \
> +name:
> +
> +/* Weak alias leaf function. */
> +#define ALEAF(name,alias)              \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .weak   alias;                  \
> +       .ent    name;                   \
> +       alias = name;                   \
> +name:
> +
> +/*
> + * Alternative function entrypoints.
> + */
> +
> +/* Global alternative entrypoint. */
> +#define AENT(name)                     \
> +       .globl  name;                   \
> +       .aent   name;                   \
> +name:
> +#define XLEAF(name)    AENT(name)
> +
> +/* Local/static alternative entrypoint. */
> +#define SAENT(name)                    \
> +       .aent   name;                   \
> +name:
> +#define SXLEAF(name)   SAENT(name)
> +
> +
> +/*
> + * Leaf functions declarations.
> + */
> +
> +/* Global nested function. */
> +#define NESTED(name, framesz, rareg)   \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .globl  name;                   \
> +       .ent    name;                   \
> +       .frame  sp, framesz, rareg;     \
> +name:
> +
> +/* Static/Local nested function. */
> +#define SNESTED(name, framesz, rareg)  \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .ent    name;                   \
> +       .frame  sp, framesz, rareg;     \
> +name:
> +
> +/* Weak nested function. */
> +#define WNESTED(name, framesz, rareg)  \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .weak   name;                   \
> +       .ent    name;                   \
> +       .frame  sp, framesz, rareg;     \
> +name:
> +
> +/* Weak alias nested function. */
> +#define ANESTED(name, alias, framesz, rareg) \
> +       _TEXT_SECTION_NAMED(name);      \
> +       .balign 4;                      \
> +       .weak   alias;                  \
> +       .ent    name;                   \
> +       alias = name;                   \
> +       .frame  sp, framesz, rareg;     \
> +name:
> +
> +/*
> + * Function termination
> + */
> +#define END(name)                      \
> +       .size name,.-name;              \
> +       .end    name;                   \
> +       .popsection
> +
> +#define SEND(name)     END(name)
> +#define WEND(name)     END(name)
> +#define AEND(name,alias) END(name)
> +
> +/*
> + * Global data declaration.
> + */
> +#define EXPORT(name) \
> +       .globl name; \
> +       .type name,@object; \
> +name:
> +
> +/*
> + * Global data declaration with size.
> + */
> +#define EXPORTS(name,sz)               \
> +       .globl name;                    \
> +       .type name,@object;             \
> +       .size name,sz;                  \
> +name:
> +
> +/*
> + * Weak data declaration with size.
> + */
> +#define WEXPORT(name,sz)               \
> +       .weak name;                     \
> +       .type name,@object;             \
> +       .size name,sz;                  \
> +name:
> +
> +/*
> + * Global data reference with size.
> + */
> +#define        IMPORT(name, size)              \
> +       .extern name,size
> +
> +/*
> + * Global zeroed data.
> + */
> +#define BSS(name,size)                         \
> +       .type name,@object;             \
> +       .comm   name,size
> +
> +/*
> + * Local zeroed data.
> + */
> +#define LBSS(name,size)                \
> +       .lcomm  name,size
> +
> +/*
> + * Insert call to _mcount if profiling.
> + */
> +#ifdef __PROFILING__
> +#define _MCOUNT                        \
> +       .set push;                      \
> +       .set noat;                      \
> +       move    $1,$31;                 \
> +       jal     _mcount;                \
> +       .set pop
> +#else
> +#define _MCOUNT
> +#endif
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#endif /*_MIPS_ASM_H_*/
> diff --git a/libgloss/mips/include/mips/cm3.h
> b/libgloss/mips/include/mips/cm3.h
> new file mode 100644
> index 000000000..251d39782
> --- /dev/null
> +++ b/libgloss/mips/include/mips/cm3.h
> @@ -0,0 +1,77 @@
> +/*
> + * Copyright 2015-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _CM3_H_
> +#define _CM3_H_
> +
> +#define CMGCR_BASE_ADDR_SHIFT  11
> +
> +#define CMGCR_BASE_ADDR_LSHIFT 4
> +/* Offsets of memory-mapped registers */
> +#define GCR_L2_CONFIG          0x130
> +#define GCR_L2_RAM_CONFIG      0x240
> +#define GCR_TAG_ADDR           0x600
> +#define GCR_TAG_STATE          0x608
> +#define GCR_TAG_DATA           0x610
> +#define GCR_TAG_ECC            0x618
> +
> +/* Contents of  L2 RAM field */
> +#define GCR_L2_RAM_HCID_SHIFT  30
> +#define GCR_L2_RAM_HCID_BITS   1
> +#define GCR_L2_RAM_HCIS_SHIFT  29
> +#define GCR_L2_RAM_HCIS_BITS   1
> +
> +/* L2 Configuration Register */
> +#define GCR_L2_REG_EXISTS_MASK 0x80000000
> +#define GCR_L2_REG_EXISTS_SHIFT        31
> +#define GCR_L2_REG_EXISTS_BITS 1
> +#define GCR_L2_LRU_WE_MASK     (1<<GCR_L2_LRU_WE_SHIFT)
> +#define GCR_L2_LRU_WE_SHIFT    26
> +#define GCR_L2_LRU_WE_BITS     1
> +#define GCR_L2_TAG_WE_MASK     (1<<GCR_L2_TAG_WE_SHIFT)
> +#define GCR_L2_TAG_WE_SHIFT    25
> +#define GCR_L2_TAG_WE_BITS     1
> +#define GCR_L2_ECC_WE_MASK     (1<<GCR_L2_ECC_WE_SHIFT)
> +#define GCR_L2_ECC_WE_SHIFT    24
> +#define GCR_L2_ECC_WE_BITS     1
> +#define GCR_L2_BYPASS_MASK     (1<<GCR_L2_BYPASS_SHIFT)
> +#define GCR_L2_BYPASS_SHIFT    20
> +#define GCR_L2_BYPASS_BITS     1
> +#define GCR_L2_SS_MASK         0x0000F000
> +#define GCR_L2_SS_SHIFT                12
> +#define GCR_L2_SS_BITS         4
> +#define GCR_L2_SL_MASK         0x00000F00
> +#define GCR_L2_SL_SHIFT                8
> +#define GCR_L2_SL_BITS         4
> +#define GCR_L2_SA_MASK         0x000000FF
> +#define GCR_L2_SA_SHIFT                0
> +#define GCR_L2_SA_BITS         8
> +
> +#endif /* _CM3_H_ */
> diff --git a/libgloss/mips/include/mips/cpu.h
> b/libgloss/mips/include/mips/cpu.h
> new file mode 100644
> index 000000000..067e1a14c
> --- /dev/null
> +++ b/libgloss/mips/include/mips/cpu.h
> @@ -0,0 +1,356 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _CPU_H_
> +#define _CPU_H_
> +
> +#if !defined(__ASSEMBLER__)
> +#include <sys/types.h>
> +#endif
> +
> +#ifndef SR_IMASK
> +#if __mips == 64
> +#include <mips/m64c0.h>
> +#elif __mips == 32
> +#include <mips/m32c0.h>
> +#endif
> +#endif /* SR_IMASK */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#if !defined(__ASSEMBLER__)
> +/*
> + * Generic MIPS cache handling
> + *
> + *   primary: virtual index, physical tag, write back;
> + *   secondary: physical index, physical tag, write back;
> + *   pass correct virtual address to primary cache routines.
> + */
> +
> +#ifdef __mips16
> +# define _MIPS_CPU_NOMIPS16 __attribute__((nomips16))
> +#else
> +# define _MIPS_CPU_NOMIPS16
> +#endif
> +
> +extern int     mips_icache_size, mips_icache_linesize, mips_icache_ways;
> +extern int     mips_dcache_size, mips_dcache_linesize, mips_dcache_ways;
> +extern int     mips_scache_size, mips_scache_linesize, mips_scache_ways;
> +extern int     mips_tcache_size, mips_tcache_linesize, mips_tcache_ways;
> +
> +/* these are now the only standard interfaces to the caches */
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_size_cache (void);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_flush_cache (void);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_flush_dcache (void);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_flush_icache (void);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_sync_icache (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_clean_cache (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_clean_dcache (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_clean_dcache_nowrite (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_clean_icache (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_lock_dcache (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_lock_icache (vaddr_t, size_t);
> +_MIPS_CPU_NOMIPS16
> +extern void    mips_lock_scache (vaddr_t, size_t);
> +
> +/*
> + * Other common utilities for all CPUs
> + */
> +extern void    mips_wbflush (void);
> +extern void    mips_cycle (unsigned);
> +_MIPS_CPU_NOMIPS16
> +extern int     mips_tlb_size (void);
> +
> +/*
> + * Coprocessor 0 register manipulation
> + * Warning: all non-atomic in face of interrupts.
> + */
> +#if defined(_mips_mfc0)
> +
> +/* exchange (swap) VAL and cp0 register REG */
> +#define _mips_mxc0(reg, val) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _mips_mfc0 (reg); \
> +    _mips_mtc0 (reg, (val)); \
> +    __o; \
> +})
> +
> +/* bit clear non-zero bits from CLR in cp0 register REG */
> +#define _mips_bcc0(reg, clr) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _mips_mfc0 (reg); \
> +    _mips_mtc0 (reg, __o & ~(clr)); \
> +    __o; \
> +})
> +
> +/* bit set non-zero bits from SET in cp0 register REG */
> +#define _mips_bsc0(reg, set) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _mips_mfc0 (reg); \
> +    _mips_mtc0 (reg, __o | (set)); \
> +    __o; \
> +})
> +
> +/* bit clear nz bits in from CLR and set nz bits from SET in REG */
> +#define _mips_bcsc0(reg, clr, set) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _mips_mfc0 (reg); \
> +    _mips_mtc0 (reg, (__o & ~(clr)) | (set)); \
> +    __o; \
> +})
> +
> +/*
> + * Standard MIPS CP0 register access functions
> + */
> +
> +/* CP0 Status register (NOTE: not atomic operations) */
> +#define mips_getsr()           _mips_mfc0(C0_SR)
> +#define mips_setsr(v)          _mips_mtc0(C0_SR,v)
> +#define mips_xchsr(v)          _mips_mxc0(C0_SR,v)
> +#define mips_bicsr(clr)                _mips_bcc0(C0_SR,clr)
> +#define mips_bissr(set)                _mips_bsc0(C0_SR,set)
> +#define mips_bcssr(c,s)                _mips_bcsc0(C0_SR,c,s)
> +
> +/* CP0 Cause register (NOTE: not atomic operations) */
> +#define mips_getcr()           _mips_mfc0(C0_CR)
> +#define mips_setcr(v)          _mips_mtc0(C0_CR,v)
> +#define mips_xchcr(v)          _mips_mxc0(C0_CR,v)
> +#define mips_biccr(clr)                _mips_bcc0(C0_CR,clr)
> +#define mips_biscr(set)                _mips_bsc0(C0_CR,set)
> +#define mips_bcscr(c,s)                _mips_bcsc0(C0_CR,c,s)
> +
> +/* CP0 PrID register */
> +#define mips_getprid()         _mips_mfc0(C0_PRID)
> +
> +#ifdef C0_COUNT
> +/* CP0 Count register */
> +#define mips_getcount()                _mips_mfc0(C0_COUNT)
> +#define mips_setcount(v)       _mips_mtc0(C0_COUNT,v)
> +#define mips_xchcount(v)       _mips_mxc0(C0_COUNT,v)
> +#endif
> +
> +#ifdef C0_COMPARE
> +/* CP0 Compare register*/
> +#define mips_getcompare()      _mips_mfc0(C0_COMPARE)
> +#define mips_setcompare(v)     _mips_mtc0(C0_COMPARE,v)
> +#define mips_xchcompare(v)     _mips_mxc0(C0_COMPARE,v)
> +#endif
> +
> +#ifdef C0_CONFIG
> +/* CP0 Config register */
> +#define mips_getconfig()       _mips_mfc0(C0_CONFIG)
> +#define mips_setconfig(v)      _mips_mtc0(C0_CONFIG,v)
> +#define mips_xchconfig(v)      _mips_mxc0(C0_CONFIG,v)
> +#define mips_bicconfig(c)      _mips_bcc0(C0_CONFIG,c)
> +#define mips_bisconfig(s)      _mips_bsc0(C0_CONFIG,s)
> +#define mips_bcsconfig(c,s)    _mips_bcsc0(C0_CONFIG,c,s)
> +#endif
> +
> +#ifdef C0_ECC
> +/* CP0 ECC register */
> +#define mips_getecc()          _mips_mfc0(C0_ECC)
> +#define mips_setecc(x)         _mips_mtc0(C0_ECC, x)
> +#define mips_xchecc(x)         _mips_mxc0(C0_ECC, x)
> +#endif
> +
> +#ifdef C0_TAGLO
> +/* CP0 TagLo register */
> +#define mips_gettaglo()                _mips_mfc0(C0_TAGLO)
> +#define mips_settaglo(x)       _mips_mtc0(C0_TAGLO, x)
> +#define mips_xchtaglo(x)       _mips_mxc0(C0_TAGLO, x)
> +#endif
> +
> +#ifdef C0_TAGHI
> +/* CP0 TagHi register */
> +#define mips_gettaghi()                _mips_mfc0(C0_TAGHI)
> +#define mips_settaghi(x)       _mips_mtc0(C0_TAGHI, x)
> +#define mips_xchtaghi(x)       _mips_mxc0(C0_TAGHI, x)
> +#endif
> +
> +#ifdef C0_WATCHLO
> +/* CP0 WatchLo register */
> +#define mips_getwatchlo()      _mips_mfc0(C0_WATCHLO)
> +#define mips_setwatchlo(x)     _mips_mtc0(C0_WATCHLO, x)
> +#define mips_xchwatchlo(x)     _mips_mxc0(C0_WATCHLO, x)
> +#endif
> +
> +#ifdef C0_WATCHHI
> +/* CP0 WatchHi register */
> +#define mips_getwatchhi()      _mips_mfc0(C0_WATCHHI)
> +#define mips_setwatchhi(x)     _mips_mtc0(C0_WATCHHI, x)
> +#define mips_xchwatchhi(x)     _mips_mxc0(C0_WATCHHI, x)
> +#endif
> +
> +#endif /*_mips_mfc0*/
> +
> +/*
> + * Count-leading zeroes and ones.
> + * Simulate with a function call if this CPU hasn't defined a
> + * macro with a suitable asm.
> + */
> +#if !defined(mips_clz)
> +extern unsigned int _mips_clz(unsigned int);
> +#define        mips_clz(x)     _mips_clz(x)
> +#define        mips_clo(x)     _mips_clz(~(x))
> +#else
> +#define _mips_have_clz 1
> +#endif
> +
> +#if !defined(mips_dclz)
> +extern unsigned int _mips_dclz(unsigned long long);
> +#define        mips_dclz(x)    _mips_dclz(x)
> +#define        mips_dclo(x)    _mips_dclz(~(x))
> +#else
> +#define _mips_have_dclz 1
> +#endif
> +
> +/*
> + * Generic MIPS prefetch instruction for MIPS IV and
> + * above. CPU-specific include files must define
> + * prefetch "hint" codes.
> + */
> +#if __mips >= 4
> +#define _mips_pref(OP,LOC) \
> +do { \
> +    __asm__ ("pref %0,%1" : : "n" (OP), "m" (LOC));    \
> +} while (0)
> +#else
> +/* pref not available for MIPS16 */
> +#define _mips_pref(OP,LOC) (void)0
> +#endif
> +
> +#ifndef PREF_LOAD
> +#define PREF_LOAD              0
> +#endif
> +#ifndef PREF_STORE
> +#define PREF_STORE             0
> +#endif
> +#ifndef PREF_LOAD_STREAMED
> +#define PREF_LOAD_STREAMED     PREF_LOAD
> +#define PREF_STORE_STREAMED    PREF_STORE
> +#endif
> +#ifndef PREF_LOAD_RETAINED
> +#define PREF_LOAD_RETAINED     PREF_LOAD
> +#define PREF_STORE_RETAINED    PREF_STORE
> +#endif
> +
> +#define mips_prefetch __builtin_prefetch
> +
> +#ifdef PREF_WRITEBACK_INVAL
> +/* MIPS specific "nudge" (push to memory) operation */
> +#define mips_nudge(ADDR) \
> +    _mips_pref(PREF_WRITEBACK_INVAL, *(ADDR))
> +#else
> +#define mips_nudge(ADDR) (void)0
> +#endif
> +
> +#ifdef PREF_PREPAREFORSTORE
> +/* MIPS specific "prepare for store" operation */
> +/* XXX Warning - may zero whole cache line, ensure cache line alignment */
> +#define mips_prepare_for_store(ADDR) \
> +    _mips_pref(PREF_PREPAREFORSTORE, *(ADDR))
> +#else
> +#define mips_prepare_for_store(ADDR) (void)0
> +#endif
> +
> +/*
> + * Default versions of get/put for any MIPS CPU.
> + */
> +#ifndef mips_get_byte
> +#define mips_get_byte(addr, errp)      (*(volatile unsigned char *)(addr))
> +#define mips_get_half(addr, errp)      (*(volatile unsigned short
> *)(addr))
> +#define mips_get_word(addr, errp)      (*(volatile unsigned int *)(addr))
> +#define mips_get_dword(addr, errp)     (*(volatile unsigned long long
> *)(addr))
> +
> +#define mips_put_byte(addr, v) (*(volatile unsigned char *)(addr)=(v), 0)
> +#define mips_put_half(addr, v) (*(volatile unsigned short *)(addr)=(v), 0)
> +#define mips_put_word(addr, v) (*(volatile unsigned int *)(addr)=(v), 0)
> +#define mips_put_dword(addr, v)        (*(volatile unsigned long long
> *)(addr)=(v), 0)
> +#endif /* mips_get_byte */
> +
> +/* unoptimisable 2 instruction loop */
> +
> +#define mips_cycle(count)                              \
> +    do {                                               \
> +      unsigned int __count = (count);                  \
> +      __asm__ volatile ("%(nop; nop; 1: bnez %0,1b; subu %0,1%)"       \
> +       : "+d" (__count));                              \
> +    } while (0)
> +
> +/* default implementation of _mips_intdisable is a function */
> +
> +/* There are no microMIPS implementations that support MSA currently.  */
> +#if !defined(__mips_micromips)
> +# define MIPS_MSA_USABLE 1
> +#else
> +# define MIPS_MSA_USABLE 0
> +#endif
> +
> +#else /* ASSEMBLER */
> +
> +/* The correct way to use a hazard barrier return */
> +
> +/* JR.HB does not resolve hazards from its delay slot.  */
> +#define MIPS_JRHB(REG) \
> +  .set push;     \
> +  .set noreorder;  \
> +  jr.hb REG;     \
> +  nop;           \
> +  .set pop
> +
> +#define MIPS_NOMICROMIPS \
> +  .set nomicromips
> +
> +#define MIPS_NOMIPS16 \
> +  .set nomips16
> +
> +#endif /* !ASSEMBLER */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +#endif /*_CPU_H_*/
> diff --git a/libgloss/mips/include/mips/ctx.S
> b/libgloss/mips/include/mips/ctx.S
> new file mode 100644
> index 000000000..2257f0e33
> --- /dev/null
> +++ b/libgloss/mips/include/mips/ctx.S
> @@ -0,0 +1,149 @@
> +/*
> + * Copyright 2016-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#include <mips/regdef.h>
> +#include <mips/asm.h>
> +#include <mips/cpu.h>
> +#include <mips/hal.h>
> +
> +/* Save the hard context to a gp_ctx pointed to by k1.
> +   Leave the value of C0_STATUS in the return register.
> +   Leave the value of k1 unchanged.  */
> +
> +.macro _gpctx_save
> +       /* Save general registers.  */
> +       REG_S   $1, CTX_REG(1) (k1)
> +       REG_S   $2, CTX_REG(2) (k1)
> +       REG_S   $3, CTX_REG(3) (k1)
> +       REG_S   $4, CTX_REG(4) (k1)
> +       REG_S   $5, CTX_REG(5) (k1)
> +       REG_S   $6, CTX_REG(6) (k1)
> +       REG_S   $7, CTX_REG(7) (k1)
> +       REG_S   $8, CTX_REG(8) (k1)
> +       REG_S   $9, CTX_REG(9) (k1)
> +       REG_S   $10, CTX_REG(10) (k1)
> +       REG_S   $11, CTX_REG(11) (k1)
> +       REG_S   $12, CTX_REG(12) (k1)
> +       REG_S   $13, CTX_REG(13) (k1)
> +       REG_S   $14, CTX_REG(14) (k1)
> +       REG_S   $15, CTX_REG(15) (k1)
> +       REG_S   $16, CTX_REG(16) (k1)
> +       REG_S   $17, CTX_REG(17)(k1)
> +       REG_S   $18, CTX_REG(18)(k1)
> +       REG_S   $19, CTX_REG(19)(k1)
> +       REG_S   $20, CTX_REG(20)(k1)
> +       REG_S   $21, CTX_REG(21)(k1)
> +       REG_S   $22, CTX_REG(22)(k1)
> +       REG_S   $23, CTX_REG(23)(k1)
> +       REG_S   $24, CTX_REG(24)(k1)
> +       REG_S   $25, CTX_REG(25)(k1)
> +       REG_S   $26, CTX_REG(26)(k1)
> +       /* $27/k1 must be saved prior to using this macro.  */
> +       REG_S   $28, CTX_REG(28)(k1)
> +       REG_S   $29, CTX_REG(29)(k1)
> +       REG_S   $30, CTX_REG(30)(k1)
> +       REG_S   $31, CTX_REG(31)(k1)
> +       PTR_S   $0, CTX_LINK(k1)        /* Clear the link field.  */
> +
> +       /* Check ISA release and optionally restore HI/LO registers.  */
> +#if (__mips_isa_rev < 6)
> +       mfhi    $9
> +       REG_S   $9, CTX_HI0(k1)
> +       mflo    $10
> +       REG_S   $10, CTX_LO0(k1)
> +#endif
> +
> +       /* Save CP0 registers.  */
> +       PTR_MFC0 $31, C0_EPC
> +       REG_S   $31, CTX_EPC(k1)
> +       mfc0    va0, C0_STATUS
> +       sw      va0, CTX_STATUS(k1)
> +.endm
> +
> +/* Restores a gp_ctx pointed to by a0.  Leaves interrupts disabled and
> +   C0_EPC ready to eret.  */
> +
> +.macro _gpctx_load
> +
> +       /* Check ISA release and optionally restore HI/LO registers.  */
> +#if (__mips_isa_rev < 6)
> +       REG_L   $9, CTX_HI0(a0)
> +       REG_L   $10, CTX_LO0(a0)
> +       mthi    $9
> +       mtlo    $10
> +#endif
> +
> +       /* Restore the general registers.  */
> +       REG_L   $1, CTX_REG(1)(a0)
> +       REG_L   $2, CTX_REG(2)(a0)
> +       REG_L   $3, CTX_REG(3)(a0)
> +       /* Do not restore $4 until the end.  */
> +       REG_L   $5, CTX_REG(5)(a0)
> +       REG_L   $6, CTX_REG(6)(a0)
> +       REG_L   $7, CTX_REG(7)(a0)
> +       REG_L   $8, CTX_REG(8)(a0)
> +       REG_L   $9, CTX_REG(9)(a0)
> +       REG_L   $10, CTX_REG(10)(a0)
> +       REG_L   $11, CTX_REG(11)(a0)
> +       REG_L   $12, CTX_REG(12)(a0)
> +       REG_L   $13, CTX_REG(13)(a0)
> +       REG_L   $14, CTX_REG(14)(a0)
> +       REG_L   $15, CTX_REG(15)(a0)
> +       REG_L   $16, CTX_REG(16)(a0)
> +       REG_L   $17, CTX_REG(17)(a0)
> +       REG_L   $18, CTX_REG(18)(a0)
> +       REG_L   $19, CTX_REG(19)(a0)
> +       REG_L   $20, CTX_REG(20)(a0)
> +       REG_L   $21, CTX_REG(21)(a0)
> +       REG_L   $22, CTX_REG(22)(a0)
> +       REG_L   $23, CTX_REG(23)(a0)
> +       REG_L   $24, CTX_REG(24)(a0)
> +       REG_L   $25, CTX_REG(25)(a0)
> +
> +       /* Restore CP0 registers, kernel registers and stack with
> +          interrupts disabled.  */
> +       di
> +       lw      $27, CTX_STATUS(a0)
> +       REG_L   $26, CTX_EPC(a0)
> +       mtc0    $27, C0_STATUS
> +       PTR_MTC0 $26, C0_EPC
> +       ehb
> +
> +       REG_L   $26, CTX_REG(26)(a0)
> +       REG_L   $27, CTX_REG(27)(a0)
> +       REG_L   $28, CTX_REG(28)(a0)
> +       REG_L   $29, CTX_REG(29)(a0)
> +       REG_L   $30, CTX_REG(30)(a0)
> +       REG_L   $31, CTX_REG(31)(a0)
> +
> +       /* Finally restore a0/$4.  */
> +       REG_L   $4, CTX_REG(4)(a0)
> +
> +.endm
> diff --git a/libgloss/mips/include/mips/dsp.h
> b/libgloss/mips/include/mips/dsp.h
> new file mode 100644
> index 000000000..b10c98561
> --- /dev/null
> +++ b/libgloss/mips/include/mips/dsp.h
> @@ -0,0 +1,60 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_ASE_H_
> +#define _MIPS_ASE_H_
> +
> +/* 32-bit DSP Control register */
> +#define DSPCTL_POS_SHIFT       0
> +#define DSPCTL_POS_MASK                0x0000007f
> +#define DSPCTL_SCOUNT_SHIFT    7
> +#define DSPCTL_SCOUNT_MASK     0x00001f80
> +#define DSPCTL_C               0x00002000
> +#define DSPCTL_OU_SHIFT                16
> +#define DSPCTL_OU_MASK         0x00ff0000
> +#define  DSPCTL_OU_AC0OVF       0x00010000
> +#define  DSPCTL_OU_AC1OVF       0x00020000
> +#define  DSPCTL_OU_AC2OVF       0x00040000
> +#define  DSPCTL_OU_AC3OVF       0x00080000
> +#define  DSPCTL_OU_ALUOVF       0x00100000
> +#define  DSPCTL_OU_MULOVF       0x00200000
> +#define  DSPCTL_OU_SHFOVF       0x00400000
> +#define  DSPCTL_OU_EXTOVF       0x00800000
> +#define DSPCTL_CCOND_SHIFT     24
> +#define DSPCTL_CCOND_MASK      0x0f000000
> +
> +/* RDDSP/WRDSP instruction mask bits */
> +#define RWDSP_POS              0x01
> +#define RWDSP_SCOUNT           0x02
> +#define RWDSP_C                        0x04
> +#define RWDSP_OU               0x08
> +#define RWDSP_CCOND            0x10
> +
> +#endif /* _MIPS_DSP_H_ */
> diff --git a/libgloss/mips/include/mips/endian.h
> b/libgloss/mips/include/mips/endian.h
> new file mode 100644
> index 000000000..057af7e19
> --- /dev/null
> +++ b/libgloss/mips/include/mips/endian.h
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_ENDIAN_H_
> +#define _MIPS_ENDIAN_H_
> +
> +#ifndef __ASSEMBLER__
> +#include <stdint.h>    /* get compiler types */
> +#include <sys/types.h>
> +#endif
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef BYTE_ORDER
> +/*
> + * Definitions for byte order,
> + * according to byte significance from low address to high.
> + */
> +#define LITTLE_ENDIAN   1234    /* least-significant byte first (vax) */
> +#define BIG_ENDIAN      4321    /* most-significant byte first (IBM, net)
> */
> +
> +#if defined(__MIPSEB__) || defined(MIPSEB)
> +#define BYTE_ORDER      BIG_ENDIAN
> +#elif defined(__MIPSEL__) || defined(MIPSEL)
> +#define BYTE_ORDER      LITTLE_ENDIAN
> +#else
> +#error BYTE_ORDER
> +#endif
> +
> +#ifndef __ASSEMBLER__
> +
> +#if __mips_isa_rev >= 2 && ! __mips16
> +
> +/* MIPS32r2 & MIPS64r2 can use the wsbh and rotate instructions, define
> +   MD_SWAP so that <sys/endian.h> will use them. */
> +
> +#define MD_SWAP
> +
> +#define __swap16md(x) __extension__({                                  \
> +    uint16_t __swap16md_x = (x);                                       \
> +    uint16_t __swap16md_v;                                             \
> +    __asm__ ("wsbh %0,%1"                                              \
> +            : "=d" (__swap16md_v)                                      \
> +            : "d" (__swap16md_x));                                     \
> +    __swap16md_v;                                                      \
> +})
> +
> +#define __swap32md(x) __extension__({                                  \
> +    uint32_t __swap32md_x = (x);                                       \
> +    uint32_t __swap32md_v;                                             \
> +    __asm__ ("wsbh %0,%1; rotr %0,16"                                  \
> +            : "=d" (__swap32md_v)                                      \
> +            : "d" (__swap32md_x));                                     \
> +    __swap32md_v;                                                      \
> +})
> +
> +#endif
> +#endif /* __ASSEMBLER__ */
> +#endif /* BYTE_ORDER */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#include <machine/endian.h>
> +
> +#endif /*_MIPS_ENDIAN_H_*/
> diff --git a/libgloss/mips/include/mips/fgregdef.h
> b/libgloss/mips/include/mips/fgregdef.h
> new file mode 100644
> index 000000000..b36ea159f
> --- /dev/null
> +++ b/libgloss/mips/include/mips/fgregdef.h
> @@ -0,0 +1,128 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_FPREGDEF_H_
> +#define _MIPS_FPREGDEF_H_
> +
> +/* result registers */
> +#define fv0    $f0
> +#define fv1    $f2
> +
> +/* argument registers */
> +#define fa0    $f12
> +#if  (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
> +     || (defined _ABI64 && _MIPS_SIM == _ABI64)
> +#define fa1    $f13
> +#else
> +#define fa1    $f14
> +#endif
> +
> +#if __mips_fpr == 64
> +
> +/* 64-bit f.p. registers (-mips3 and above) */
> +
> +/* temporary registers */
> +#define ft0    $f4
> +#define ft1    $f5
> +#define ft2    $f6
> +#define ft3    $f7
> +#define ft4    $f8
> +#define ft5    $f9
> +#define ft6    $f10
> +#define ft7    $f11
> +#define ft8    $f16
> +#define ft9    $f17
> +#define ft10   $f18
> +#define ft11   $f19
> +
> +# if  (defined _ABIN32 && _MIPS_SIM == _ABIN32) \
> +      || (defined _ABI64 && _MIPS_SIM == _ABI64)
> +/* saved registers */
> +#  define      fs0     $f20
> +#  define      fs1     $f21
> +#  define      fs2     $f22
> +#  define      fs3     $f23
> +#  define      fs4     $f24
> +#  define      fs5     $f35
> +#  define      fs6     $f26
> +#  define      fs7     $f27
> +#  define      fs8     $f28
> +#  define      fs9     $f29
> +#  define      fs10    $f30
> +#  define      fs11    $f31
> +# else
> +/* o32 FP64 */
> +#  define      ft12    $f21
> +#  define      ft13    $f23
> +#  define      ft14    $f35
> +#  define      ft15    $f27
> +#  define      ft16    $f29
> +#  define      ft17    $f31
> +#  define      fs0     $f20
> +#  define      fs1     $f22
> +#  define      fs2     $f24
> +#  define      fs3     $f26
> +#  define      fs4     $f28
> +#  define      fs5     $f30
> +# endif
> +
> +#else
> +
> +/* 32-bit f.p. registers */
> +
> +/* temporary registers */
> +#define ft0    $f4
> +#define ft1    $f5
> +#define ft2    $f6
> +#define ft3    $f7
> +#define ft4    $f8
> +#define ft5    $f9
> +#define ft6    $f10
> +#define ft7    $f11
> +#define ft8    $f12
> +#define ft9    $f13
> +#define ft10   $f14
> +#define ft11   $f15
> +#define ft12   $f16
> +#define ft13   $f17
> +#define ft14   $f18
> +#define ft15   $f19
> +
> +/* saved registers */
> +#define        fs0     $f20
> +#define        fs1     $f22
> +#define        fs2     $f24
> +#define        fs3     $f26
> +#define        fs4     $f28
> +#define        fs5     $f30
> +
> +#endif
> +
> +#endif /*_MIPS_FPREGDEF_H_*/
> diff --git a/libgloss/mips/include/mips/fpa.h
> b/libgloss/mips/include/mips/fpa.h
> new file mode 100644
> index 000000000..93dde7184
> --- /dev/null
> +++ b/libgloss/mips/include/mips/fpa.h
> @@ -0,0 +1,33 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#if __mips == 32 || __mips == 64
> +#include <mips/m32c1.h>
> +#endif
> diff --git a/libgloss/mips/include/mips/hal.h
> b/libgloss/mips/include/mips/hal.h
> new file mode 100644
> index 000000000..b161dfb89
> --- /dev/null
> +++ b/libgloss/mips/include/mips/hal.h
> @@ -0,0 +1,452 @@
> +/*
> + * Copyright 2014-2018, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _HAL_H
> +#define _HAL_H
> +
> +#include <mips/asm.h>
> +#include <mips/m32c0.h>
> +
> +#if _MIPS_SIM == _ABIO32
> +#define UHI_ABI 0
> +#elif _MIPS_SIM == _ABIN32
> +#define UHI_ABI 1
> +#elif _MIPS_SIM == _ABI64
> +#define UHI_ABI 2
> +#else
> +#error "UHI context structure is not defined for current ABI"
> +#endif
> +
> +#define CTX_REG(REGNO) ((SZREG)*((REGNO)-1))
> +
> +#define CTX_AT         (CTX_REG(1))
> +#define CTX_V0         (CTX_REG(2))
> +#define CTX_V1         (CTX_REG(3))
> +#define CTX_A0         (CTX_REG(4))
> +#define CTX_A1         (CTX_REG(5))
> +#define CTX_A2         (CTX_REG(6))
> +#define CTX_A3         (CTX_REG(7))
> +#if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI
> +# define CTX_A4                (CTX_REG(8))
> +# define CTX_A5                (CTX_REG(9))
> +# define CTX_A6                (CTX_REG(10))
> +# define CTX_A7                (CTX_REG(11))
> +# define CTX_T0                (CTX_REG(12))
> +# define CTX_T1                (CTX_REG(13))
> +# define CTX_T2                (CTX_REG(14))
> +# define CTX_T3                (CTX_REG(15))
> +#else
> +# define CTX_T0                (CTX_REG(8))
> +# define CTX_T1                (CTX_REG(9))
> +# define CTX_T2                (CTX_REG(10))
> +# define CTX_T3                (CTX_REG(11))
> +# define CTX_T4                (CTX_REG(12))
> +# define CTX_T5                (CTX_REG(13))
> +# define CTX_T6                (CTX_REG(14))
> +# define CTX_T7                (CTX_REG(15))
> +#endif
> +#define CTX_S0         (CTX_REG(16))
> +#define CTX_S1         (CTX_REG(17))
> +#define CTX_S2         (CTX_REG(18))
> +#define CTX_S3         (CTX_REG(19))
> +#define CTX_S4         (CTX_REG(20))
> +#define CTX_S5         (CTX_REG(21))
> +#define CTX_S6         (CTX_REG(22))
> +#define CTX_S7         (CTX_REG(23))
> +#define CTX_T8         (CTX_REG(24))
> +#define CTX_T9         (CTX_REG(25))
> +#define CTX_K0         (CTX_REG(26))
> +#define CTX_K1         (CTX_REG(27))
> +#define CTX_GP         (CTX_REG(28))
> +#define CTX_SP         (CTX_REG(29))
> +#define CTX_FP         (CTX_REG(30))
> +#define CTX_RA         (CTX_REG(31))
> +#define CTX_EPC                (CTX_REG(32))
> +#define CTX_BADVADDR   (CTX_REG(33))
> +#define CTX_HI0                (CTX_REG(34))
> +#define CTX_LO0                (CTX_REG(35))
> +#define CTX_HILO_SIZE  (2*SZREG)
> +#define CTX_LINK       (CTX_REG(34)+CTX_HILO_SIZE)
> +#define CTX_STATUS     ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR)
> +#define CTX_CAUSE      ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+4)
> +#define CTX_BADINSTR   ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+8)
> +#define CTX_BADPINSTR  ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+12)
> +#define CTX_SIZE       ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+16)
> +
> +#define DSPCTX_DSPC ((SZREG)*2)
> +#define DSPCTX_HI1  ((SZREG)*3)
> +#define DSPCTX_HI2  ((SZREG)*4)
> +#define DSPCTX_HI3  ((SZREG)*5)
> +#define DSPCTX_LO1  ((SZREG)*6)
> +#define DSPCTX_LO2  ((SZREG)*7)
> +#define DSPCTX_LO3  ((SZREG)*8)
> +#define DSPCTX_SIZE ((SZREG)*9)
> +
> +#define FP32CTX_CSR    ((SZREG)*2)
> +#define FP64CTX_CSR    ((SZREG)*2)
> +#define MSACTX_FCSR    ((SZREG)*2)
> +#define MSACTX_MSACSR  ((SZREG)*3)
> +
> +#define MSACTX_0       ((SZREG)*4)
> +#define MSACTX_1       (MSACTX_0 + (1 * 16))
> +#define MSACTX_2       (MSACTX_0 + (2 * 16))
> +#define MSACTX_3       (MSACTX_0 + (3 * 16))
> +#define MSACTX_4       (MSACTX_0 + (4 * 16))
> +#define MSACTX_5       (MSACTX_0 + (5 * 16))
> +#define MSACTX_6       (MSACTX_0 + (6 * 16))
> +#define MSACTX_7       (MSACTX_0 + (7 * 16))
> +#define MSACTX_8       (MSACTX_0 + (8 * 16))
> +#define MSACTX_9       (MSACTX_0 + (9 * 16))
> +#define MSACTX_10      (MSACTX_0 + (10 * 16))
> +#define MSACTX_11      (MSACTX_0 + (11 * 16))
> +#define MSACTX_12      (MSACTX_0 + (12 * 16))
> +#define MSACTX_13      (MSACTX_0 + (13 * 16))
> +#define MSACTX_14      (MSACTX_0 + (14 * 16))
> +#define MSACTX_15      (MSACTX_0 + (15 * 16))
> +#define MSACTX_16      (MSACTX_0 + (16 * 16))
> +#define MSACTX_17      (MSACTX_0 + (17 * 16))
> +#define MSACTX_18      (MSACTX_0 + (18 * 16))
> +#define MSACTX_19      (MSACTX_0 + (19 * 16))
> +#define MSACTX_20      (MSACTX_0 + (20 * 16))
> +#define MSACTX_21      (MSACTX_0 + (21 * 16))
> +#define MSACTX_22      (MSACTX_0 + (22 * 16))
> +#define MSACTX_23      (MSACTX_0 + (23 * 16))
> +#define MSACTX_24      (MSACTX_0 + (24 * 16))
> +#define MSACTX_25      (MSACTX_0 + (25 * 16))
> +#define MSACTX_26      (MSACTX_0 + (26 * 16))
> +#define MSACTX_27      (MSACTX_0 + (27 * 16))
> +#define MSACTX_28      (MSACTX_0 + (28 * 16))
> +#define MSACTX_29      (MSACTX_0 + (29 * 16))
> +#define MSACTX_30      (MSACTX_0 + (30 * 16))
> +#define MSACTX_31      (MSACTX_0 + (31 * 16))
> +#define MSACTX_SIZE    (MSACTX_0 + (32 * 16))
> +
> +#define FP32CTX_0      ((SZREG)*4)
> +#define FP32CTX_2      (FP32CTX_0 + (1 * 8))
> +#define FP32CTX_4      (FP32CTX_0 + (2 * 8))
> +#define FP32CTX_6      (FP32CTX_0 + (3 * 8))
> +#define FP32CTX_8      (FP32CTX_0 + (4 * 8))
> +#define FP32CTX_10     (FP32CTX_0 + (5 * 8))
> +#define FP32CTX_12     (FP32CTX_0 + (6 * 8))
> +#define FP32CTX_14     (FP32CTX_0 + (7 * 8))
> +#define FP32CTX_16     (FP32CTX_0 + (8 * 8))
> +#define FP32CTX_18     (FP32CTX_0 + (9 * 8))
> +#define FP32CTX_20     (FP32CTX_0 + (10 * 8))
> +#define FP32CTX_22     (FP32CTX_0 + (11 * 8))
> +#define FP32CTX_24     (FP32CTX_0 + (12 * 8))
> +#define FP32CTX_26     (FP32CTX_0 + (13 * 8))
> +#define FP32CTX_28     (FP32CTX_0 + (14 * 8))
> +#define FP32CTX_30     (FP32CTX_0 + (15 * 8))
> +#define FP32CTX_SIZE   (FP32CTX_30 + (17 * 8))
> +
> +#define FP64CTX_0      ((SZREG)*4)
> +#define FP64CTX_2      (FP64CTX_0 + (1 * 8))
> +#define FP64CTX_4      (FP64CTX_0 + (2 * 8))
> +#define FP64CTX_6      (FP64CTX_0 + (3 * 8))
> +#define FP64CTX_8      (FP64CTX_0 + (4 * 8))
> +#define FP64CTX_10     (FP64CTX_0 + (5 * 8))
> +#define FP64CTX_12     (FP64CTX_0 + (6 * 8))
> +#define FP64CTX_14     (FP64CTX_0 + (7 * 8))
> +#define FP64CTX_16     (FP64CTX_0 + (8 * 8))
> +#define FP64CTX_18     (FP64CTX_0 + (9 * 8))
> +#define FP64CTX_20     (FP64CTX_0 + (10 * 8))
> +#define FP64CTX_22     (FP64CTX_0 + (11 * 8))
> +#define FP64CTX_24     (FP64CTX_0 + (12 * 8))
> +#define FP64CTX_26     (FP64CTX_0 + (13 * 8))
> +#define FP64CTX_28     (FP64CTX_0 + (14 * 8))
> +#define FP64CTX_30     (FP64CTX_0 + (15 * 8))
> +#define FP64CTX_1      (FP64CTX_30 + (1 * 8))
> +#define FP64CTX_3      (FP64CTX_30 + (2 * 8))
> +#define FP64CTX_5      (FP64CTX_30 + (3 * 8))
> +#define FP64CTX_7      (FP64CTX_30 + (4 * 8))
> +#define FP64CTX_9      (FP64CTX_30 + (5 * 8))
> +#define FP64CTX_11     (FP64CTX_30 + (6 * 8))
> +#define FP64CTX_13     (FP64CTX_30 + (7 * 8))
> +#define FP64CTX_15     (FP64CTX_30 + (8 * 8))
> +#define FP64CTX_17     (FP64CTX_30 + (9 * 8))
> +#define FP64CTX_19     (FP64CTX_30 + (10 * 8))
> +#define FP64CTX_21     (FP64CTX_30 + (11 * 8))
> +#define FP64CTX_23     (FP64CTX_30 + (12 * 8))
> +#define FP64CTX_25     (FP64CTX_30 + (13 * 8))
> +#define FP64CTX_27     (FP64CTX_30 + (14 * 8))
> +#define FP64CTX_29     (FP64CTX_30 + (15 * 8))
> +#define FP64CTX_31     (FP64CTX_30 + (16 * 8))
> +#define FP64CTX_SIZE   (FP64CTX_31 + (17 * 8))
> +
> +#define FPCTX_SIZE()   (mips_getsr() & SR_FR ? FP64CTX_SIZE :
> FP32CTX_SIZE)
> +
> +#define XPACTX_BADVADDR        ((SZREG)*2)
> +
> +#define LINKCTX_TYPE_MSA        0x004D5341
> +#define LINKCTX_TYPE_FP32       0x46503332
> +#define LINKCTX_TYPE_FP64       0x46503634
> +#define LINKCTX_TYPE_FMSA       0x463D5341
> +#define LINKCTX_TYPE_DSP        0x00445350
> +#define LINKCTX_TYPE_STKSWP     0x53574150
> +#define LINKCTX_TYPE_XPA       0x00585041
> +
> +#define LINKCTX_ID      ((SZREG)*0)
> +#define LINKCTX_NEXT    ((SZREG)*1)
> +
> +#define LINKCTX_TYPE(X) (((struct linkctx *)(X))->id)
> +
> +#define SWAPCTX_OLDSP   ((SZREG)*2)
> +#define SWAPCTX_SIZE    ((SZREG)*3)
> +
> +#ifndef __ASSEMBLER__
> +
> +#include <stdint.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +struct linkctx;
> +
> +#define C_CTX_REGNO(REGNO) ((REGNO) - 1)
> +
> +struct gpctx
> +{
> +  union
> +  {
> +    struct
> +    {
> +      reg_t at;
> +      reg_t v[2];
> +# if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI
> +      reg_t a[8];
> +      reg_t t[4];
> +# else
> +      reg_t a[4];
> +      reg_t t[8];
> +# endif
> +      reg_t s[8];
> +      reg_t t2[2];
> +      reg_t k[2];
> +      reg_t gp;
> +      reg_t sp;
> +      reg_t fp;
> +      reg_t ra;
> +    };
> +    reg_t r[31];
> +  };
> +
> +  reg_t epc;
> +  reg_t badvaddr;
> +  reg_t hi;
> +  reg_t lo;
> +  /* This field is for future extension */
> +  struct linkctx *link;
> +  /* Status at the point of the exception.  This may not be restored
> +     on return from exception if running under an RTOS */
> +  uint32_t status;
> +  /* These fields should be considered read-only */
> +  uint32_t cause;
> +  uint32_t badinstr;
> +  uint32_t badpinstr;
> +};
> +
> +struct linkctx
> +{
> +  reg_t id;
> +  struct linkctx *next;
> +};
> +
> +struct swapctx
> +{
> +  struct linkctx link;
> +  reg_t oldsp;
> +};
> +
> +static inline void
> +_linkctx_append (struct gpctx *gp, struct linkctx *nu)
> +{
> +  struct linkctx **ctx = (struct linkctx **)&gp->link;
> +  while (*ctx)
> +    ctx = &(*ctx)->next;
> +  *ctx = nu;
> +}
> +
> +struct dspctx
> +{
> +  struct linkctx link;
> +  reg_t dspc;
> +  reg_t hi[3];
> +  reg_t lo[3];
> +};
> +
> +struct fpctx
> +{
> +  struct linkctx link;
> +  reg_t fcsr;
> +  reg_t reserved;
> +};
> +
> +typedef char _msareg[16] __attribute__ ((aligned(16)));
> +
> +struct msactx
> +{
> +  struct linkctx link;
> +  reg_t fcsr;
> +  reg_t msacsr;
> +  union
> +    {
> +      _msareg w[32];
> +      double d[64];
> +      float s[128];
> +    };
> +};
> +
> +#define MSAMSACTX_D(CTX, N) (CTX)->w[(N)]
> +#define MSACTX_DBL(CTX, N) (CTX)->d[(N) << 1]
> +#ifdef __MIPSEL__
> +#define MSACTX_SGL(CTX, N) (CTX)->s[(N) << 2]
> +#else
> +#define MSACTX_SGL(CTX, N) (CTX)->s[((N) << 2) | 1]
> +#endif
> +
> +struct fp32ctx
> +{
> +  struct fpctx fp;
> +  union
> +    {
> +      double d[16];    /* even doubles */
> +      float s[32];     /* even singles, padded */
> +    };
> +};
> +
> +#define FP32CTX_DBL(CTX, N) (CTX)->d[(N)]
> +#ifdef __MIPSEL__
> +#define FP32CTX_SGL(CTX, N) (CTX)->s[(N)]
> +#else
> +#define FP32CTX_SGL(CTX, N) (CTX)->s[(N) ^ 1]
> +#endif
> +
> +struct fp64ctx
> +{
> +  struct fpctx fp;
> +  union
> +    {
> +      double d[32];    /* even doubles, followed by odd doubles */
> +      float s[64];     /* even singles, followed by odd singles, padded */
> +    };
> +};
> +
> +#define FP64CTX_DBL(CTX, N) (CTX)->d[((N) >> 1) + (((N) & 1) << 4)]
> +#ifdef __MIPSEL__
> +#define FP64CTX_SGL(CTX, N) (CTX)->s[((N) & ~1) + (((N) & 1) << 5)]
> +#else
> +#define FP64CTX_SGL(CTX, N) (CTX)->s[((N) | 1) + (((N) & 1) << 5)]
> +#endif
> +
> +struct xpactx
> +{
> +  struct linkctx link;
> +  reg64_t badvaddr;
> +};
> +
> +#ifdef __mips16
> +# define _MIPS_HAL_NOMIPS16 __attribute__((nomips16))
> +#else
> +# define _MIPS_HAL_NOMIPS16
> +#endif
> +
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _dspctx_save (struct dspctx *ptr);
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _dspctx_load (struct dspctx *ptr);
> +
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _xpa_save (struct xpactx *ptr);
> +
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _fpctx_save (struct fpctx *ptr);
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _fpctx_load (struct fpctx *ptr);
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _msactx_save (struct msactx *ptr);
> +extern reg_t _MIPS_HAL_NOMIPS16
> +  _msactx_load (struct msactx *ptr);
> +
> +/* Fall back exception handlers:
> +   _mips_handle_exception - May be implemented by a user but is aliased
> +                           to __exception_handle by default.
> +   __exception_handle    - Toolchain provided fallback handler.
> +*/
> +extern void _MIPS_HAL_NOMIPS16
> +  _mips_handle_exception (struct gpctx *ctx, int exception);
> +extern void _MIPS_HAL_NOMIPS16
> +  __exception_handle (struct gpctx *ctx, int exception);
> +
> +/* Obtain the largest available region of RAM */
> +extern void _MIPS_HAL_NOMIPS16
> +  _get_ram_range (void **ram_base, void **ram_extent);
> +
> +/* Invoke a UHI operation via SDBBP using the provided context */
> +extern int _MIPS_HAL_NOMIPS16
> +  __uhi_indirect (struct gpctx *);
> +
> +/* Report an unhandled exception */
> +extern int32_t _MIPS_HAL_NOMIPS16
> +  __uhi_exception (struct gpctx *, int32_t);
> +
> +/* Print a message to a logger.  Minimal formatting support for one
> +   integer argument.  */
> +extern int32_t _MIPS_HAL_NOMIPS16
> +  __plog (int8_t *, int32_t);
> +
> +/* Boot context support functions */
> +extern int _MIPS_HAL_NOMIPS16
> +  __get_startup_BEV (void) __attribute__((weak));
> +extern int _MIPS_HAL_NOMIPS16
> +  __chain_uhi_excpt (struct gpctx *) __attribute__((weak));
> +
> +/* Emergency exit, use it when unrecoverable errors occur */
> +extern int _MIPS_HAL_NOMIPS16
> +  __exit (int);
> +
> +/* UHI assert support.  This function can return.  */
> +extern void _MIPS_HAL_NOMIPS16
> +  __uhi_assert (const char *, const char *, int32_t);
> +
> +#ifdef NDEBUG           /* required by ANSI standard */
> +# define uhi_assert(__e) ((void)0)
> +#else
> +# define uhi_assert(__e) ((__e) ? (void)0 : \
> +                          __uhi_assert (#__e, __FILE__, __LINE__))
> +#endif
> +
> +#endif
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif // _HAL_H
> diff --git a/libgloss/mips/include/mips/intctrl.h
> b/libgloss/mips/include/mips/intctrl.h
> new file mode 100644
> index 000000000..7e6c00097
> --- /dev/null
> +++ b/libgloss/mips/include/mips/intctrl.h
> @@ -0,0 +1,71 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <mips/hal.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +/*
> + * Use the macros themselves for idempotency to ease replacement at the OS
> + * level.
> + */
> +#ifndef _mips_intpatch
> +/*
> + * Install a handler into the template vector code by patching the address
> + * calculation instructions.  The INDEX is the interrupt number with SW0
> + * being index 0 and HW5 being index 7, this also applies to EIC vectors
> + * where the INDEX represents the vector number.  K1_TO_KSCRATCH1 should
> be
> + * set if an instruction should be injected to move K1 to KSCRATCH1 before
> + * clobbering it.
> + */
> +_MIPS_HAL_NOMIPS16
> +void _mips_intpatch (const reg_t index, const uintptr_t handler,
> +                    bool k1_to_kscratch1);
> +#endif /* _mips_intpatch */
> +
> +#ifndef _mips_intmask
> +/*
> + * Enable or disable an interrupt at INDEX where INDEX has the same
> meaning
> + * as in _mips_intpatch.  Returns nonzero if the interrupt was already
> + * enabled.
> + */
> +_MIPS_HAL_NOMIPS16
> +reg_t _mips_intmask (const reg_t index, const reg_t enable);
> +#endif /* _mips_intmask */
> +
> +#ifndef _mips_intack
> +/*
> + * Acknowledge (clear) an interrupt at INDEX where INDEX has the same
> meaning
> + * as in _mips_intpatch.  Returns nonzero if the interrupt needed
> + * acknowledging.
> + */
> +_MIPS_HAL_NOMIPS16
> +reg_t _mips_intack (const reg_t index);
> +#endif /* _mips_intack */
> diff --git a/libgloss/mips/include/mips/m32c0.h
> b/libgloss/mips/include/mips/m32c0.h
> new file mode 100644
> index 000000000..67c2c37bd
> --- /dev/null
> +++ b/libgloss/mips/include/mips/m32c0.h
> @@ -0,0 +1,1607 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _M32C0_H_
> +#define _M32C0_H_
> +
> +#ifndef _M64C0_H_
> +/* MIPS32-specific MMU interface */
> +#include <mips/m32tlb.h>
> +#endif
> +/*
> + * MIPS32 Exception Codes
> + */
> +#define EXC_INTR       0       /* interrupt */
> +#define EXC_MOD                1       /* tlb modification */
> +#define EXC_TLBL       2       /* tlb miss (load/i-fetch) */
> +#define EXC_TLBS       3       /* tlb miss (store) */
> +#define EXC_ADEL       4       /* address error (load/i-fetch) */
> +#define EXC_ADES       5       /* address error (store) */
> +#define EXC_IBE                6       /* bus error (i-fetch) */
> +#define EXC_DBE                7       /* data bus error (load/store) */
> +#define EXC_SYS                8       /* system call */
> +#define EXC_BP         9       /* breakpoint */
> +#define EXC_RI         10      /* reserved instruction */
> +#define EXC_CPU                11      /* coprocessor unusable */
> +#define EXC_OVF                12      /* integer overflow */
> +#define EXC_TRAP       13      /* trap exception */
> +#define EXC_MSAFPE     14      /* MSA floating point exception */
> +#define EXC_FPE                15      /* floating point exception */
> +#define EXC_IS1                16      /* implementation-specific 1 */
> +#define EXC_IS2                17      /* implementation-specific 2 */
> +#define EXC_C2E                18      /* coprocessor 2 exception */
> +#define EXC_TLBRI      19      /* TLB read inhibit */
> +#define EXC_TLBXI      20      /* TLB execute inhibit */
> +#define EXC_MSAU       21      /* MSA unusable exception */
> +#define EXC_MDMX       22      /* mdmx unusable */
> +#define EXC_WATCH      23      /* watchpoint */
> +#define EXC_MCHECK     24      /* machine check */
> +#define EXC_THREAD     25      /* thread */
> +#define EXC_DSPU       26      /* dsp unusable */
> +#define EXC_RES27      27
> +#define EXC_RES28      28
> +#define EXC_RES29      29
> +#define EXC_RES30      30
> +#define EXC_RES31      31
> +
> +
> +/*
> + * MIPS32 Cause Register (CP0 Register 13, Select 0)
> + */
> +#define CR_BD          0x80000000      /* branch delay */
> +#define  CR_BD_SHIFT           31
> +#define CR_TI          0x40000000      /* timer interrupt (r2) */
> +#define  CR_TI_SHIFT           30
> +#define CR_CEMASK      0x30000000      /* coprocessor used */
> +#define  CR_CESHIFT            28
> +#define  CR_CE_SHIFT           28
> +#define  CR_CE_BITS             2
> +#define CR_DC          0x08000000      /* disable count (r2) */
> +#define  CR_DC_SHIFT           27
> +#define CR_PCI         0x04000000      /* performance counter i/u (r2) */
> +#define  CR_PCI_SHIFT          26
> +#define CR_IV          0x00800000      /* use special i/u vec */
> +#define  CR_IV_SHIFT           23
> +#define CR_WP          0x00400000      /* deferred watchpoint */
> +#define  CR_WP_SHIFT           22
> +#define CR_FDCI                0x00200000      /* fast debug channned i/u
> (r2) */
> +#define  CR_FDCI_SHIFT         21
> +
> +#define CR_IMASK       0x0000ff00      /* interrupt pending mask */
> +#define CR_IP_MASK     0x0000ff00
> +#define  CR_IP_SHIFT            8
> +#define  CR_IP_BITS             8
> +#define CR_RIPL                0x0000fc00
> +#define  CR_RIPL_SHIFT         10
> +#define  CR_RIPL_BITS           6
> +
> +/* interrupt pending bits */
> +#define CR_HINT5       0x00008000      /* h/w interrupt 5 */
> +#define CR_HINT4       0x00004000      /* h/w interrupt 4 */
> +#define CR_HINT3       0x00002000      /* h/w interrupt 3 */
> +#define CR_HINT2       0x00001000      /* h/w interrupt 2 */
> +#define CR_HINT1       0x00000800      /* h/w interrupt 1 */
> +#define CR_HINT0       0x00000400      /* h/w interrupt 0 */
> +#define CR_SINT1       0x00000200      /* s/w interrupt 1 */
> +#define CR_SINT0       0x00000100      /* s/w interrupt 0 */
> +
> +/* alternative interrupt pending bit naming */
> +#define CR_IP7         0x00008000
> +#define CR_IP6         0x00004000
> +#define CR_IP5         0x00002000
> +#define CR_IP4         0x00001000
> +#define CR_IP3         0x00000800
> +#define CR_IP2         0x00000400
> +#define CR_IP1         0x00000200
> +#define CR_IP0         0x00000100
> +
> +#define CR_XMASK       0x0000007c      /* exception code mask */
> +#define CR_X_MASK      0x0000007c
> +#define  CR_X_SHIFT             2
> +#define  CR_X_BITS              5
> +#define CR_XCPT(x)     ((x)<<2)
> +
> +/*
> + * MIPS32 Status Register  (CP0 Register 12, Select 0)
> + */
> +#define SR_CU3         0x80000000      /* coprocessor 3 enable */
> +#define  SR_CU3_SHIFT          31
> +#define SR_CU2         0x40000000      /* coprocessor 2 enable */
> +#define  SR_CU2_SHIFT          30
> +#define SR_CU1         0x20000000      /* coprocessor 1 enable */
> +#define  SR_CU1_SHIFT          29
> +#define SR_CU0         0x10000000      /* coprocessor 0 enable */
> +
> +#define SR_RP          0x08000000      /* reduce power */
> +#define  SR_RP_SHIFT           27
> +#define SR_FR          0x04000000      /* 64-bit fpu registers */
> +#define  SR_FR_SHIFT           26
> +#define SR_RE          0x02000000      /* reverse endian (user mode) */
> +#define  SR_RE_SHIFT           25
> +#define SR_MX          0x01000000      /* enable MDMX/DSP ASE */
> +#define  SR_MX_SHIFT           24
> +#define SR_PX          0x00800000      /* user 64-bit reg / 32-bit addr */
> +#define  SR_PX_SHIFT           23
> +#define SR_BEV         0x00400000      /* boot exception vectors */
> +#define  SR_BEV_SHIFT          22
> +#define SR_TS          0x00200000      /* TLB shutdown */
> +#define  SR_TS_SHIFT           21
> +#define SR_SR          0x00100000      /* soft reset occurred */
> +#define SR_PE          0x00100000      /* soft reset (clear parity error)
> */
> +#define  SR_SR_SHIFT           20
> +#define SR_NMI         0x00080000      /* NMI occurred */
> +#define  SR_NMI_SHIFT          19
> +#define SR_MCU         0x00040000      /* MCU ASE implemented */
> +#define  SR_MCU_SHIFT          18
> +
> +#define SR_IPL_MASK    0x0000fc00
> +#define  SR_IPL_SHIFT          10
> +#define  SR_IPL_BITS            6
> +#define SR_IMASK       0x0000ff00
> +
> +/* interrupt mask bits */
> +#define SR_HINT5       0x00008000      /* enable h/w interrupt 6 */
> +#define SR_HINT4       0x00004000      /* enable h/w interrupt 5 */
> +#define SR_HINT3       0x00002000      /* enable h/w interrupt 4 */
> +#define SR_HINT2       0x00001000      /* enable h/w interrupt 3 */
> +#define SR_HINT1       0x00000800      /* enable h/w interrupt 2 */
> +#define SR_HINT0       0x00000400      /* enable h/w interrupt 1 */
> +#define SR_SINT1       0x00000200      /* enable s/w interrupt 1 */
> +#define SR_SINT0       0x00000100      /* enable s/w interrupt 0 */
> +
> +/* alternative interrupt mask naming */
> +#define SR_IM9         0x00040000      /* 1st MUCON ASE interrupt */
> +#define SR_IM8         0x00010000      /* 2nd MUCON ASE interrupt */
> +#define SR_IM7         0x00008000
> +#define SR_IM6         0x00004000
> +#define SR_IM5         0x00002000
> +#define SR_IM4         0x00001000
> +#define SR_IM3         0x00000800
> +#define SR_IM2         0x00000400
> +#define SR_IM1         0x00000200
> +#define SR_IM0         0x00000100
> +
> +#define SR_KX          0x00000080      /* 64-bit kernel mode */
> +#define SR_KX_SHIFT             7
> +#define SR_SX          0x00000040      /* 64-bit supervisor mode */
> +#define SR_SX_SHIFT             6
> +#define SR_UX          0x00000020      /* 64-bit user mode */
> +#define SR_UX_SHIFT             5
> +
> +#define SR_UM          0x00000010      /* user mode */
> +#define SR_KSU_MASK    0x00000018      /* ksu mode mask */
> +#define SR_KSU_SHIFT            3
> +#define SR_KSU_BITS             2
> +#define SR_KSU_USER    0x00000010      /* user mode */
> +#define SR_KSU_SPVS    0x00000008      /* supervisor mode */
> +#define SR_KSU_KERN    0x00000000      /* kernel mode */
> +
> +#define SR_ERL         0x00000004      /* error level */
> +#define  SR_ERL_SHIFT           2
> +#define SR_EXL         0x00000002      /* exception level */
> +#define  SR_EXL_SHIFT           1
> +#define SR_IE          0x00000001      /* interrupt enable */
> +#define  SR_IE_SHIFT            0
> +
> +/*
> + * MIPS32r6 VPControl (CP0 Register 0, Select 4)
> + */
> +#define VPCONTROL_DIS  0x00000001
> +#define VPCONTROL_SHIFT                 0
> +
> +/*
> + * MIPS32r2 HWREna Register  (CP0 Register 7, Select 0)
> + */
> +#define HWRENA_ULR     0x20000000
> +#define HWRENA_XNP     0x00000020
> +#define HWRENA_PERFCNT 0x00000010
> +#define HWRENA_CCRES   0x00000008
> +#define HWRENA_CC      0x00000004
> +#define HWRENA_SYNCSTEP        0x00000002
> +#define HWRENA_CPUNUM  0x00000001
> +
> +/*
> + * MIPS32r2 IntCtl Register  (CP0 Register 12, Select 1)
> + */
> +#define INTCTL_IPTI    0xe0000000      /* timer i/u pending bit */
> +#define  INTCTL_IPTI_SHIFT     29
> +#define  INTCTL_IPTI_BITS       3
> +#define INTCTL_IPPCI   0x1c000000      /* perfctr i/u pending bit */
> +#define  INTCTL_IPPCI_SHIFT    26
> +#define  INTCTL_IPPCI_BITS      3
> +#define INTCTL_IPFDC   0x03800000      /* fast debug chan i/u pending bit
> */
> +#define  INTCTL_IPFDC_SHIFT    23
> +#define  INTCTL_IPFDC_BITS      3
> +#define INTCTL_VS      0x000003e0      /* vector spacing */
> +#define  INTCTL_VS_SHIFT        5
> +#define  INTCTL_VS_BITS                 5
> +#define  INTCTL_VS_0   (0x00 << INTCTL_VS_SHIFT)
> +#define  INTCTL_VS_32  (0x01 << INTCTL_VS_SHIFT)
> +#define  INTCTL_VS_64  (0x02 << INTCTL_VS_SHIFT)
> +#define  INTCTL_VS_128 (0x04 << INTCTL_VS_SHIFT)
> +#define  INTCTL_VS_256 (0x08 << INTCTL_VS_SHIFT)
> +#define  INTCTL_VS_512 (0x10 << INTCTL_VS_SHIFT)
> +
> +/*
> + * MIPS32r2 SRSCtl Register  (CP0 Register 12, Select 2)
> + */
> +#define SRSCTL_HSS     0x3c000000      /* highest shadow set */
> +#define SRSCTL_HSS_SHIFT       26
> +#define SRSCTL_EICSS   0x003c0000      /* EIC shadow set */
> +#define SRSCTL_EICSS_SHIFT     18
> +#define SRSCTL_ESS     0x0000f000      /* exception shadow set */
> +#define SRSCTL_ESS_SHIFT       12
> +#define SRSCTL_PSS     0x000003c0      /* previous shadow set */
> +#define SRSCTL_PSS_SHIFT        6
> +#define SRSCTL_CSS     0x0000000f      /* current shadow set */
> +#define SRSCTL_CSS_SHIFT        0
> +
> +/*
> + * MIPS32 BEVVA Register (CP0 Register 15, Select 4)
> + */
> +#define BEVVA_BASE_MASK        0xfffff000
> +#define BEVVA_BASE_SHIFT       12
> +#define BEVVA_MASK_MASK        0x00000fff
> +#define BEVVA_MASK_SHIFT        0
> +
> +/*
> + * MIPS32 Config0 Register  (CP0 Register 16, Select 0)
> + */
> +#define CFG0_M         0x80000000      /* Config1 implemented */
> +#define  CFG0_M_SHIFT          31
> +#define CFG0_K23_MASK  0x70000000      /* Fixed MMU kseg2/3 CCA */
> +#define  CFG0_K23_SHIFT                28
> +#define CFG0_KU_MASK   0x0e000000      /* Fixed MMU kuseg CCA */
> +#define  CFG0_KU_SHIFT         25
> +#define CFG0_BE                0x00008000      /* Big Endian */
> +#define  CFG0_BE_SHIFT         15
> +#define CFG0_AT_MASK   0x00006000      /* Architecture type: */
> +#define CFG0_ATMASK    0x00006000
> +#define  CFG0_AT_SHIFT         13
> +#define  CFG0_AT_BITS           2
> +#define  CFG0_AT_M32    (0 << CFG0_AT_SHIFT) /* MIPS32 */
> +#define  CFG0_AT_M64_A32 (1 << CFG0_AT_SHIFT) /* MIPS64, 32-bit addresses
> */
> +#define  CFG0_AT_M64_A64 (2 << CFG0_AT_SHIFT) /* MIPS64, 64-bit addresses
> */
> +#define  CFG0_AT_RES    (3 << CFG0_AT_SHIFT)
> +#define CFG0_AR_MASK   0x00001c00
> +#define CFG0_ARMASK    0x00001c00
> +#define  CFG0_AR_SHIFT         10
> +#define  CFG0_ARSHIFT          10
> +#define  CFG0_AR_BITS           3
> +#define  CFG0_AR_R1     (0 << CFG0_AR_SHIFT) /* Release 1 */
> +#define  CFG0_AR_R2     (1 << CFG0_AR_SHIFT) /* Release 2,3,5 */
> +#define  CFG0_AR_R6     (2 << CFG0_AR_SHIFT) /* Release 6 */
> +#define CFG0_MT_MASK   0x00000380      /* MMU Type: */
> +#define CFG0_MTMASK    0x00000380
> +#define  CFG0_MT_SHIFT          7
> +#define  CFG0_MT_BITS           3
> +#define  CFG0_MT_NONE   (0 << CFG0_MT_SHIFT) /* No MMU */
> +#define  CFG0_MT_TLB    (1 << CFG0_MT_SHIFT) /* Standard TLB */
> +#define  CFG0_MT_BAT    (2 << CFG0_MT_SHIFT) /* BAT */
> +#define  CFG0_MT_FIXED  (3 << CFG0_MT_SHIFT) /* Fixed mapping */
> +#define  CFG0_MT_NONSTD         (3 << CFG0_MT_SHIFT) /* Legacy */
> +#define  CFG0_MT_DUAL   (4 << CFG0_MT_SHIFT) /* Dual VTLB and FTLB */
> +#define CFG0_VI                0x00000008      /* Icache is virtual */
> +#define  CFG0_VI_SHIFT          3
> +#define CFG0_K0_MASK   0x00000007      /* KSEG0 coherency algorithm */
> +#define CFG0_K0MASK    0x00000007
> +#define  CFG0_K0_SHIFT          0
> +#define  CFG0_K0_BITS           3
> +
> +/*
> + * MIPS32 Config1 Register (CP0 Register 16, Select 1)
> + */
> +#define CFG1_M         0x80000000      /* Config2 implemented */
> +#define CFG1_M_SHIFT           31
> +#define CFG1_MMUS_MASK 0x7e000000      /* mmu size - 1 */
> +#define CFG1_MMUSMASK  0x7e000000
> +#define  CFG1_MMUS_SHIFT       25
> +#define  CFG1_MMUSSHIFT                25
> +#define  CFG1_MMUS_BITS                 6
> +#define CFG1_IS_MASK   0x01c00000      /* icache lines 64<<n */
> +#define CFG1_ISMASK    0x01c00000
> +#define  CFG1_IS_SHIFT         22      /* Unless n==7, then 32 */
> +#define  CFG1_ISSHIFT          22
> +#define  CFG1_IS_BITS           3
> +#define CFG1_IL_MASK   0x00380000      /* icache line size 2<<n */
> +#define CFG1_ILMASK    0x00380000
> +#define  CFG1_IL_SHIFT         19
> +#define  CFG1_ILSHIFT          19
> +#define  CFG1_IL_BITS           3
> +#define CFG1_IA_MASK   0x00070000      /* icache ways - 1 */
> +#define CFG1_IAMASK    0x00070000
> +#define  CFG1_IA_SHIFT         16
> +#define  CFG1_IASHIFT          16
> +#define  CFG1_IA_BITS           3
> +#define CFG1_DS_MASK   0x0000e000      /* dcache lines 64<<n */
> +#define CFG1_DSMASK    0x0000e000
> +#define  CFG1_DS_SHIFT         13
> +#define  CFG1_DSSHIFT          13
> +#define  CFG1_DS_BITS           3
> +#define CFG1_DL_MASK   0x00001c00      /* dcache line size 2<<n */
> +#define CFG1_DLMASK    0x00001c00
> +#define  CFG1_DL_SHIFT         10
> +#define  CFG1_DLSHIFT          10
> +#define  CFG1_DL_BITS           3
> +#define CFG1_DA_MASK   0x00000380      /* dcache ways - 1 */
> +#define CFG1_DAMASK    0x00000380
> +#define  CFG1_DA_SHIFT          7
> +#define  CFG1_DASHIFT           7
> +#define  CFG1_DA_BITS           3
> +#define CFG1_C2                0x00000040      /* Coprocessor 2 present */
> +#define  CFG1_C2_SHIFT          6
> +#define CFG1_MD                0x00000020      /* MDMX implemented */
> +#define  CFG1_MD_SHIFT          5
> +#define CFG1_PC                0x00000010      /* performance counters
> implemented */
> +#define  CFG1_PC_SHIFT          4
> +#define CFG1_WR                0x00000008      /* watch registers
> implemented */
> +#define  CFG1_WR_SHIFT          3
> +#define CFG1_CA                0x00000004      /* compression (mips16)
> implemented */
> +#define  CFG1_CA_SHIFT          2
> +#define CFG1_EP                0x00000002      /* ejtag implemented */
> +#define  CFG1_EP_SHIFT          1
> +#define CFG1_FP                0x00000001      /* fpu implemented */
> +#define  CFG1_FP_SHIFT          0
> +
> +
> +/*
> + * MIPS32r2 Config2 Register (CP0 Register 16, Select 2)
> + */
> +#define CFG2_M         0x80000000      /* Config3 implemented */
> +#define  CFG1_M_SHIFT          31
> +#define CFG2_TU_MASK   0x70000000      /* tertiary cache control */
> +#define CFG2_TUMASK    0x70000000
> +#define  CFG2_TU_SHIFT         28
> +#define  CFG2_TUSHIFT          28
> +#define  CFG2_TU_BITS           3
> +#define CFG2_TS_MASK   0x0f000000      /* tcache sets per wway 64<<n */
> +#define CFG2_TSMASK    0x0f000000
> +#define  CFG2_TS_SHIFT         24
> +#define  CFG2_TSSHIFT          24
> +#define  CFG2_TS_BITS           4
> +#define CFG2_TL_MASK   0x00f00000      /* tcache line size 2<<n */
> +#define CFG2_TLMASK    0x00f00000
> +#define  CFG2_TL_SHIFT         20
> +#define  CFG2_TLSHIFT          20
> +#define  CFG2_TL_BITS           4
> +#define CFG2_TA_MASK   0x000f0000      /* tcache ways - 1 */
> +#define CFG2_TAMASK    0x000f0000
> +#define  CFG2_TA_SHIFT         16
> +#define  CFG2_TASHIFT          16
> +#define  CFG2_TA_BITS           4
> +#define CFG2_SU_MASK   0x0000f000      /* secondary cache control */
> +#define CFG2_SUMASK    0x0000f000
> +#define  CFG2_SU_SHIFT         12
> +#define  CFG2_SUSHIFT          12
> +#define  CFG2_SU_BITS           4
> +#define CFG2_SS_MASK   0x00000f00      /* scache sets per wway 64<<n */
> +#define CFG2_SSMASK    0x00000f00
> +#define  CFG2_SS_SHIFT          8
> +#define  CFG2_SSSHIFT           8
> +#define  CFG2_SS_BITS           4
> +#define CFG2_SL_MASK   0x000000f0      /* scache line size 2<<n */
> +#define CFG2_SLMASK    0x000000f0
> +#define  CFG2_SL_SHIFT          4
> +#define  CFG2_SLSHIFT           4
> +#define  CFG2_SL_BITS           4
> +#define CFG2_SA_MASK   0x0000000f      /* scache ways - 1 */
> +#define CFG2_SAMASK    0x0000000f
> +#define  CFG2_SA_SHIFT          0
> +#define  CFG2_SASHIFT           0
> +#define  CFG2_SA_BITS           4
> +
> +/*
> + * MIPS32r2 Config3 Register (CP0 Register 16, Select 3)
> + */
> +#define CFG3_M         0x80000000      /* Config4 implemented */
> +#define  CFG3_M_SHIFT          31
> +#define CFG3_BPG       0x40000000      /* Big pages implemented */
> +#define  CFG3_BPG_SHIFT                30
> +#define CFG3_CMGCR     0x20000000      /* Coherency manager implemented */
> +#define  CFG3_CMGCR_SHIFT      29
> +#define CFG3_MSAP      0x10000000      /* MSA implemented */
> +#define  CFG3_MSAP_SHIFT       28
> +#define CFG3_BP                0x08000000      /* BadInstrP implemented */
> +#define  CFG3_BP_SHIFT         27
> +#define CFG3_BI                0x04000000      /* BadInstr implemented */
> +#define  CFG3_BI_SHIFT         26
> +#define CFG3_SC                0x02000000      /* Segment control
> implemented */
> +#define  CFG3_SC_SHIFT         25
> +#define CFG3_PW                0x01000000      /* HW page table walk
> implemented */
> +#define  CFG3_PW_SHIFT         24
> +#define CFG3_VZ                0x00800000      /* Virtualization module
> implemented */
> +#define  CFG3_VZ_SHIFT         23
> +#define CFG3_IPLW_MASK 0x00600000      /* IPL field width */
> +#define  CFG3_IPLW_SHIFT       21
> +#define  CFG3_IPLW_BITS                 2
> +#define  CFG3_IPLW_6BIT        (0 << CFG3_IPLW_SHIFT) /* IPL/RIPL are
> 6-bits wide */
> +#define  CFG3_IPLW_8BIT        (1 << CFG3_IPLW_SHIFT) /* IPL/RIPL are
> 8-bits wide */
> +#define CFG3_MMAR_MASK 0x001c0000      /* MicroMIPS64 architecture
> revision */
> +#define  CFG3_MMAR_SHIFT       18
> +#define  CFG3_MMAR_BITS                 3
> +#define  CFG3_MMAR_R3  (0 << CFG3_MMAR_SHIFT) /* MicroMIPS64 Release 3 */
> +#define CFG3_MCU       0x00020000      /* MCU ASE is implemented */
> +#define  CFG3_MCU_SHIFT                17
> +#define CFG3_IOE       0x00010000      /* MicroMIPS exception entry
> points */
> +#define  CFG3_IOE_SHIFT                16
> +#define CFG3_ISA_MASK  0x0000c000      /* ISA availability */
> +#define  CFG3_ISA_SHIFT                14
> +#define  CFG3_ISA_BITS          2
> +#define  CFG3_ISA_MIPS (0 << CFG3_ISA_SHIFT)  /* MIPS only */
> +#define  CFG3_ISA_UMIPS (1 << CFG3_ISA_SHIFT)  /* MicroMIPS only */
> +#define  CFG3_ISA_BOTH (2 << CFG3_ISA_SHIFT)  /* MIPS (boot) and
> MicroMIPS */
> +#define  CFG3_ISA_UBOTH        (3 << CFG3_ISA_SHIFT)  /* MIPS and
> MicroMIPS (boot) */
> +#define CFG3_ULRI      0x00002000      /* UserLocal register is available
> */
> +#define  CFG3_ULRI_SHIFT       13
> +#define CFG3_RXI       0x00001000      /* RIE and XIE exist in pagegrain
> */
> +#define  CFG3_RXI_SHIFT                12
> +#define CFG3_DSP2P     0x00000800      /* DSPR2 ASE present */
> +#define  CFG3_DSP2P_SHIFT      11
> +#define CFG3_DSPP      0x00000400      /* DSP ASE present */
> +#define  CFG3_DSPP_SHIFT       10
> +#define CFG3_CTXTC     0x00000200      /* Context Config regs are present
> */
> +#define  CFG3_CTXTC_SHIFT       9
> +#define CFG3_ITL       0x00000100      /* IFlowtrace mechanism
> implemented */
> +#define  CFG3_ITL_SHIFT                 8
> +#define CFG3_LPA       0x00000080      /* Large physical addresses */
> +#define  CFG3_LPA_SHIFT                 7
> +#define CFG3_VEIC      0x00000040      /* Vectored external i/u
> controller */
> +#define  CFG3_VEIC_SHIFT        6
> +#define CFG3_VI                0x00000020      /* Vectored i/us */
> +#define  CFG3_VI_SHIFT          5
> +#define CFG3_SP                0x00000010      /* Small page support */
> +#define  CFG3_SP_SHIFT          4
> +#define CFG3_CDMM      0x00000008      /* Common Device Memory Map
> support */
> +#define  CFG3_CDMM_SHIFT        3
> +#define CFG3_MT                0x00000004      /* MT ASE present */
> +#define  CFG3_MT_SHIFT          2
> +#define CFG3_SM                0x00000002      /* SmartMIPS ASE */
> +#define  CFG3_SM_SHIFT          1
> +#define CFG3_TL                0x00000001      /* Trace Logic */
> +#define  CFG3_TL_SHIFT          0
> +
> +/*
> + * MIPS32r2 Config4 Register (CP0 Register 16, Select 4)
> + */
> +#define CFG4_M         0x80000000      /* Config5 implemented */
> +#define  CFG4_M_SHIFT          31
> +#define CFG4_IE_MASK   0x60000000      /* TLB invalidate insn support */
> +#define  CFG4_IE_SHIFT         29
> +#define  CFG4_IE_BITS           2
> +#define  CFG4_IE_NONE  (0 << CFG4_IE_SHIFT) /* TLB invalidate not
> available */
> +#define  CFG4_IE_EHINV (1 << CFG4_IE_SHIFT) /* TLB invalidate with EHINV
> */
> +#define  CFG4_IE_INV   (2 << CFG4_IE_SHIFT) /* TLB invalidate per entry */
> +#define  CFG4_IE_INVALL        (3 << CFG4_IE_SHIFT) /* TLB invalidate
> entire MMU */
> +#define CFG4_AE                0x10000000      /* EntryHI.ASID is 10-bits
> */
> +#define  CFG4_AE_SHIFT         28
> +#define CFG4_VTLBSEXT_MASK   0x0f000000        /* VTLB size extension
> field */
> +#define  CFG4_VTLBSEXT_SHIFT        24
> +#define  CFG4_VTLBSEXT_BITS          4
> +#define CFG4_KSCREXIST_MASK  0x00ff0000        /* Indicates presence of
> KScratch */
> +#define  CFG4_KSCREXIST_SHIFT       16
> +#define  CFG4_KSCREXIST_BITS         8
> +#define CFG4_MMUED          0x0000c000 /* MMU Extension definition */
> +#define  CFG4_MMUED_SHIFT           14
> +#define  CFG4_MMUED_BITS             2
> +#define  CFG4_MMUED_SIZEEXT  (1 << CFG4_MMUED_SHIFT) /* MMUSizeExt */
> +#define  CFG4_MMUED_FTLB     (2 << CFG4_MMUED_SHIFT) /* FTLB fields */
> +#define  CFG4_MMUED_FTLBVEXT (3 << CFG4_MMUED_SHIFT) /* FTLB and Vext */
> +#define CFG4_FTLBPS_MASK     0x00001f00        /* FTLB Page Size */
> +#define  CFG4_FTLBPS_SHIFT           8
> +#define  CFG4_FTLBPS_BITS            5
> +#define CFG4_FTLBW_MASK             0x000000f0 /* FTLB Ways mask */
> +#define  CFG4_FTLBW_SHIFT            4
> +#define  CFG4_FTLBW_BITS             4
> +#define CFG4_FTLBS_MASK             0x0000000f /* FTLB Sets mask */
> +#define  CFG4_FTLBS_SHIFT            0
> +#define  CFG4_FTLBS_BITS             4
> +#define CFG4_MMUSE_MASK             0x000000ff /* MMU size extension */
> +#define  CFG4_MMUSE_SHIFT            0
> +#define  CFG4_MMUSE_BITS             8
> +
> +/*
> + * MIPS32r2 Config5 Register (CP0 Register 16, Select 5)
> + */
> +#define CFG5_M         0x80000000      /* Undefined extension */
> +#define  CFG5_M_SHIFT          31
> +#define CFG5_K         0x40000000      /* Disable CCA control */
> +#define  CFG5_K_SHIFT          30
> +#define CFG5_CV                0x20000000      /* Disable CacheException
> in KSEG1 */
> +#define  CFG5_CV_SHIFT         29
> +#define CFG5_EVA       0x10000000      /* EVA is implemented */
> +#define  CFG5_EVA_SHIFT                28
> +#define CFG5_MSAEN     0x08000000      /* Enable MSA ASE */
> +#define  CFG5_MSAEN_SHIFT      27
> +#define CFG_XNP                0x00002000
> +#define CFG_XNP_SHIFT          13
> +#define CFG5_CES       0x00001000      /* Current endian state */
> +#define  CFG5_CES_SHIFT                12
> +#define CFG5_DEC       0x00000800      /* Dual endian control */
> +#define  CFG5_DEC_SHIFT                11
> +#define CFG5_L2C       0x00000400      /* Config 2 is memory mapped */
> +#define  CFG5_L2C_SHIFT                10
> +#define CFG5_UFE       0x00000200      /* Usermode FRE control */
> +#define  CFG5_LUFE_SHIFT        9
> +#define CFG5_FRE       0x00000100      /* Emulation support for FR=0 */
> +#define  CFG5_FRE_SHIFT                 8
> +#define CFG5_VP                0x00000080      /* Multiple virtual
> processors */
> +#define  CFG5_VP_SHIFT          7
> +#define CFG5_SBRI      0x00000040      /* Force RI on SDBBP */
> +#define  CFG5_SBRI_SHIFT        6
> +#define CFG5_MVH       0x00000020      /* XPA instruction support */
> +#define  CFG5_MVH_SHIFT                 5
> +#define CFG5_LLB       0x00000010      /* Load-Linked Bit present */
> +#define  CFG5_LLB_SHIFT                 4
> +#define CFG5_MRP       0x00000008      /* MAAR and MAARI are present */
> +#define  CFG5_MRP_SHIFT                 3
> +#define CFG5_UFR       0x00000004      /* Usermode FR control */
> +#define  CFG5_UFR_SHIFT                 2
> +#define CFG5_NF                0x00000001      /* Nested fault support */
> +#define  CFG5_NF_SHIFT          0
> +
> +/*
> + * Primary cache mode
> + */
> +#define CFG_CBITS              3
> +#define CFG_C_UNCACHED         2
> +#define CFG_C_WBACK            3
> +#define CFG_C_NONCOHERENT      3
> +
> +#if 0
> +/* These cache modes are CPU specific */
> +#define CFG_C_WTHRU_NOALLOC    0
> +#define CFG_C_WTHRU_ALLOC      1
> +#define CFG_C_COHERENTXCL      4
> +#define CFG_C_COHERENTXCLW     5
> +#define CFG_C_COHERENTUPD      6
> +#define CFG_C_UNCACHED_ACCEL   7
> +#endif
> +
> +
> +/*
> + * Primary Cache TagLo (CP0 Register 28, Select 0/2)
> + */
> +#define TAG_PTAG_MASK           0xffffff00      /* Primary Tag */
> +#define TAG_PTAG_SHIFT          8
> +#define TAG_PSTATE_MASK         0x000000c0      /* Primary Cache State */
> +#define TAG_PSTATE_SHIFT        6
> +#define TAG_PSTATE_LOCK                0x00000020
> +#define TAG_PARITY_MASK         0x00000001      /* Primary Tag Parity */
> +#define TAG_PARITY_SHIFT        0
> +
> +/* primary cache state (XXX actually implementation specific) */
> +#define PSTATE_INVAL           0
> +#define PSTATE_SHARED          1
> +#define PSTATE_CLEAN_EXCL      2
> +#define PSTATE_DIRTY_EXCL      3
> +
> +
> +/*
> + * Cache operations
> + */
> +#define Index_Invalidate_I               0x00        /* 0       0 */
> +#define Index_Writeback_Inv_D            0x01        /* 0       1 */
> +#define Index_Writeback_Inv_T            0x02        /* 0       2 */
> +#define Index_Writeback_Inv_S            0x03        /* 0       3 */
> +#define Index_Load_Tag_I                 0x04        /* 1       0 */
> +#define Index_Load_Tag_D                 0x05        /* 1       1 */
> +#define Index_Load_Tag_T                 0x06        /* 1       2 */
> +#define Index_Load_Tag_S                 0x07        /* 1       3 */
> +#define Index_Store_Tag_I                0x08        /* 2       0 */
> +#define Index_Store_Tag_D                0x09        /* 2       1 */
> +#define Index_Store_Tag_T                0x0A        /* 2       2 */
> +#define Index_Store_Tag_S                0x0B        /* 2       3 */
> +#define Hit_Invalidate_I                 0x10        /* 4       0 */
> +#define Hit_Invalidate_D                 0x11        /* 4       1 */
> +#define Hit_Invalidate_T                 0x12        /* 4       2 */
> +#define Hit_Invalidate_S                 0x13        /* 4       3 */
> +#define Fill_I                           0x14        /* 5       0 */
> +#define Hit_Writeback_Inv_D              0x15        /* 5       1 */
> +#define Hit_Writeback_Inv_T              0x16        /* 5       2 */
> +#define Hit_Writeback_Inv_S              0x17        /* 5       3 */
> +#define Hit_Writeback_D                  0x19        /* 6       1 */
> +#define Hit_Writeback_T                  0x1A        /* 6       2 */
> +#define Hit_Writeback_S                  0x1B        /* 6       3 */
> +#define Fetch_Lock_I                    0x1C        /* 7       0 */
> +#define Fetch_Lock_D                    0x1D        /* 7       1 */
> +#define Fetch_Lock_S                     0x1F        /* 7       3 */
> +
> +/* MIPS32 WatchLo Register (CP0 Register 18) */
> +#define WATCHLO_VA             0xfffffff8
> +#define WATCHLO_I              0x00000004
> +#define WATCHLO_R              0x00000002
> +#define WATCHLO_W              0x00000001
> +
> +/* MIPS32 WatchHi Register (CP0 Register 19) */
> +#define WATCHHI_M              0x80000000
> +#define  WATCHHI_M_SHIFT               31
> +#define WATCHHI_G              0x40000000
> +#define  WATCHHI_G_SHIFT               30
> +#define WATCHHI_ASID_MASK      0x00ff0000
> +#define WATCHHI_ASIDMASK       0x00ff0000
> +#define  WATCHHI_ASID_SHIFT            16
> +#define  WATCHHI_ASIDSHIFT             16
> +#define  WATCHHI_ASID_BITS              8
> +#define WATCHHI_MASK           0x00000ffc
> +#define WATCHHI_I              0x00000004
> +#define WATCHHI_R              0x00000002
> +#define WATCHHI_W              0x00000001
> +
> +/* MIPS32 PerfCnt Register (CP0 Register 25) */
> +#define PERFCNT_M              0x80000000
> +#define PERFCNT_EVENT_MASK     0x000007e0
> +#define PERFCNT_EVENTMASK      0x000007e0
> +#define PERFCNT_EVENT_SHIFT             5
> +#define PERFCNT_EVENTSHIFT              5
> +#define PERFCNT_EVENT_BITS              6
> +#define PERFCNT_IE             0x00000010
> +#define PERFCNT_U              0x00000008
> +#define PERFCNT_S              0x00000004
> +#define PERFCNT_K              0x00000002
> +#define PERFCNT_EXL            0x00000001
> +
> +/* MIPS32r2 PageGrain  Register (CP0 Register 5, Select 1) */
> +#define PAGEGRAIN_ELPA 0x20000000      /* Enable large physical addresses
> */
> +#define PAGEGRAIN_ELPA_SHIFT   29
> +#define PAGEGRAIN_ELPA_BITS    1
> +
> +#define PAGEGRAIN_ESP  0x10000000      /* Enable small (1KB) page support
> */
> +
> +/* MIPS32r2 EBase  Register (CP0 Register 15, Select 1) */
> +#define EBASE_BASE     0xfffff000      /* Exception base */
> +#define EBASE_WG       0x00000800      /* Write Gate */
> +#define  EBASE_WG_SHIFT                11
> +#define EBASE_CPU      0x000003ff      /* CPU number */
> +#define  EBASE_CPU_SHIFT        0
> +#define  EBASE_CPU_BITS                10
> +
> +/* MIPS32r2 EntryHi register (CP0 Register 10, Select 0) */
> +#define C0_ENTRYHI64_R_MASK    0xC000000000000000
> +#define C0_ENTRYHI64_R_BITS    2
> +#define C0_ENTRYHI64_R_SHIFT   61
> +#define C0_ENTRYHI64_VPN2_MASK 0xFFFFFFE000
> +#define C0_ENTRYHI64_VPN2_BITS 27
> +#define C0_ENTRYHI64_VPN2_SHIFT        13
> +#define C0_ENTRYHI_VPN2_MASK   0xFFFFE000
> +#define C0_ENTRYHI_VPN2_BITS   19
> +#define C0_ENTRYHI_VPN2_SHIFT  13
> +#define C0_ENTRYHI_VPN2X_MASK  0x3
> +#define C0_ENTRYHI_VPN2X_BITS  2
> +#define C0_ENTRYHI_VPN2X_SHIFT 11
> +#define C0_ENTRYHI_EHINV_MASK  0x400
> +#define C0_ENTRYHI_EHINV_BITS  1
> +#define C0_ENTRYHI_EHINV_SHIFT 10
> +#define C0_ENTRYHI_ASIDX_MASK  0x300
> +#define C0_ENTRYHI_ASIDX_BITS  2
> +#define C0_ENTRYHI_ASIDX_SHIFT 8
> +#define C0_ENTRYHI_ASID_MASK   0xFF
> +#define C0_ENTRYHI_ASID_BITS   8
> +#define C0_ENTRYHI_ASID_SHIFT  0
> +
> +/* MIPS32 EntryLo0 register (CP0 Register 2, select 0) */
> +#define ENTRYLO064_RI_MASK     0x8000000000000000
> +#define ENTRYLO064_RI_BITS     1
> +#define ENTRYLO064_RI_SHIFT    63
> +#define ENTRYLO064_XI_MASK     0x4000000000000000
> +#define ENTRYLO064_XI_BITS     1
> +#define ENTRYLO064_XI_SHIFT    62
> +#define ENTRYLO064_PFN_MASK    0x3FFFFFFFFFFFFFE0
> +#define ENTRYLO064_PFN_BITS    56
> +#define ENTRYLO064_PFN_SHIFT   6
> +#define ENTRYLO064_RI_SHIFT    63
> +#define ENTRYLO064_RI_BITS     1
> +#define ENTRYLO064_RI_SHIFT    63
> +#define ENTRYLO0_PFNX_MASK     0x7FFFFF
> +#define ENTRYLO0_PFNX_BITS     23
> +#define ENTRYLO0_PFNX_SHIFT    0
> +#define ENTRYLO0_RI_MASK       0x80000000
> +#define ENTRYLO0_RI_BITS       1
> +#define ENTRYLO0_RI_SHIFT      31
> +#define ENTRYLO0_XI_MASK       0x40000000
> +#define ENTRYLO0_XI_BITS       1
> +#define ENTRYLO0_XI_SHIFT      30
> +#define ENTRYLO0_PFN_MASK      0x3FFFFFE0
> +#define ENTRYLO0_PFN_BITS      23
> +#define ENTRYLO0_PFN_SHIFT     6
> +#define ENTRYLO0_C_MASK                0x38
> +#define ENTRYLO0_C_BITS                3
> +#define ENTRYLO0_C_SHIFT       3
> +#define ENTRYLO0_D_MASK                0x4
> +#define ENTRYLO0_D_BITS                1
> +#define ENTRYLO0_D_SHIFT       2
> +#define ENTRYLO0_V_MASK                0x2
> +#define ENTRYLO0_V_BITS                1
> +#define ENTRYLO0_V_SHIFT       1
> +#define ENTRYLO0_G_MASK                0x1
> +#define ENTRYLO0_G_BITS                1
> +#define ENTRYLO0_G_SHIFT       0
> +
> +/* MIPS32 EntryLo1 register (CP0 Register 3, select 0) */
> +#define ENTRYLO164_RI_MASK     ENTRYLO064_RI_MASK
> +#define ENTRYLO164_RI_BITS     ENTRYLO064_RI_BITS
> +#define ENTRYLO164_RI_SHIFT    ENTRYLO064_RI_SHIFT
> +#define ENTRYLO164_XI_MASK     ENTRYLO064_XI_MASK
> +#define ENTRYLO164_XI_BITS     ENTRYLO064_XI_BITS
> +#define ENTRYLO164_XI_SHIFT    ENTRYLO064_XI_SHIFT
> +#define ENTRYLO164_PFN_MASK    ENTRYLO064_PFN_MASK
> +#define ENTRYLO164_PFN_BITS    ENTRYLO064_PFN_BITS
> +#define ENTRYLO164_PFN_SHIFT   ENTRYLO064_PFN_SHIFT
> +#define ENTRYLO164_RI_SHIFT    ENTRYLO064_RI_SHIFT
> +#define ENTRYLO164_RI_BITS     ENTRYLO064_RI_BITS
> +#define ENTRYLO164_RI_SHIFT    ENTRYLO064_RI_SHIFT
> +#define ENTRYLO1_PFNX_MASK     ENTRYLO0_PFNX_MASK
> +#define ENTRYLO1_PFNX_BITS     ENTRYLO0_PFNX_BITS
> +#define ENTRYLO1_PFNX_SHIFT    ENTRYLO0_PFNX_SHIFT
> +#define ENTRYLO1_RI_MASK       ENTRYLO0_RI_MASK
> +#define ENTRYLO1_RI_BITS       ENTRYLO0_RI_BITS
> +#define ENTRYLO1_RI_SHIFT      ENTRYLO0_RI_SHIFT
> +#define ENTRYLO1_XI_MASK       ENTRYLO0_XI_MASK
> +#define ENTRYLO1_XI_BITS       ENTRYLO0_XI_BITS
> +#define ENTRYLO1_XI_SHIFT      ENTRYLO0_XI_SHIFT
> +#define ENTRYLO1_PFN_MASK      ENTRYLO0_PFN_MASK
> +#define ENTRYLO1_PFN_BITS      ENTRYLO0_PFN_BITS
> +#define ENTRYLO1_PFN_SHIFT     ENTRYLO0_PFN_SHIFT
> +#define ENTRYLO1_C_MASK                ENTRYLO0_C_MASK
> +#define ENTRYLO1_C_BITS                ENTRYLO0_C_BITS
> +#define ENTRYLO1_C_SHIFT       ENTRYLO0_C_SHIFT
> +#define ENTRYLO1_D_MASK                ENTRYLO0_D_MASK
> +#define ENTRYLO1_D_BITS                ENTRYLO0_D_BITS
> +#define ENTRYLO1_D_SHIFT       ENTRYLO0_D_SHIFT
> +#define ENTRYLO1_V_MASK                ENTRYLO0_V_MASK
> +#define ENTRYLO1_V_BITS                ENTRYLO0_V_BITS
> +#define ENTRYLO1_V_SHIFT       ENTRYLO0_V_SHIFT
> +#define ENTRYLO1_G_MASK                ENTRYLO0_G_MASK
> +#define ENTRYLO1_G_BITS                ENTRYLO0_G_BITS
> +#define ENTRYLO1_G_SHIFT       ENTRYLO0_G_SHIFT
> +
> +/* MIPS32 TraceControl register (CP0 Register 23, select 1) */
> +#define TRACECONTROL_TS_MASK     0x80000000
> +#define  TRACECONTROL_TS_SHIFT           31
> +#define TRACECONTROL_TB_MASK     0x08000000
> +#define  TRACECONTROL_TB_SHIFT           27
> +#define TRACECONTROL_IO_MASK     0x04000000
> +#define  TRACECONTROL_IO_SHIFT           26
> +#define TRACECONTROL_D_MASK      0x02000000
> +#define  TRACECONTROL_D_SHIFT            25
> +#define TRACECONTROL_E_MASK      0x01000000
> +#define  TRACECONTROL_E_SHIFT            24
> +#define TRACECONTROL_K_MASK      0x00800000
> +#define  TRACECONTROL_K_SHIFT            23
> +#define TRACECONTROL_S_MASK      0x00400000
> +#define  TRACECONTROL_S_SHIFT            22
> +#define TRACECONTROL_U_MASK      0x00200000
> +#define  TRACECONTROL_U_SHIFT            21
> +#define TRACECONTROL_ASID_M_MASK  0x001fe000
> +#define  TRACECONTROL_ASID_M_SHIFT       13
> +#define  TRACECONTROL_ASID_M_BITS         8
> +#define TRACECONTROL_ASID_MASK   0x00001fe0
> +#define  TRACECONTROL_ASID_SHIFT          5
> +#define  TRACECONTROL_ASID_BITS                   8
> +#define TRACECONTROL_G_MASK      0x00000010
> +#define  TRACECONTROL_G_SHIFT             4
> +#define TRACECONTROL_TFCR_MASK   0x00000008
> +#define  TRACECONTROL_TFCR_SHIFT          3
> +#define TRACECONTROL_TLSM_MASK   0x00000004
> +#define  TRACECONTROL_TLSM_SHIFT          2
> +#define TRACECONTROL_TIM_MASK    0x00000002
> +#define  TRACECONTROL_TIM_SHIFT                   1
> +#define TRACECONTROL_ON_MASK     0x00000001
> +#define  TRACECONTROL_ON_SHIFT            0
> +
> +/* MIPS32 TraceControl2 register (CP0 Register 23, select 2) */
> +#define TRACECONTROL2_SYPEXT_MASK   0xc0000000
> +#define  TRACECONTROL2_SYPEXT_SHIFT        30
> +#define  TRACECONTROL2_SYPEXT_BITS          2
> +#define TRACECONTROL2_CPUIDV_MASK   0x20000000
> +#define  TRACECONTROL2_CPUIDV_SHIFT        29
> +#define TRACECONTROL2_CPUID_MASK    0x1fe00000
> +#define  TRACECONTROL2_CPUID_SHIFT         21
> +#define  TRACECONTROL2_CPUID_BITS           8
> +#define TRACECONTROL2_TCV_MASK     0x00100000
> +#define  TRACECONTROL2_TCV_SHIFT           20
> +#define TRACECONTROL2_TCNUM_MASK    0x000ff000
> +#define  TRACECONTROL2_TCNUM_SHIFT         12
> +#define  TRACECONTROL2_TCNUM_BITS           8
> +#define TRACECONTROL2_MODE_MASK            0x00000f80
> +#define  TRACECONTROL2_MODE_SHIFT           7
> +#define  TRACECONTROL2_MODE_BITS            5
> +#define TRACECONTROL2_VMODE_MASK    0x00000060
> +#define  TRACECONTROL2_VMODE_SHIFT          5
> +#define  TRACECONTROL2_VMODE_BITS           2
> +#define  TRACECONTROL2_VMODE_PC            (0x0 <<
> TRACECONTROL2_VMODE_SHIFT)
> +#define  TRACECONTROL2_VMODE_PCLSA  (0x1 << TRACECONTROL2_VMODE_SHIFT)
> +#define  TRACECONTROL2_VMODE_PCLSAD (0x2 << TRACECONTROL2_VMODE_SHIFT)
> +#define TRACECONTROL2_TBI_MASK     0x00000010
> +#define  TRACECONTROL2_TBI_SHIFT            4
> +#define TRACECONTROL2_TBU_MASK     0x00000008
> +#define  TRACECONTROL2_TBU_SHIFT            3
> +#define TRACECONTROL2_SYP_MASK     0x00000007
> +#define  TRACECONTROL2_SYP_SHIFT            0
> +#define  TRACECONTROL2_SYP_BITS                     3
> +
> +/* MIPS32 TraceControl3 register (CP0 Register 24, select 2) */
> +#define TRACECONTROL3_TNUD_MASK            0x20000000
> +#define  TRACECONTROL3_TNUD_SHIFT          29
> +#define TRACECONTROL3_MSA_EN_MASK   0x10000000
> +#define  TRACECONTROL3_MSA_EN_SHIFT        28
> +#define TRACECONTROL3_MSA_MASK     0x08000000
> +#define  TRACECONTROL3_MSA_SHIFT           27
> +#define TRACECONTROL3_EASID_M_MASK  0x06000000
> +#define  TRACECONTROL3_EASID_M_SHIFT       25
> +#define  TRACECONTROL3_EASID_M_BITS         2
> +#define TRACECONTROL3_EASID_MASK    0x01800000
> +#define  TRACECONTROL3_EASID_SHIFT         23
> +#define  TRACECONTROL3_EASID_BITS           2
> +#define TRACECONTROL3_GV_MASK      0x00400000
> +#define  TRACECONTROL3_GV_SHIFT                    22
> +#define TRACECONTROL3_GUESTID_MASK  0x003fc000
> +#define  TRACECONTROL3_GUESTID_SHIFT       14
> +#define  TRACECONTROL3_GUESTID_BITS         8
> +#define TRACECONTROL3_PECOVF_MASK   0x00000200
> +#define  TRACECONTROL3_PECOVF_SHIFT        13
> +#define TRACECONTROL3_PECFCR_MASK   0x00000100
> +#define  TRACECONTROL3_PECFCR_SHIFT        12
> +#define TRACECONTROL3_PECBP_MASK    0x00000080
> +#define  TRACECONTROL3_PECBP_SHIFT         11
> +#define TRACECONTROL3_PECSYNC_MASK  0x00000040
> +#define  TRACECONTROL3_PECSYNC_SHIFT       10
> +#define TRACECONTROL3_PECE_MASK            0x00000020
> +#define  TRACECONTROL3_PECE_SHIFT           9
> +#define TRACECONTROL3_PEC_MASK     0x00000010
> +#define  TRACECONTROL3_PEC_SHIFT            8
> +#define TRACECONTROL3_TRIDLE_MASK   0x00000004
> +#define  TRACECONTROL3_TRIDLE_SHIFT         2
> +#define TRACECONTROL3_TRPAD_MASK    0x00000002
> +#define  TRACECONTROL3_TRPAD_SHIFT          1
> +#define TRACECONTROL3_FDT_MASK     0x00000001
> +#define  TRACECONTROL3_FDT_SHIFT            0
> +
> +#ifdef __ASSEMBLER__
> +
> +/*
> + * MIPS32 Coprocessor 0 register numbers
> + */
> +#define C0_INDEX       $0
> +#define C0_INX         $0
> +#define C0_RANDOM      $1
> +#define C0_RAND                $1
> +#define C0_ENTRYLO0    $2
> +#define C0_TLBLO0      $2
> +#define C0_ENTRYLO1    $3
> +#define C0_TLBLO1      $3
> +#define C0_GLOBAL      $3,1
> +#define C0_CONTEXT     $4
> +#define C0_CTXT                $4
> +#define C0_CONTEXTCONF $4,1
> +#define C0_USERLOCAL   $4,2
> +#define C0_XCONTEXTCONF        $4,3
> +#define C0_DEBUGCTXTID $4,4
> +#define C0_PAGEMASK    $5
> +#define C0_PAGEGRAIN   $5,1
> +#define C0_SEGCTL0     $5,2
> +#define C0_SEGCTL1     $5,3
> +#define C0_SEGCTL2     $5,4
> +#define C0_PWBASE      $5,5
> +#define C0_PWFIELD     $5,6
> +#define C0_PWSIZE      $5,7
> +#define C0_WIRED       $6
> +#define C0_PWCTL       $6,6
> +#define C0_HWRENA      $7
> +#define C0_BADVADDR    $8
> +#define C0_VADDR       $8
> +#define C0_BADINSTR    $8,1
> +#define C0_BADPINSTR   $8,2
> +#define C0_COUNT       $9
> +#define C0_ENTRYHI     $10
> +#define C0_TLBHI       $10
> +#define C0_COMPARE     $11
> +#define C0_STATUS      $12
> +#define C0_SR          $12
> +#define C0_INTCTL      $12,1
> +#define C0_SRSCTL      $12,2
> +#define C0_SRSMAP      $12,3
> +#define C0_CAUSE       $13
> +#define C0_CR          $13
> +#define C0_NESTEDEXC   $13,5
> +#define C0_EPC                 $14
> +#define C0_NEPC                $14,2
> +#define C0_PRID                $15
> +#define C0_EBASE       $15,1
> +#define C0_CDMMBASE    $15,2
> +#define C0_CMGCRBASE   $15,3
> +#define C0_BEVVA       $15,4
> +#define C0_CONFIG      $16
> +#define C0_CONFIG0     $16,0
> +#define C0_CONFIG1     $16,1
> +#define C0_CONFIG2     $16,2
> +#define C0_CONFIG3     $16,3
> +#define C0_CONFIG4     $16,4
> +#define C0_CONFIG5     $16,5
> +#define C0_LLADDR      $17
> +#define C0_MAAR                $17,1
> +#define C0_MAARI       $17,2
> +#define C0_WATCHLO     $18
> +#define C0_WATCHHI     $19
> +#define C0_XCONTEXT    $20
> +#define C0_DEBUG       $23
> +#define C0_TRACECONTROL          $23,1
> +#define C0_TRACECONTROL2  $23,2
> +#define C0_USERTRACEDATA1 $23,3
> +#define C0_TRACEIBPC      $23,4
> +#define C0_TRACEDBPC      $23,5
> +#define C0_DEBUG2        $23,6
> +#define C0_DEPC                  $24
> +#define C0_TRACECONTROL3  $24,2
> +#define C0_USERTRACEDATA2 $24,3
> +#define C0_PERFCNT     $25
> +#define C0_ERRCTL      $26
> +#define C0_CACHEERR    $27
> +#define C0_TAGLO       $28
> +#define C0_ITAGLO      $28
> +#define C0_DTAGLO      $28,2
> +#define C0_TAGLO2      $28,4
> +#define C0_DATALO      $28,1
> +#define C0_IDATALO     $28,1
> +#define C0_DDATALO     $28,3
> +#define C0_DATALO2     $28,5
> +#define C0_TAGHI       $29
> +#define C0_ITAGHI      $29
> +#define C0_DTAGHI      $29,2
> +#define C0_DATAHI      $29,1
> +#define C0_IDATAHI     $29,1
> +#define C0_DDATAHI     $29,3
> +#define C0_ERRPC       $30
> +#define C0_DESAVE      $31
> +#define C0_KSCRATCH1   $31,2
> +#define C0_KSCRATCH2   $31,3
> +#define C0_KSCRATCH3   $31,4
> +#define C0_KSCRATCH4   $31,5
> +#define C0_KSCRATCH5   $31,6
> +#define C0_KSCRATCH6   $31,7
> +
> +$index         =       $0
> +$random                =       $1
> +$entrylo0      =       $2
> +$entrylo1      =       $3
> +$context       =       $4
> +$pagemask      =       $5
> +$wired         =       $6
> +$hwrena                =       $7
> +$vaddr                 =       $8
> +$badvaddr      =       $8
> +$count                 =       $9
> +$entryhi       =       $10
> +$compare       =       $11
> +$sr            =       $12
> +$cr            =       $13
> +$epc           =       $14
> +$prid          =       $15
> +$config                =       $16
> +$lladdr                =       $17
> +$watchlo       =       $18
> +$watchhi       =       $19
> +$debug         =       $23
> +$depc          =       $24
> +$perfcnt       =       $25
> +$errctl                =       $26
> +$cacheerr      =       $27
> +$taglo         =       $28
> +$taghi         =       $29
> +$errpc         =       $30
> +$desave                =       $31
> +
> +
> +#else /* !__ASSEMBLER__ */
> +
> +/*
> + * Standard types
> + */
> +typedef unsigned int           reg32_t;        /* a 32-bit register */
> +typedef unsigned long long     reg64_t;        /* a 64-bit register */
> +#if _MIPS_SIM==_ABIO32
> +typedef unsigned int           reg_t;
> +typedef signed int             sreg_t;
> +#else
> +typedef unsigned long long     reg_t;
> +typedef signed long long       sreg_t;
> +#endif
> +
> +/*
> + * MIPS32 Coprocessor 0 register encodings for C use.
> + * These encodings are implementation specific.
> + */
> +#define C0_INDEX       0
> +#define C0_INX         0
> +#define C0_RANDOM      1
> +#define C0_RAND                1
> +#define C0_ENTRYLO0    2
> +#define C0_TLBLO0      2
> +#define C0_ENTRYLO1    3
> +#define C0_TLBLO1      3
> +#define C0_GLOBAL      0x103
> +#define C0_CONTEXT     4
> +#define C0_CTXT                4
> +#define C0_CONTEXTCONF 0x104
> +#define C0_USERLOCAL   0x204
> +#define C0_XCONTEXTCONF        0x304
> +#define C0_DEBUGCTXTID 0x404
> +#define C0_PAGEMASK    5
> +#define C0_PAGEGRAIN   0x105
> +#define C0_SEGCTL0     0x205
> +#define C0_SEGCTL1     0x305
> +#define C0_SEGCTL2     0x405
> +#define C0_PWBASE      0x505
> +#define C0_PWFIELD     0x605
> +#define C0_PWSIZE      0x705
> +#define C0_WIRED       6
> +#define C0_PWCTL       0x606
> +#define C0_HWRENA      7
> +#define C0_BADVADDR    8
> +#define C0_VADDR       8
> +#define C0_BADINSTR    0x108
> +#define C0_BADINSTRP   0x208
> +#define C0_COUNT       9
> +#define C0_ENTRYHI     10
> +#define C0_TLBHI       10
> +#define C0_COMPARE     11
> +#define C0_STATUS      12
> +#define C0_SR          12
> +#define C0_INTCTL      0x10C
> +#define C0_SRSCTL      0x20C
> +#define C0_SRSMAP      0x30C
> +#define C0_CAUSE       13
> +#define C0_CR          13
> +#define C0_NESTEDEXC   0x50D
> +#define C0_EPC                 14
> +#define C0_NEPC                0x20E
> +#define C0_PRID                15
> +#define C0_EBASE       0x10F
> +#define C0_CDMMBASE    0x20F
> +#define C0_CMGCRBASE   0x30F
> +#define C0_BEVVA       0x40F
> +#define C0_CONFIG      16
> +#define C0_CONFIG0     16
> +#define C0_CONFIG1     0x110
> +#define C0_CONFIG2     0x210
> +#define C0_CONFIG3     0x310
> +#define C0_CONFIG4     0x410
> +#define C0_CONFIG5     0x510
> +#define C0_LLADDR      17
> +#define C0_MAAR                0x111
> +#define C0_MAARI       0x111
> +#define C0_WATCHLO     18
> +#define C0_WATCHHI     19
> +#define C0_XCONTEXT    20
> +#define C0_DEBUG       23
> +#define C0_TRACECONTROL          0x117
> +#define C0_TRACECONTROL2  0x217
> +#define C0_USERTRACEDATA1 0x317
> +#define C0_TRACEIBPC      0x417
> +#define C0_TRACEDBPC      0x517
> +#define C0_DEBUG2        0x617
> +#define C0_DEPC                  24
> +#define C0_TRACECONTROL3  0x218
> +#define C0_USERTRACEDATA2 0x318
> +#define C0_PERFCNT     25
> +#define C0_ERRCTL      26
> +#define C0_CACHEERR    27
> +#define C0_TAGLO       28
> +#define C0_ITAGLO      28
> +#define C0_DTAGLO      0x21C
> +#define C0_TAGLO2      0x41C
> +#define C0_DATALO      0x11C
> +#define C0_IDATALO     0x11C
> +#define C0_DDATALO     0x31C
> +#define C0_DATALO2     0x51C
> +#define C0_TAGHI       29
> +#define C0_ITAGHI      29
> +#define C0_DTAGHI      0x21D
> +#define C0_DATAHI      0x11D
> +#define C0_IDATAHI     0x11D
> +#define C0_DDATAHI     0x31D
> +#define C0_ERRPC       30
> +#define C0_DESAVE      31
> +#define C0_KSCRATCH1   0x21F
> +#define C0_KSCRATCH2   0x31F
> +#define C0_KSCRATCH3   0x41F
> +#define C0_KSCRATCH4   0x51F
> +#define C0_KSCRATCH5   0x61F
> +#define C0_KSCRATCH6   0x71F
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#define _mips_sync() __asm__ __volatile__ ("sync" : : : "memory")
> +
> +/* wait for unmasked interrupt */
> +#define _mips_wait() \
> +  __asm__ __volatile ("wait")
> +
> +/*
> + * Define macros for accessing the MIPS32 coprocessor 0 registers. Most
> apart
> + * from "set" return the original register value. These macros take an
> encoded
> + * (register, select) combination, so they can use the textual names
> above.
> + */
> +
> +#define MIPS_C0_REGNAME(regno, sel) ((sel << 8) + regno)
> +
> +#define mips32_get_c0(selreg) \
> +__extension__ ({ \
> +  register unsigned long __r; \
> +  __asm__ __volatile ("mfc0 %0,$%1,%2" \
> +                     : "=d" (__r) \
> +                     : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \
> +  __r; \
> +})
> +
> +#undef EHB
> +#if defined (__MIPS_NO_IMPLICIT_EHB)
> +#define EHB    ""
> +#else
> +#define EHB    "ehb\n"
> +#endif
> +
> +#define mips32_set_c0(selreg, val) \
> +do { \
> +    __asm__ __volatile (".set push \n"\
> +                       ".set noreorder\n"\
> +                       "mtc0 %z0,$%1,%2\n"\
> +                       EHB \
> +                       ".set pop" \
> +                       : \
> +                       : "dJ" ((reg32_t)(val)), "JK" (selreg & 0x1F),\
> +                         "JK" (selreg >> 8) \
> +                       : "memory"); \
> +} while (0)
> +
> +#define mips32_xch_c0(selreg, val) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = mips32_get_c0 (selreg); \
> +    mips32_set_c0 (selreg, val); \
> +    __o; \
> +})
> +
> +#define mips32_bc_c0(selreg, clr) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = mips32_get_c0 (selreg); \
> +    mips32_set_c0 (selreg, __o & ~(clr)); \
> +    __o; \
> +})
> +
> +#define mips32_bs_c0(selreg, set) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = mips32_get_c0 (selreg); \
> +    mips32_set_c0 (selreg, __o | (set)); \
> +    __o; \
> +})
> +
> +#define mips32_bcs_c0(selreg, clr, set) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = mips32_get_c0 (selreg); \
> +    mips32_set_c0 (selreg, (__o & ~(clr)) | (set)); \
> +    __o; \
> +})
> +
> +/* MIPS instructions */
> +#define mips_sync()            \
> +  ({__asm__ volatile ("\t sync \n");})
> +
> +#define mips_synci(ADDR)               \
> +  ({__asm__ volatile ("\t synci 0(%0) \n" :: "r" (ADDR));})
> +
> +#define mips_synci_step()                      \
> +({                                             \
> +    int _step;                                 \
> +    __asm__ volatile (                         \
> +      "\t rdhwr %0,$1 \n" : "=r" (_step));     \
> +    _step;                                     \
> +})
> +
> +#define mips_ehb()             \
> +  ({__asm__ volatile ("\t ehb \n");})
> +
> +#define mips_tlbwi()   \
> +  ({__asm__ volatile ("\t tlbwi \n");})
> +
> +#define mips_tlbwr()   \
> +  ({__asm__ volatile ("\t tlbwr \n");})
> +
> +#define mips_tlbp()    \
> +  ({__asm__ volatile ("\t tlbp \n");})
> +
> +#define mips_tlbr()    \
> +  ({__asm__ volatile ("\t tlbr \n");})
> +
> +#define mips_eva_tlbinvf()     \
> +({__asm__ volatile (           \
> +    "\t .set  push \n"         \
> +    "\t .set  eva \n"          \
> +    "\t tlbinvf \n"            \
> +    "\t .set  pop \n"          \
> +    );                         \
> +})
> +
> +/* Set upper half of EntryHI */
> +#define mips32_sethientryhi(VAL)       \
> +({__asm__ volatile (           \
> +    "\t .set  push \n"         \
> +    "\t .set  xpa \n"          \
> +    "\t mthc0 %0,$10,0 \n"     \
> +    "\t .set  pop \n"          \
> +    : :"r" (VAL)               \
> +    );                         \
> +})
> +
> +#define mips_cache(OP,ADDR)    \
> +  ({__asm__ volatile ("\t cache %0,0(%1) \n" :: "JK" (OP), "r" (ADDR));})
> +
> +/* generic equivalents for mips/cpu.h */
> +#define _mips_mfc0(r)          mips32_get_c0(r)
> +#define _mips_mtc0(r,v)                mips32_set_c0(r,v)
> +
> +/* MIPS32 Entry*, Index, PageMask registers */
> +#define mips32_getentryhi()    mips32_get_c0(C0_ENTRYHI)
> +#define mips32_setentryhi(v)   mips32_set_c0(C0_ENTRYHI,v)
> +#define mips32_getentrylo0()   mips32_get_c0(C0_ENTRYLO0)
> +#define mips32_setentrylo0(v)  mips32_set_c0(C0_ENTRYLO0,v)
> +#define mips32_getentrylo1()   mips32_get_c0(C0_ENTRYLO1)
> +#define mips32_setentrylo1(v)  mips32_set_c0(C0_ENTRYLO1,v)
> +#define mips32_getpagemask()   mips32_get_c0(C0_PAGEMASK)
> +#define mips32_setpagemask(v)  mips32_set_c0(C0_PAGEMASK,v)
> +#define mips32_getindex()      mips32_get_c0(C0_INDEX)
> +#define mips32_setindex(v)     mips32_set_c0(C0_INDEX,v)
> +
> +/* MIPS32 Config0 register */
> +#define mips32_getconfig0()    mips32_get_c0(C0_CONFIG0)
> +#define mips32_setconfig0(v)   mips32_set_c0(C0_CONFIG0,v)
> +#define mips32_xchconfig0(v)   mips32_xch_c0(C0_CONFIG0,v)
> +#define mips32_bicconfig0(clr) mips32_bc_c0(C0_CONFIG0,clr)
> +#define mips32_bisconfig0(set) mips32_bs_c0(C0_CONFIG0,set)
> +#define mips32_bcsconfig0(c,s) mips32_bcs_c0(C0_CONFIG0,c,s)
> +
> +/* MIPS32 Config1, 2, 3, 4, 5 register */
> +#define mips32_getconfig1()    mips32_get_c0(C0_CONFIG1)
> +#define mips32_setconfig1(v)   mips32_set_c0(C0_CONFIG1,v)
> +#define mips32_xchconfig1(v)   mips32_xch_c0(C0_CONFIG1,v)
> +#define mips32_bicconfig1(clr) mips32_bc_c0(C0_CONFIG1,clr)
> +#define mips32_bisconfig1(set) mips32_bs_c0(C0_CONFIG1,set)
> +#define mips32_bcsconfig1(c,s) mips32_bcs_c0(C0_CONFIG1,c,s)
> +
> +#define mips32_getconfig2()    mips32_get_c0(C0_CONFIG2)
> +#define mips32_setconfig2(v)   mips32_set_c0(C0_CONFIG2,v)
> +#define mips32_xchconfig2(v)   mips32_xch_c0(C0_CONFIG2,v)
> +#define mips32_bicconfig2(clr) mips32_bc_c0(C0_CONFIG2,clr)
> +#define mips32_bisconfig2(set) mips32_bs_c0(C0_CONFIG2,set)
> +#define mips32_bcsconfig2(c,s) mips32_bcs_c0(C0_CONFIG2,c,s)
> +
> +#define mips32_getconfig3()    mips32_get_c0(C0_CONFIG3)
> +#define mips32_setconfig3(v)   mips32_set_c0(C0_CONFIG3,v)
> +#define mips32_xchconfig3(v)   mips32_xch_c0(C0_CONFIG3,v)
> +#define mips32_bicconfig3(clr) mips32_bc_c0(C0_CONFIG3,clr)
> +#define mips32_bisconfig3(set) mips32_bs_c0(C0_CONFIG3,set)
> +#define mips32_bcsconfig3(c,s) mips32_bcs_c0(C0_CONFIG3,c,s)
> +
> +#define mips32_getconfig4()    mips32_get_c0(C0_CONFIG4)
> +#define mips32_setconfig4(v)   mips32_set_c0(C0_CONFIG4,v)
> +#define mips32_xchconfig4(v)   mips32_xch_c0(C0_CONFIG4,v)
> +#define mips32_bicconfig4(clr) mips32_bc_c0(C0_CONFIG4,clr)
> +#define mips32_bisconfig4(set) mips32_bs_c0(C0_CONFIG4,set)
> +#define mips32_bcsconfig4(c,s) mips32_bcs_c0(C0_CONFIG4,c,s)
> +
> +#define mips32_getconfig5()    mips32_get_c0(C0_CONFIG5)
> +#define mips32_setconfig5(v)   mips32_set_c0(C0_CONFIG5,v)
> +#define mips32_xchconfig5(v)   mips32_xch_c0(C0_CONFIG5,v)
> +#define mips32_bicconfig5(clr) mips32_bc_c0(C0_CONFIG5,clr)
> +#define mips32_bisconfig5(set) mips32_bs_c0(C0_CONFIG5,set)
> +#define mips32_bcsconfig5(c,s) mips32_bcs_c0(C0_CONFIG5,c,s)
> +
> +/* MIPS32 Debug register */
> +#define mips32_getdebug()      mips32_get_c0(C0_DEBUG)
> +#define mips32_setdebug(v)     mips32_set_c0(C0_DEBUG,v)
> +#define mips32_xchdebug(v)     mips32_xch_c0(C0_DEBUG,v)
> +#define mips32_bicdebug(clr)   mips32_bc_c0(C0_DEBUG,clr)
> +#define mips32_bisdebug(set)   mips32_bs_c0(C0_DEBUG,set)
> +#define mips32_bcsdebug(c,s)   mips32_bcs_c0(C0_DEBUG,c,s)
> +
> +/* MIPS32 ErrCtl register */
> +#define mips32_geterrctl()     mips32_get_c0(C0_ERRCTL)
> +#define mips32_seterrctl(x)    mips32_set_c0(C0_ERRCTL,x)
> +#define mips32_xcherrctl(x)    mips32_xch_c0(C0_ERRCTL,x)
> +#define mips32_bicerrctl(clr)  mips32_bc_c0(C0_ERRCTL,clr)
> +#define mips32_biserrctl(set)  mips32_bs_c0(C0_ERRCTL,set)
> +#define mips32_bcserrctl(c,s)  mips32_bcs_c0(C0_ERRCTL,c,s)
> +
> +/* MIPS32 TagLo register */
> +#define mips32_getitaglo()     mips32_get_c0(C0_TAGLO)         /* alias
> define */
> +#define mips32_setitaglo(x)    mips32_set_c0(C0_TAGLO,x)       /* alias
> define */
> +#define mips32_xchitaglo(x)    mips32_xch_c0(C0_TAGLO,x)       /* alias
> define */
> +#define mips32_getdtaglo()     mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 2))
> +#define mips32_setdtaglo(x)    mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 2),x)
> +#define mips32_xchdtaglo(x)    mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 2),x)
> +#define mips32_gettaglo2()     mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 4))
> +#define mips32_settaglo2(x)    mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 4),x)
> +#define mips32_xchtaglo2(x)    mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 4),x)
> +
> +/* MIPS32 DataLo register */
> +#define mips32_getdatalo()     mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 1))
> +#define mips32_setdatalo(x)    mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 1),x)
> +#define mips32_xchdatalo(x)    mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 1),x)
> +#define mips32_getidatalo()    mips32_getdatalo()      /* alias define */
> +#define mips32_setidatalo(x)   mips32_setdatalo(x)     /* alias define */
> +#define mips32_xchidatalo(x)   mips32_xchdatalo(x)     /* alias define */
> +#define mips32_getddatalo()    mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 3))
> +#define mips32_setddatalo(x)   mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 3),x)
> +#define mips32_xchddatalo(x)   mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 3),x)
> +#define mips32_getdatalo2()    mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 5))
> +#define mips32_setdatalo2(x)   mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 5),x)
> +#define mips32_xchdatalo2(x)   mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 5),x)
> +
> +/* MIPS32r2 IntCtl register */
> +#define mips32_getintctl()     mips32_get_c0(C0_INTCTL)
> +#define mips32_setintctl(x)    mips32_set_c0(C0_INTCTL,x)
> +#define mips32_xchintctl(x)    mips32_xch_c0(C0_INTCTL,x)
> +
> +/* MIPS32r2 SRSCtl register */
> +#define mips32_getsrsctl()     mips32_get_c0(C0_SRSCTL)
> +#define mips32_setsrsctl(x)    mips32_set_c0(C0_SRSCTL,x)
> +#define mips32_xchsrsctl(x)    mips32_xch_c0(C0_SRSCTL,x)
> +
> +/* MIPS32r2 SRSMap register */
> +#define mips32_getsrsmapl()    mips32_get_c0(C0_SRSMAP)
> +#define mips32_setsrsmap(x)    mips32_set_c0(C0_SRSMAP,x)
> +#define mips32_xchsrsmap(x)    mips32_xch_c0(C0_SRSMAP,x)
> +
> +/* MIPS32r2/SmartMIPS PageGrain register */
> +#define mips32_getpagegrain()  mips32_get_c0(C0_PAGEGRAIN)
> +#define mips32_setpagegrain(x) mips32_set_c0(C0_PAGEGRAIN,x)
> +#define mips32_xchpagegrain(x) mips32_xch_c0(C0_PAGEGRAIN,x)
> +
> +/* MIPS32r2 HWREna register */
> +#define mips32_gethwrena()     mips32_get_c0(C0_HWRENA)
> +#define mips32_sethwrena(v)    mips32_set_c0(C0_HWRENA,v)
> +#define mips32_xchhwrena(v)    mips32_xch_c0(C0_HWRENA,v)
> +#define mips32_bichwrena(clr)  mips32_bc_c0(C0_HWRENA,clr)
> +#define mips32_bishwrena(set)  mips32_bs_c0(C0_HWRENA,set)
> +#define mips32_bcshwrena(c,s)  mips32_bcs_c0(C0_HWRENA,c,s)
> +
> +/* MIPS32r2 EBase register */
> +#define mips32_getebase()      mips32_get_c0(C0_EBASE)
> +#define mips32_setebase(x)     mips32_set_c0(C0_EBASE,x)
> +#define mips32_xchebase(x)     mips32_xch_c0(C0_EBASE,x)
> +
> +/* CP0 Status register (NOTE: not atomic operations) */
> +#define mips32_getsr()         mips32_get_c0(C0_SR)
> +#define mips32_setsr(v)                mips32_set_c0(C0_SR,v)
> +#define mips32_xchsr(v)                mips32_xch_c0(C0_SR,v)
> +#define mips32_bicsr(clr)      mips32_bc_c0(C0_SR,clr)
> +#define mips32_bissr(set)      mips32_bs_c0(C0_SR,set)
> +#define mips32_bcssr(c,s)      mips32_bcs_c0(C0_SR,c,s)
> +
> +/* CP0 Cause register (NOTE: not atomic operations) */
> +#define mips32_getcr()         mips32_get_c0(C0_CR)
> +#define mips32_setcr(v)                mips32_set_c0(C0_CR,v)
> +#define mips32_xchcr(v)                mips32_xch_c0(C0_CR,v)
> +#define mips32_biccr(clr)      mips32_bc_c0(C0_CR,clr)
> +#define mips32_biscr(set)      mips32_bs_c0(C0_CR,set)
> +#define mips32_bcscr(c,s)      mips32_bcs_c0(C0_CR,c,s)
> +
> +/* CP0 PrID register */
> +#define mips32_getprid()       mips32_get_c0(C0_PRID)
> +
> +#ifdef C0_COUNT
> +/* CP0 Count register */
> +#define mips32_getcount()      mips32_get_c0(C0_COUNT)
> +#define mips32_setcount(v)     mips32_set_c0(C0_COUNT,v)
> +#define mips32_xchcount(v)     mips32_xch_c0(C0_COUNT,v)
> +#endif
> +
> +#ifdef C0_COMPARE
> +/* CP0 Compare register*/
> +#define mips32_getcompare()    mips32_get_c0(C0_COMPARE)
> +#define mips32_setcompare(v)   mips32_set_c0(C0_COMPARE,v)
> +#define mips32_xchcompare(v)   mips32_xch_c0(C0_COMPARE,v)
> +#endif
> +
> +#ifdef C0_CONFIG
> +/* CP0 Config register */
> +#define mips32_getconfig()     mips32_get_c0(C0_CONFIG)
> +#define mips32_setconfig(v)    mips32_set_c0(C0_CONFIG,v)
> +#define mips32_xchconfig(v)    mips32_xch_c0(C0_CONFIG,v)
> +#define mips32_bicconfig(c)    mips32_bc_c0(C0_CONFIG,c)
> +#define mips32_bisconfig(s)    mips32_bs_c0(C0_CONFIG,s)
> +#define mips32_bcsconfig(c,s)  mips32_bcs_c0(C0_CONFIG,c,s)
> +#endif
> +
> +#ifdef C0_ECC
> +/* CP0 ECC register */
> +#define mips32_getecc()                mips32_get_c0(C0_ECC)
> +#define mips32_setecc(x)       mips32_set_c0(C0_ECC, x)
> +#define mips32_xchecc(x)       mips32_xch_c0(C0_ECC, x)
> +#endif
> +
> +#ifdef C0_TAGHI
> +/* CP0 TagHi register */
> +#define mips32_gettaghi()      mips32_get_c0(C0_TAGHI)
> +#define mips32_settaghi(x)     mips32_set_c0(C0_TAGHI, x)
> +#define mips32_xchtaghi(x)     mips32_xch_c0(C0_TAGHI, x)
> +#endif
> +
> +#ifdef C0_WATCHLO
> +/* CP0 WatchLo register */
> +#define mips32_getwatchlo()    mips32_get_c0(C0_WATCHLO)
> +#define mips32_setwatchlo(x)   mips32_set_c0(C0_WATCHLO, x)
> +#define mips32_xchwatchlo(x)   mips32_xch_c0(C0_WATCHLO, x)
> +#endif
> +
> +#ifdef C0_WATCHHI
> +/* CP0 WatchHi register */
> +#define mips32_getwatchhi()    mips32_get_c0(C0_WATCHHI)
> +#define mips32_setwatchhi(x)   mips32_set_c0(C0_WATCHHI, x)
> +#define mips32_xchwatchhi(x)   mips32_xch_c0(C0_WATCHHI, x)
> +#endif
> +
> +#ifdef C0_USERTRACE1
> +/* PDTRACE usertrace registers */
> +#define mips32_usertrace1(x)   mips32_set_c0(C0_USERTRACE1, x)
> +#define mips32_usertrace2(x)   mips32_set_c0(C0_USERTRACE2, x)
> +#endif
> +
> +/*
> + * Define macros for accessing the MIPS32 coprocessor 0 registers.  Most
> + * apart from "set" return the original register value.  These particular
> + * macros take (reg, sel) as separate paramters, so they can't be used
> with
> + * the coprocessor 0 register names above.
> + */
> +#define _m32c0_mfc0(reg, sel) \
> +__extension__ ({ \
> +  register unsigned long __r; \
> +  __asm__ __volatile ("mfc0 %0,$%1,%2" \
> +                     : "=d" (__r) \
> +                     : "JK" (reg), "JK" (sel)); \
> +  __r; \
> +})
> +
> +#define _m32c0_mtc0(reg, sel, val) \
> +do { \
> +    __asm__ __volatile (".set push \n"\
> +                       ".set noreorder\n"\
> +                       "mtc0 %z0,$%1,%2\n"\
> +                       "ehb\n" \
> +                       ".set pop" \
> +                       : \
> +                       : "dJ" ((reg32_t)(val)), "JK" (reg), "JK" (sel) \
> +                       : "memory"); \
> +} while (0)
> +
> +#define _m32c0_mxc0(reg, sel, val) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _m32c0_mfc0 (reg, sel); \
> +    _m32c0_mtc0 (reg, sel, val); \
> +    __o; \
> +})
> +
> +#define _m32c0_bcc0(reg, sel, clr) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _m32c0_mfc0 (reg, sel); \
> +    _m32c0_mtc0 (reg, sel, __o & ~(clr)); \
> +    __o; \
> +})
> +
> +#define _m32c0_bsc0(reg, sel, set) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _m32c0_mfc0 (reg, sel); \
> +    _m32c0_mtc0 (reg, sel, __o | (set)); \
> +    __o; \
> +})
> +
> +#define _m32c0_bcsc0(reg, sel, clr, set) \
> +__extension__ ({ \
> +    register reg32_t __o; \
> +    __o = _m32c0_mfc0 (reg, sel); \
> +    _m32c0_mtc0 (reg, sel, (__o & ~(clr)) | (set)); \
> +    __o; \
> +})
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +/* Define MIPS32 user-level intrinsics */
> +#include <mips/mips32.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/* CP0 intrinsics */
> +
> +/* MIPS32r2 atomic interrupt disable */
> +#define _mips_intdisable() __extension__({ \
> +    unsigned int __v; \
> +    __asm__ __volatile__ ("di %0; ehb" : "=d" (__v)); \
> +    __v; \
> +})
> +
> +/* MIPS32r2 atomic interrupt disable */
> +#define _mips_intenable() __extension__({ \
> +    unsigned int __v; \
> +    __asm__ __volatile__ ("ei %0; ehb" : "=d" (__v)); \
> +    __v; \
> +})
> +
> +/* MIPS32r2 atomic interrupt restore */
> +#define _mips_intrestore(x) \
> +    mips_setsr (x)
> +
> +/* MIPS32r2 set SRSCtl.PSS (previous shadow set), returning old value */
> +extern unsigned int _mips32r2_xchsrspss (unsigned int);
> +
> +/* MIPS32r2 write previous gpr */
> +#define _mips32r2_wrpgpr(regno, val) \
> +do { \
> +    __asm __volatile ("wrpgpr $%0,%z1" \
> +                     : /* no outputs */ \
> +                     : "JK" (regno), "dJ" (val)); \
> +} while (0)
> +
> +/* MIPS32r2 read previous gpr */
> +#define _mips32r2_rdpgpr(regno) \
> +__extension__({ \
> +    reg_t __val; \
> +    __asm __volatile ("rdpgpr %0,$%1" \
> +                     : "=d" (__val) \
> +                     : "JK" (regno)); \
> +    __val; \
> +})
> +
> +#endif /* __ASSEMBLER__ */
> +
> +/* MIPS32 PREF instruction hint codes */
> +#define PREF_LOAD              0
> +#define PREF_STORE             1
> +#define PREF_LOAD_STREAMED     4
> +#define PREF_STORE_STREAMED    5
> +#define PREF_LOAD_RETAINED     6
> +#define PREF_STORE_RETAINED    7
> +#define PREF_WRITEBACK_INVAL   25
> +#define PREF_PREPAREFORSTORE   30
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +#endif /* _M32C0_H_ */
> diff --git a/libgloss/mips/include/mips/m32c1.h
> b/libgloss/mips/include/mips/m32c1.h
> new file mode 100644
> index 000000000..e33837c2b
> --- /dev/null
> +++ b/libgloss/mips/include/mips/m32c1.h
> @@ -0,0 +1,276 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _M32C1_H_
> +#define _M32C1_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef __ASSEMBLER__
> +
> +unsigned fpa_getrid(void);     /* get fpa revision id */
> +unsigned fpa_getsr(void);      /* get fpa status register */
> +void    fpa_setsr(unsigned);
> +unsigned fpa_xchsr(unsigned);
> +unsigned fpa_bicsr(unsigned);
> +unsigned fpa_bissr(unsigned);
> +
> +unsigned msa_getmir(void);     /* get msa revision id */
> +unsigned msa_getsr(void);      /* get msa status register */
> +void    msa_setsr(unsigned);
> +unsigned msa_xchsr(unsigned);
> +unsigned msa_bicsr(unsigned);
> +unsigned msa_bissr(unsigned);
> +
> +/*
> + * Define macros to accessing the Coprocessor 1 control registers.
> + * Most apart from "set" return the original register value.
> + */
> +
> +#define fpa_getrid() \
> +__extension__({ \
> +  register unsigned __r; \
> +  __asm__ __volatile ("cfc1 %0,$0" : "=d" (__r)); \
> +  __r; \
> +})
> +
> +#define fpa_getfir() fpa_getrid()
> +
> +#define fpa_getsr() \
> +__extension__({ \
> +  register unsigned __r; \
> +  __asm__ __volatile ("cfc1 %0,$31" : "=d" (__r)); \
> +  __r; \
> +})
> +
> +#define fpa_setsr(val) \
> +__extension__({ \
> +    register unsigned __r = (val); \
> +    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__r)); \
> +    __r; \
> +})
> +
> +#define fpa_xchsr(val) \
> +__extension__({ \
> +    register unsigned __o, __n = (val); \
> +    __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \
> +    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \
> +    __o; \
> +})
> +
> +#define fpa_bissr(val) \
> +__extension__({ \
> +    register unsigned __o, __n; \
> +    __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \
> +    __n = __o | (val); \
> +    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \
> +    __o; \
> +})
> +
> +#define fpa_bicsr(val) \
> +__extension__({ \
> +    register unsigned __o, __n; \
> +    __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \
> +    __n = __o &~ (val); \
> +    __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \
> +    __o; \
> +})
> +
> +
> +#define msa_getmir() \
> +__extension__({ \
> +  register unsigned __r; \
> +  __asm__ __volatile (".set push\n" \
> +                     ".set fp=64\n" \
> +                     ".set msa\n" \
> +                     "cfcmsa %0,$0\n" \
> +                     ".set pop": "=d" (__r)); \
> +  __r; \
> +})
> +
> +#define msa_getsr() \
> +__extension__({ \
> +  register unsigned __r; \
> +  __asm__ __volatile (".set push\n" \
> +                     ".set fp=64\n" \
> +                     ".set msa\n" \
> +                     "cfcmsa %0,$1\n" \
> +                     ".set pop": "=d" (__r)); \
> +  __r; \
> +})
> +
> +#define msa_setsr(val) \
> +__extension__({ \
> +    register unsigned __r = (val); \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "ctcmsa $1,%0\n" \
> +                       ".set pop": : "d" (__r)); \
> +    __r; \
> +})
> +
> +#define msa_xchsr(val) \
> +__extension__({ \
> +    register unsigned __o, __n = (val); \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "cfcmsa %0,$1\n" \
> +                       ".set pop": "=d" (__o)); \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "ctcmsa $1,%0\n" \
> +                       ".set pop": : "d" (__n)); \
> +    __o; \
> +})
> +
> +#define msa_bissr(val) \
> +__extension__({ \
> +    register unsigned __o, __n; \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "cfcmsa %0,$1\n" \
> +                       ".set pop": "=d" (__o)); \
> +    __n = __o | (val); \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "ctcmsa $1,%0\n" \
> +                       ".set pop": : "d" (__n)); \
> +    __o; \
> +})
> +
> +#define msa_bicsr(val) \
> +__extension__({ \
> +    register unsigned __o, __n; \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "cfcmsa %0,$1\n" \
> +                       ".set pop": "=d" (__o)); \
> +    __n = __o &~ (val); \
> +    __asm__ __volatile (".set push\n" \
> +                       ".set fp=64\n" \
> +                       ".set msa\n" \
> +                       "ctcmsa $1,%0\n" \
> +                       ".set pop": : "d" (__n)); \
> +    __o; \
> +})
> +
> +#endif /* !ASSEMBLER */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +/*
> + * FCSR - FPU Control & Status Register
> + */
> +#define FPA_CSR_MD0    0x00200000      /* machine dependent */
> +#define FPA_CSR_MD1    0x00400000      /* machine dependent */
> +#define FPA_CSR_COND   0x00800000      /* $fcc0 */
> +#define FPA_CSR_COND0  0x00800000      /* $fcc0 */
> +#define FPA_CSR_FLUSH  0x01000000      /* flush to 0 */
> +#define FPA_CSR_FS     0x01000000      /* flush to 0 */
> +#define FPA_CSR_COND1  0x02000000      /* $fcc1 */
> +#define FPA_CSR_COND2  0x04000000      /* $fcc2 */
> +#define FPA_CSR_COND3  0x08000000      /* $fcc3 */
> +#define FPA_CSR_COND4  0x10000000      /* $fcc4 */
> +#define FPA_CSR_COND5  0x20000000      /* $fcc5 */
> +#define FPA_CSR_COND6  0x40000000      /* $fcc6 */
> +#define FPA_CSR_COND7  0x80000000      /* $fcc7 */
> +
> +/*
> + * X the exception cause indicator
> + * E the exception enable
> + * S the sticky/flag bit
> +*/
> +#define FPA_CSR_ALL_X 0x0003f000
> +#define FPA_CSR_UNI_X  0x00020000
> +#define FPA_CSR_INV_X  0x00010000
> +#define FPA_CSR_DIV_X  0x00008000
> +#define FPA_CSR_OVF_X  0x00004000
> +#define FPA_CSR_UDF_X  0x00002000
> +#define FPA_CSR_INE_X  0x00001000
> +
> +#define FPA_CSR_ALL_E  0x00000f80
> +#define FPA_CSR_INV_E  0x00000800
> +#define FPA_CSR_DIV_E  0x00000400
> +#define FPA_CSR_OVF_E  0x00000200
> +#define FPA_CSR_UDF_E  0x00000100
> +#define FPA_CSR_INE_E  0x00000080
> +
> +#define FPA_CSR_ALL_S  0x0000007c
> +#define FPA_CSR_INV_S  0x00000040
> +#define FPA_CSR_DIV_S  0x00000020
> +#define FPA_CSR_OVF_S  0x00000010
> +#define FPA_CSR_UDF_S  0x00000008
> +#define FPA_CSR_INE_S  0x00000004
> +
> +/* rounding mode */
> +#define FPA_CSR_RN     0x0     /* nearest */
> +#define FPA_CSR_RZ     0x1     /* towards zero */
> +#define FPA_CSR_RU     0x2     /* towards +Infinity */
> +#define FPA_CSR_RD     0x3     /* towards -Infinity */
> +
> +/* FPU Implementation Register */
> +#define FPA_FIR_F64    0x00400000      /* implements 64-bits registers */
> +#define FPA_FIR_L      0x00200000      /* implements long fixed point */
> +#define FPA_FIR_W      0x00100000      /* implements word fixed point */
> +#define FPA_FIR_3D     0x00080000      /* implements MIPS-3D ASE */
> +#define FPA_FIR_PS     0x00040000      /* implements paired-single format
> */
> +#define FPA_FIR_D      0x00020000      /* implements double format */
> +#define FPA_FIR_S      0x00010000      /* implements single format */
> +#define FPA_FIR_PRID   0x0000ff00      /* ProcessorID */
> +#define FPA_FIR_REV    0x000000ff      /* Revision */
> +
> +#ifdef __ASSEMBLER__
> +
> +       .previous
> +
> +/* control regs */
> +       $fir =          $0
> +       $fccr =         $25
> +       $fexr =         $26
> +       $fenr =         $28
> +       $fcsr  =        $31
> +
> +/* backwards compat */
> +       $fpa_rid =      $0
> +       $fpa_sr  =      $31
> +#endif
> +
> +
> +#endif /*_M32C1_H_*/
> diff --git a/libgloss/mips/include/mips/m32tlb.h
> b/libgloss/mips/include/mips/m32tlb.h
> new file mode 100644
> index 000000000..0abd99dde
> --- /dev/null
> +++ b/libgloss/mips/include/mips/m32tlb.h
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> + /*
> +  * m32tlb.h: MIPS32 TLB support functions
> +  */
> +
> +#ifndef _M32TLB_H_
> +#define _M32TLB_H_
> +
> +#if __mips != 32 && __mips != 64
> +#error use -mips32 or -mips64 option with this file
> +#endif
> +
> +#include <mips/notlb.h>
> +#ifndef __ASSEMBLER__
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifdef __mips16
> +# define _MIPS_M32TLB_NOMIPS16 __attribute__((nomips16))
> +#else
> +# define _MIPS_M32TLB_NOMIPS16
> +#endif
> +
> +typedef unsigned int tlbhi_t;
> +typedef unsigned int tlblo_t;
> +
> +// Returns the size of the TLB.
> +_MIPS_M32TLB_NOMIPS16
> +int mips_tlb_size (void);
> + // Probes the TLB for an entry matching hi, and if present invalidates
> it.
> +_MIPS_M32TLB_NOMIPS16
> +void mips_tlbinval (tlbhi_t hi);
> +
> +// Invalidate the whole TLB.
> +_MIPS_M32TLB_NOMIPS16
> +void mips_tlbinvalall (void);
> +
> +// Reads the TLB entry with specified by index, and returns the EntryHi,
> +// EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmsk
> +// respectively.
> +_MIPS_M32TLB_NOMIPS16
> +void mips_tlbri2 (tlbhi_t *phi, tlblo_t *plo0, tlblo_t *plo1, unsigned
> *pmsk,
> +                 int index);
> +
> +// Writes hi, lo0, lo1 and msk into the TLB entry specified by index.
> +_MIPS_M32TLB_NOMIPS16
> +void mips_tlbwi2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk,
> +                 int index);
> +
> +// Writes hi, lo0, lo1 and msk into the TLB entry specified by the
> +// Random register.
> +_MIPS_M32TLB_NOMIPS16
> +void mips_tlbwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk);
> +
> +// Probes the TLB for an entry matching hi and returns its index, or -1 if
> +// not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of
> the
> +// entry are also returned in *plo0, *plo1 and *pmsk respectively
> +_MIPS_M32TLB_NOMIPS16
> +int mips_tlbprobe2 (tlbhi_t hi, tlblo_t *plo0, tlblo_t *plo1, unsigned
> *pmsk);
> +
> +// Probes the TLB for an entry matching hi and if present rewrites that
> entry,
> +// otherwise updates a random entry. A safe way to update the TLB.
> +_MIPS_M32TLB_NOMIPS16
> +int mips_tlbrwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#endif /* _M32TLB_H_ */
> diff --git a/libgloss/mips/include/mips/m64c0.h
> b/libgloss/mips/include/mips/m64c0.h
> new file mode 100644
> index 000000000..2fc0203ea
> --- /dev/null
> +++ b/libgloss/mips/include/mips/m64c0.h
> @@ -0,0 +1,268 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _M64C0_H_
> +#define _M64C0_H_
> +
> +/* Superset of MIPS32 */
> +#include <mips/m32c0.h>
> +
> +#ifndef __ASSEMBLER__
> +typedef union {
> +  unsigned long long ll;
> +  struct {
> +#if defined(_MIPSEB) || defined(MIPSEB)
> +    unsigned int hi;
> +    unsigned int lo;
> +#else
> +    unsigned int lo;
> +    unsigned int hi;
> +#endif
> +  } s;
> +} __ll_shape_type;
> +#endif
> +
> +/*
> + * Define macros for accessing the MIPS coprocessor 0 registers which are
> + * 64 bits wide.
> + * Most apart from "set" return the original register value.
> + */
> +
> +#if (_MIPS_SIM == _ABIO32)
> +#define mips64_get_c0(selreg) \
> +__extension__ ({ \
> +  __ll_shape_type __r; \
> +  __asm__ __volatile ("mfc0 %0,$%2,%3\n" \
> +                     ".set  push\n"\
> +                     ".set  xpa\n"\
> +                     "mfhc0 %1,$%2,%3\n" \
> +                     ".set  pop\n" \
> +                     : "=r" (__r.s.lo), \
> +                       "=r" (__r.s.hi) \
> +                     : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \
> +  __r.ll; \
> +})
> +#else  /* _MIPS_SIM==N32 || _MIPS_SIM==N64 */
> +#define mips64_get_c0(selreg) \
> +__extension__ ({ \
> +  register unsigned long __r; \
> +  __asm__ __volatile ("dmfc0 %0,$%1,%2" \
> +                     : "=d" (__r) \
> +                     : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \
> +  __r; \
> +})
> +#endif
> +
> +#undef EHB
> +#if defined (__MIPS_NO_IMPLICIT_EHB)
> +#define EHB    ""
> +#else
> +#define EHB    "ehb\n"
> +#endif
> +
> +#if (_MIPS_SIM == _ABIO32)
> +#define mips64_set_c0(selreg, val) \
> +do { \
> +    __ll_shape_type __ll; \
> +    __ll.ll = (val); \
> +    __asm__ __volatile (".set push \n"\
> +                       ".set noreorder\n"\
> +                       "mtc0 %z0,$%2,%3\n"\
> +                       ".set  xpa\n"\
> +                       "mthc0 %z1,$%2,%3\n"\
> +                       EHB \
> +                       ".set pop" \
> +                       : \
> +                       : "dJ" ((reg32_t)(__ll.s.lo)),\
> +                         "dJ" ((reg32_t)(__ll.s.hi)),\
> +                         "JK" (selreg & 0x1F),\
> +                         "JK" (selreg >> 8)\
> +                       : "memory"); \
> +} while (0)
> +#else  /* _MIPS_SIM==N32 || _MIPS_SIM==N64 */
> +#define mips64_set_c0(selreg, val) \
> +do { \
> +    __asm__ __volatile (".set push \n"\
> +                       ".set noreorder\n"\
> +                       "dmtc0 %z0,$%1,%2\n"\
> +                       EHB \
> +                       ".set pop" \
> +                       : \
> +                       : "dJ" ((reg64_t)(val)), "JK" (selreg & 0x1F),\
> +                         "JK" (selreg >> 8) \
> +                       : "memory"); \
> +} while (0)
> +#endif
> +
> +#define mips64_xch_c0(selreg, val) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = mips64_get_c0 (selreg); \
> +    mips64_set_c0 (selreg, val); \
> +    __o; \
> +})
> +
> +#define mips64_bc_c0(selreg, clr) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = mips64_get_c0 (selreg); \
> +    mips64_set_c0 (selreg, __o & ~(clr)); \
> +    __o; \
> +})
> +
> +#define mips64_bs_c0(selreg, set) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = mips64_get_c0 (selreg); \
> +    mips64_set_c0 (selreg, __o | (set)); \
> +    __o; \
> +})
> +
> +#define mips64_bcs_c0(selreg, clr, set) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = mips64_get_c0 (selreg); \
> +    mips64_set_c0 (selreg, (__o & ~(clr)) | (set)); \
> +    __o; \
> +})
> +
> +/* MIPS64 Entry*, Index, PageMask registers */
> +#define mips64_setentryhi(x)   mips64_set_c0(C0_ENTRYHI,x)
> +#define mips64_getentryhi()    mips64_get_c0(C0_ENTRYHI)
> +#define mips64_setentrylo0(x)  mips64_set_c0(C0_ENTRYLO0,x)
> +#define mips64_getentrylo0()   mips64_get_c0(C0_ENTRYLO0)
> +#define mips64_setentrylo1(x)  mips64_set_c0(C0_ENTRYLO1,x)
> +#define mips64_getentrylo1()   mips64_get_c0(C0_ENTRYLO1)
> +#define mips64_setpagemask(x)  mips64_set_c0(C0_PAGEMASK,x)
> +#define mips64_getpagemask()   mips64_get_c0(C0_PAGEMASK)
> +#define mips64_setindex(x)     mips32_set_c0(C0_INDEX,x)
> +#define mips64_getindex(x)     mips32_get_c0(C0_INDEX)
> +
> +/* MIPS64 Config3 and Config4 registers */
> +#define mips64_getconfig3()    mips32_get_c0(C0_CONFIG3)
> +#define mips64_setconfig3(x)   mips32_set_c0(C0_CONFIG3,x)
> +#define mips64_getconfig4()    mips32_get_c0(C0_CONFIG4)
> +#define mips64_setconfig4(x)   mips32_set_c0(C0_CONFIG4,x)
> +
> +/* MIPS64 TagLo register */
> +#define mips64_getitaglo()     mips64_get_c0(C0_TAGLO)         /* alias
> define */
> +#define mips64_setitaglo(x)    mips64_set_c0(C0_TAGLO,x)       /* alias
> define */
> +#define mips64_xchitaglo(x)    mips64_xch_c0(C0_TAGLO,x)       /* alias
> define */
> +#define mips64_getdtaglo()     mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 2))
> +#define mips64_setdtaglo(x)    mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 2),x)
> +#define mips64_xchdtaglo(x)    mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 2),x)
> +#define mips64_gettaglo2()     mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 4))
> +#define mips64_settaglo2(x)    mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 4),x)
> +#define mips64_xchtaglo2(x)    mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 4),x)
> +
> +/* MIPS64 DataLo register */
> +#define mips64_getdatalo()     mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 1))
> +#define mips64_setdatalo(x)    mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 1),x)
> +#define mips64_xchdatalo(x)    mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 1),x)
> +#define mips64_getidatalo()    mips64_getdatalo()      /* alias define */
> +#define mips64_setidatalo(x)   mips64_setdatalo(x)     /* alias define */
> +#define mips64_xchidatalo(x)   mips64_xchdatalo(x)     /* alias define */
> +#define mips64_getddatalo()    mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 3))
> +#define mips64_setddatalo(x)   mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 3),x)
> +#define mips64_xchddatalo(x)   mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 3),x)
> +#define mips64_getdatalo2()    mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 5))
> +#define mips64_setdatalo2(x)   mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 5),x)
> +#define mips64_xchdatalo2(x)   mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO,
> 5),x)
> +
> +/* CP0 TagHi register */
> +#define mips64_gettaghi()      mips64_get_c0(C0_TAGHI)
> +#define mips64_settaghi(x)     mips64_set_c0(C0_TAGHI, x)
> +#define mips64_xchtaghi(x)     mips64_xch_c0(C0_TAGHI, x)
> +
> +/* CP0 WatchLo register */
> +#define mips64_getwatchlo()    mips64_get_c0(C0_WATCHLO)
> +#define mips64_setwatchlo(x)   mips64_set_c0(C0_WATCHLO, x)
> +#define mips64_xchwatchlo(x)   mips64_xch_c0(C0_WATCHLO, x)
> +
> +#define _m64c0_mfc0(reg, sel) \
> +__extension__ ({ \
> +  register unsigned long __r; \
> +  __asm__ __volatile ("dmfc0 %0,$%1,%2" \
> +                     : "=d" (__r) \
> +                     : "JK" (reg), "JK" (sel)); \
> +  __r; \
> +})
> +
> +#define _m64c0_mtc0(reg, sel, val) \
> +do { \
> +    __asm__ __volatile (".set push \n"\
> +                       ".set noreorder\n"\
> +                       "dmtc0 %z0,$%1,%2\n"\
> +                       "ehb\n" \
> +                       ".set pop" \
> +                       : \
> +                       : "dJ" ((reg64_t)(val)), "JK" (reg), "JK" (sel) \
> +                       : "memory"); \
> +} while (0)
> +
> +#define _m64c0_mxc0(reg, sel, val) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = _m64c0_mfc0 (reg, sel); \
> +    _m64c0_mtc0 (reg, sel, val); \
> +    __o; \
> +})
> +
> +#define _m64c0_bcc0(reg, sel, clr) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = _m64c0_mfc0 (reg, sel); \
> +    _m64c0_mtc0 (reg, sel, __o & ~(clr)); \
> +    __o; \
> +})
> +
> +#define _m64c0_bsc0(reg, sel, set) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = _m64c0_mfc0 (reg, sel); \
> +    _m64c0_mtc0 (reg, sel, __o | (set)); \
> +    __o; \
> +})
> +
> +#define _m64c0_bcsc0(reg, sel, clr, set) \
> +__extension__ ({ \
> +    register reg64_t __o; \
> +    __o = _m64c0_mfc0 (reg, sel); \
> +    _m64c0_mtc0 (reg, sel, (__o & ~(clr)) | (set)); \
> +    __o; \
> +})
> +
> +/* Define MIPS64 user-level intrinsics */
> +#include <mips/mips64.h>
> +
> +/* MIPS64-specific MMU interface */
> +#include <mips/m64tlb.h>
> +
> +#endif /* _M64C0_H_ */
> diff --git a/libgloss/mips/include/mips/m64tlb.h
> b/libgloss/mips/include/mips/m64tlb.h
> new file mode 100644
> index 000000000..86b0e58aa
> --- /dev/null
> +++ b/libgloss/mips/include/mips/m64tlb.h
> @@ -0,0 +1,106 @@
> +/*
> + * Copyright 2015-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +/*
> + * m64tlb.h: MIPS64 / XPA TLB support functions
> +*/
> +#ifndef _M64TLB_H_
> +#define _M64TLB_H_
> +
> +#if __mips != 32 && __mips != 64
> +#error use -mips32 or -mips64 option with this file
> +#endif
> +
> +#include <mips/notlb.h>
> +
> +#ifndef __ASSEMBLER__
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifdef __mips16
> +# define _MIPS_M64TLB_NOMIPS16 __attribute__((nomips16))
> +#else
> +# define _MIPS_M64TLB_NOMIPS16
> +#endif
> +
> +typedef unsigned long long tlbhi64_t;
> +typedef unsigned long long tlblo64_t;
> +// Returns the size of the TLB.
> +_MIPS_M64TLB_NOMIPS16
> +int m64_tlb_size (void);
> +
> +// Probes the TLB for an entry matching hi, and if present invalidates it.
> +_MIPS_M64TLB_NOMIPS16
> +void m64_tlbinval (tlbhi64_t hi);
> +
> +// Invalidate the whole TLB.
> +_MIPS_M64TLB_NOMIPS16
> +void m64_tlbinvalall (void);
> +
> +// Reads the TLB entry with specified by index, and returns the EntryHi,
> +// EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmsk
> +// respectively.
> +_MIPS_M64TLB_NOMIPS16
> +void m64_tlbri2 (tlbhi64_t *phi, tlblo64_t *plo0, tlblo64_t *plo1,
> +                unsigned long long *pmsk, int index);
> +
> +// Writes hi, lo0, lo1 and msk into the TLB entry specified by index.
> +_MIPS_M64TLB_NOMIPS16
> +void m64_tlbwi2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
> +                unsigned long long msk, int index);
> +
> +// Writes hi, lo0, lo1 and msk into the TLB entry specified by the
> +// Random register.
> +_MIPS_M64TLB_NOMIPS16
> +void m64_tlbwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
> +                unsigned long long msk);
> +
> +// Probes the TLB for an entry matching hi and returns its index, or -1 if
> +// not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of
> the
> +// entry are also returned in *plo0, *plo1 and *pmsk respectively
> +_MIPS_M64TLB_NOMIPS16
> +int m64_tlbprobe2 (tlbhi64_t hi, tlblo64_t *plo0, tlblo64_t *plo1,
> +                  unsigned long long *pmsk);
> +
> +// Probes the TLB for an entry matching hi and if present rewrites that
> entry,
> +// otherwise updates a random entry. A safe way to update the TLB.
> +_MIPS_M64TLB_NOMIPS16
> +int m64_tlbrwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1,
> +                unsigned long long  msk);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#endif /* _M64TLB_H_ */
> diff --git a/libgloss/mips/include/mips/mips32.h
> b/libgloss/mips/include/mips/mips32.h
> new file mode 100644
> index 000000000..20e31a2e7
> --- /dev/null
> +++ b/libgloss/mips/include/mips/mips32.h
> @@ -0,0 +1,177 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS32_H_
> +#define _MIPS32_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef __ASSEMBLER__
> +
> +#if ! __mips16
> +
> +/* C interface to clz/clo instructions */
> +
> +/* count leading zeros */
> +# define mips_clz(x) __builtin_clz (x)
> +
> +/* count trailing zeros */
> +# define mips_ctz(x) __builtin_ctz (x)
> +
> +#define mips_clo(x) __extension__({ \
> +    unsigned int __x = (x); \
> +    unsigned int __v; \
> +    __asm__ ("clo %0,%1" : "=d" (__v) : "d" (__x)); \
> +    __v; \
> +})
> +
> +#ifndef __mips64
> +
> +/* Simulate 64-bit count leading zeroes */
> +#if !defined(mips_dclz)
> +#define mips_dclz(x) __extension__({ \
> +    unsigned long long __x = (x); \
> +    unsigned int __hx = (__x >> 32); \
> +    __hx ? mips_clz(__hx) : 32 + mips_clz(__x); \
> +})
> +#endif
> +
> +/* Simulate 64-bit count leading ones */
> +#if !defined(mips_dclo)
> +#define mips_dclo(x) __extension__({ \
> +    unsigned long long __x = (x); \
> +    unsigned int __hx = (__x >> 32); \
> +    (~__hx) ? mips_clo(__hx) : 32 + mips_clo(__x); \
> +})
> +#endif
> +
> +/* Simulate 64-bit count trailing zeroes */
> +#if !defined(mips_dctz)
> +#define mips_dctz(x) __extension__({ \
> +    unsigned long long __dx = (x); \
> +    unsigned int __ldx = __dx; \
> +    unsigned int __hdx = __dx >> 32; \
> +    __ldx ? mips_ctz(__ldx) : (63 ^ mips_clz(__hdx & -__hdx)); \
> +   })
> +#endif
> +
> +#endif
> +
> +/* MIPS32r2 wsbh opcode */
> +#define _mips32r2_wsbh(x) __extension__({ \
> +    unsigned int __x = (x), __v; \
> +    __asm__ ("wsbh %0,%1" \
> +            : "=d" (__v) \
> +            : "d" (__x)); \
> +    __v; \
> +})
> +
> +/* MIPS32r2 byte-swap word */
> +#define _mips32r2_bswapw(x) __extension__({ \
> +    unsigned int __x = (x), __v; \
> +    __asm__ ("wsbh %0,%1; rotr %0,16" \
> +            : "=d" (__v) \
> +            : "d" (__x)); \
> +    __v; \
> +})
> +
> +/* MIPS32r2 insert bits */
> +#define _mips32r2_ins(tgt,val,pos,sz) __extension__({ \
> +    unsigned int __t = (tgt), __v = (val); \
> +    __asm__ ("ins %0,%z1,%2,%3" \
> +            : "+d" (__t) \
> +            : "dJ" (__v), "I" (pos), "I" (sz)); \
> +    __t; \
> +})
> +
> +/* MIPS32r2 extract bits */
> +#define _mips32r2_ext(x,pos,sz) __extension__({ \
> +    unsigned int __x = (x), __v; \
> +    __asm__ ("ext %0,%z1,%2,%3" \
> +            : "=d" (__v) \
> +            : "dJ" (__x), "I" (pos), "I" (sz)); \
> +    __v; \
> +})
> +
> +#if __mips_isa_rev < 6
> +
> +/* MIPS32r2 jr.hb */
> +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
> +#define mips32_jr_hb() __asm__ __volatile__(   \
> +       "bltzal $0,0f\n"                        \
> +"0:     addiu  $31,1f-0b\n"                    \
> +"       jr.hb  $31\n"                          \
> +"1:"                                           \
> +       : : : "$31")
> +#elif _MIPS_SIM == _ABI64
> +#define mips32_jr_hb() __asm__ __volatile__(   \
> +       "bltzal $0,0f\n"                        \
> +"0:     daddiu $31,1f-0b\n"                    \
> +"       jr.hb  $31\n"                          \
> +"1:"                                           \
> +       : : : "$31")
> +#else
> +#error Unknown ABI
> +#endif
> +
> +#else /*  __mips_isa_rev < 6  */
> +
> +/* MIP32r6 jr.hb */
> +#if _MIPS_SIM == _ABIO32 ||  _MIPS_SIM == _ABIN32
> +#define mips32_jr_hb() __asm__ __volatile__(   \
> +       "auipc  $24,%pcrel_hi(1f)\n"            \
> +       "addiu  $24,%pcrel_lo(1f + 4)\n"        \
> +       "jr.hb  $24\n"                          \
> +"1:"                                           \
> +       : : : "$24")
> +#elif _MIPS_SIM == _ABI64
> +#define mips32_jr_hb() __asm__ __volatile__(   \
> +       "auipc  $24,%pcrel_hi(1f)\n"            \
> +       "daddiu $24,%pcrel_lo(1f + 4)\n"        \
> +       "jr.hb  $24\n"                          \
> +"1:"                                           \
> +       : : : "$24")
> +#else
> +#error Unknown ABI
> +#endif
> +
> +#endif /* __mips_isa_rev < 6 */
> +
> +#endif /* ! __mips16 */
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _MIPS32_H_ */
> diff --git a/libgloss/mips/include/mips/mips64.h
> b/libgloss/mips/include/mips/mips64.h
> new file mode 100644
> index 000000000..03b608e2e
> --- /dev/null
> +++ b/libgloss/mips/include/mips/mips64.h
> @@ -0,0 +1,116 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS64_H_
> +#define _MIPS64_H_
> +
> +#include <mips/mips32.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef __ASSEMBLER__
> +
> +#if __mips == 64 && ! __mips16
> +
> +/* 64-bit count leading zeroes */
> +#if !defined(mips_dclz)
> +# define mips_dclz(x) __builtin_clzll (x)
> +#endif
> +
> +/* 64-bit count trailing zeroes */
> +#if !defined(mips_dctz)
> +# define mips_dctz(x) __builtin_ctzll (x)
> +#endif
> +
> +#if !defined(mips_dclo)
> +#define mips_dclo(x) __extension__({ \
> +    unsigned long long __x = (x); \
> +    unsigned int __v; \
> +    __asm__ ("dclo %0,%1" : "=d" (__v) : "d" (__x)); \
> +    __v; \
> +})
> +#endif
> +
> +/* MIPS64r2 dshd opcode */
> +#define _mips64r2_dshd(x) __extension__({ \
> +    unsigned long long __x = (x), __v; \
> +    __asm__ ("dshd %0,%1" \
> +            : "=d" (__v) \
> +            : "d" (__x)); \
> +    __v; \
> +})
> +
> +/* MIPS64r2 dsbh opcode */
> +#define _mips64r2_dsbh(x) __extension__({ \
> +    unsigned long long __x = (x), __v; \
> +    __asm__ ("dsbh %0,%1" \
> +            : "=d" (__v) \
> +            : "d" (__x)); \
> +    __v; \
> +})
> +
> +/* MIPS64r2 byte-swap doubleword */
> +#define _mips64r2_bswapd(x) __extension__({ \
> +    unsigned long long __x = (x), __v; \
> +    __asm__ ("dsbh %0,%1; dshd %0,%0" \
> +            : "=d" (__v) \
> +            : "d" (__x)); \
> +    __v; \
> +})
> +
> +/* MIPS64r2 insert bits */
> +#define _mips64r2_dins(tgt,val,pos,sz) __extension__({ \
> +    unsigned long long __t = (tgt), __v = (val); \
> +    __asm__ ("dins %0,%z1,%2,%3" \
> +            : "+d" (__t) \
> +            : "dJ" (__v), "I" (pos), "I" (sz)); \
> +    __t; \
> +})
> +
> +/* MIPS64r2 extract bits */
> +#define _mips64r2_dext(x,pos,sz) __extension__({ \
> +    unsigned long long __x = (x), __v; \
> +    __asm__ ("dext %0,%z1,%2,%3" \
> +            : "=d" (__v) \
> +            : "dJ" (__x), "I" (pos), "I" (sz)); \
> +    __v; \
> +})
> +
> +#endif /* __mips == 64 && ! __mips16 */
> +
> +#endif /* !__ASSEMBLER__ */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _MIPS64_H_ */
> diff --git a/libgloss/mips/include/mips/mt.h
> b/libgloss/mips/include/mips/mt.h
> new file mode 100644
> index 000000000..91a75f28c
> --- /dev/null
> +++ b/libgloss/mips/include/mips/mt.h
> @@ -0,0 +1,521 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_MT_H_
> +#define _MIPS_MT_H_
> +
> +#include <mips/m32c0.h>
> +#include <mips/mips32.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/*
> + * MIPS32 MVPControl Register (CP0 Register 0, Select 1)
> + */
> +#define MVPCONTROL_EVP         0x00000001  /* Enable Virtual Processors */
> +#define MVPCONTROL_VPC         0x00000002  /* VPE Configuration State */
> +#define MVPCONTROL_STLB                0x00000004  /* Share TLBS */
> +#define MVPCONTROL_CPA         0x00000008  /* Cache Partitioning Active */
> +
> +/*
> + * MIPS32 MVPConf0 Register (CP0 Register 0, Select 2)
> + */
> +#define MVPCONF0_PTC           0x000000ff
> +#define  MVPCONF0_PTC_SHIFT             0
> +#define MVPCONF0_PVPE          0x00003c00
> +#define  MVPCONF0_PVPE_SHIFT           10
> +#define MVPCONF0_TCA           0x00008000
> +#define MVPCONF0_PTLBE         0x03ff0000
> +#define  MVPCONF0_PTLBE_SHIFT          16
> +#define MVPCONF0_TLBS          0x20000000
> +#define MVPCONF0_M             0x80000000
> +
> +/*
> + * MIPS32 MVPConf1 Register (CP0 Register 0, Select 3)
> + */
> +#define MVPCONF1_PCP1          0x000000ff
> +#define  MVPCONF1_PCP1_SHIFT            0
> +#define MVPCONF1_PCP2          0x0003fc00
> +#define  MVPCONF1_PCP2_SHIFT           10
> +#define MVPCONF1_PCX           0x0ff00000
> +#define  MVPCONF1_PCX_SHIFT            20
> +#define MVPCONF1_C1F           0x40000000
> +#define MVPCONF1_C1M           0x80000000
> +
> +/*
> + * MIPS32 VPEControl Register (CP0 Register 1, Select 1)
> + */
> +#define VPECONTROL_TARGTC      0x000000ff
> +#define  VPECONTROL_TARGTC_SHIFT        0
> +#define VPECONTROL_TARGVPE     0x00003c00
> +#define  VPECONTROL_TARGVPE_SHIFT      10
> +#define VPECONTROL_TE          0x00008000
> +#define VPECONTROL_EXCPT       0x00070000
> +#define  VPECONTROL_EXCPT_SHIFT                16
> +#define VPECONTROL_GSI         0x00100000
> +#define VPECONTROL_YSI         0x00200000
> +
> +/*
> + * MIPS32 VPEConf0 Register (CP0 Register 1, Select 2)
> + */
> +#define VPECONF0_VPA           0x00000001
> +#define VPECONF0_MVP           0x00000002
> +#define VPECONF0_XTC           0x1fe00000
> +#define VPECONF0_XTC_SHIFT             21
> +#define VPECONF0_M             0x80000000
> +
> +/*
> + * MIPS32 VPEConf1 Register (CP0 Register 1, Select 3)
> + */
> +#define VPECONF1_NCP1          0x000000ff
> +#define  VPECONF1_NCP1_SHIFT            0
> +#define VPECONF1_NCP2          0x0003fc00
> +#define  VPECONF1_NCP2_SHIFT           10
> +#define VPECONF1_NCX           0x0ff00000
> +#define  VPECONF1_NCX_SHIFT            20
> +
> +/*
> + * MIPS32 YQMask Register (CP0 Register 1, Select 4)
> + */
> +#define YQMASK_MASK            0x7fffffff
> +#define  YQMASK_MASK_SHIFT              0
> +
> +/*
> + * MIPS32 VPEOpt Register (CP0 Register 1, Select 7)
> + */
> +#define VPEOPT_DWX0            0x00000001
> +#define VPEOPT_DWX1            0x00000002
> +#define VPEOPT_DWX2            0x00000004
> +#define VPEOPT_DWX3            0x00000008
> +#define VPEOPT_DWX4            0x00000010
> +#define VPEOPT_DWX5            0x00000020
> +#define VPEOPT_DWX6            0x00000040
> +#define VPEOPT_DWX7            0x00000080
> +#define VPEOPT_DWX             0x000000ff
> +#define  VPEOPT_DWX_SHIFT       0
> +#define VPEOPT_IWX0            0x00000100
> +#define VPEOPT_IWX1            0x00000200
> +#define VPEOPT_IWX2            0x00000400
> +#define VPEOPT_IWX3            0x00000800
> +#define VPEOPT_IWX4            0x00001000
> +#define VPEOPT_IWX5            0x00002000
> +#define VPEOPT_IWX6            0x00004000
> +#define VPEOPT_IWX7            0x00008000
> +#define VPEOPT_IWX             0x0000ff00
> +#define  VPEOPT_IWX_SHIFT       8
> +
> +/*
> + * MIPS32 TCStatus Register (CP0 Register 2, Select 1)
> + */
> +#define TCSTATUS_TASID         0x000000ff
> +#define  TCSTATUS_TASID_SHIFT           0
> +#define TCSTATUS_IXMT          0x00000400
> +#define TCSTATUS_TKSU          0x00001800
> +#define  TCSTATUS_TKSU_SHIFT           11
> +#define TCSTATUS_A             0x00002000
> +#define TCSTATUS_DA            0x00008000
> +#define TCSTATUS_IMPL          0x000f0000
> +#define  TCSTATUS_IMPL_SHIFT           16
> +#define TCSTATUS_DT            0x00100000
> +#define TCSTATUS_TDS           0x00200000
> +#define TCSTATUS_TSST          0x00400000
> +#define TCSTATUS_RNST          0x01800000
> +#define  TCSTATUS_RNST_SHIFT           23
> +#define TCSTATUS_TCU0          0x10000000
> +#define TCSTATUS_TCU1          0x20000000
> +#define TCSTATUS_TCU2          0x40000000
> +#define TCSTATUS_TCU3          0x80000000
> +
> +/*
> + * MIPS32 TCBind Register (CP0 Register 2, Select 2)
> + */
> +#define TCBIND_CURVPE          0x0000000f
> +#define  TCBIND_CURVPE_SHIFT            0
> +#define TCBIND_CURTC           0x1fe00000
> +#define  TCBIND_CURTC_SHIFT            21
> +
> +/*
> + * MIPS32 TCHalt Register (CP0 Register 2, Select 4)
> + */
> +#define TCHALT_H               0x00000001
> +
> +/*
> + * MIPS32 SRSConf0 Register (CP0 Register 6, Select 1)
> + */
> +#define SRSCONF0_SRS1          0x000003ff
> +#define  SRSCONF0_SRS1_SHIFT            0
> +#define SRSCONF0_SRS2          0x000ffc00
> +#define  SRSCONF0_SRS2_SHIFT           10
> +#define SRSCONF0_SRS3          0x3ff00000
> +#define  SRSCONF0_SRS3_SHIFT           20
> +#define SRSCONF0_M             0x80000000
> +
> +/*
> + * MIPS32 SRSConf1 Register (CP0 Register 6, Select 2)
> + */
> +#define SRSCONF1_SRS4          0x000003ff
> +#define  SRSCONF1_SRS4_SHIFT            0
> +#define SRSCONF1_SRS5          0x000ffc00
> +#define  SRSCONF1_SRS5_SHIFT           10
> +#define SRSCONF1_SRS6          0x3ff00000
> +#define  SRSCONF1_SRS6_SHIFT           20
> +#define SRSCONF1_M             0x80000000
> +
> +/*
> + * MIPS32 SRSConf2 Register (CP0 Register 6, Select 3)
> + */
> +#define SRSCONF2_SRS7          0x000003ff
> +#define  SRSCONF2_SRS7_SHIFT            0
> +#define SRSCONF2_SRS8          0x000ffc00
> +#define  SRSCONF2_SRS8_SHIFT           10
> +#define SRSCONF2_SRS9          0x3ff00000
> +#define  SRSCONF2_SRS9_SHIFT           20
> +#define SRSCONF2_M             0x80000000
> +
> +/*
> + * MIPS32 SRSConf3 Register (CP0 Register 6, Select 4)
> + */
> +#define SRSCONF3_SRS10         0x000003ff
> +#define  SRSCONF3_SRS10_SHIFT           0
> +#define SRSCONF3_SRS11         0x000ffc00
> +#define  SRSCONF3_SRS11_SHIFT          10
> +#define SRSCONF3_SRS12         0x3ff00000
> +#define  SRSCONF3_SRS12_SHIFT          20
> +#define SRSCONF3_M             0x80000000
> +
> +/*
> + * MIPS32 SRSConf4 Register (CP0 Register 6, Select 5)
> + */
> +#define SRSCONF4_SRS13         0x000003ff
> +#define  SRSCONF4_SRS13_SHIFT           0
> +#define SRSCONF4_SRS14         0x000ffc00
> +#define  SRSCONF4_SRS14_SHIFT          10
> +#define SRSCONF4_SRS15         0x3ff00000
> +#define  SRSCONF4_SRS15_SHIFT          20
> +
> +/*
> + * MIPS32 Config3 Register (CP0 Register 16, Select 3)
> + * New fields for MT
> + */
> +#define CFG3_MT                        0x00000004
> +
> +#ifdef __ASSEMBLER__
> +
> +/*
> + * MT Coprocessor 0 register numbers
> + */
> +#define C0_MVPCONTROL         $0,1
> +#define C0_MVPCONF0           $0,2
> +#define C0_MVPCONF1           $0,3
> +#define C0_VPECONTROL         $1,1
> +#define C0_VPECONF0           $1,2
> +#define C0_VPECONF1           $1,3
> +#define C0_YQMASK             $1,4
> +#define C0_VPESCHEDULE        $1,5
> +#define C0_VPESCHEFBACK       $1,6
> +#define C0_VPEOPT            $1,7
> +#define C0_TCSTATUS           $2,1
> +#define C0_TCBIND             $2,2
> +#define C0_TCRESTART          $2,3
> +#define C0_TCHALT             $2,4
> +#define C0_TCCONTEXT          $2,5
> +#define C0_TCSCHEDULE         $2,6
> +#define C0_TCSCHEFBACK        $2,7
> +#define C0_SRSCONF0           $6,1
> +#define C0_SRSCONF1           $6,2
> +#define C0_SRSCONF2           $6,3
> +#define C0_SRSCONF3           $6,4
> +#define C0_SRSCONF4           $6,5
> +
> +#else
> +
> +#define mips32_getmvpcontrol()         _m32c0_mfc0(0,1)
> +#define mips32_setmvpcontrol(x)                _m32c0_mtc0(0,1,x)
> +#define mips32_xchmvpcontrol(x)                _m32c0_mxc0(0,1,x)
> +
> +#define mips32_getmvpconf0()           _m32c0_mfc0(0,2)
> +#define mips32_setmvpconf0(x)          _m32c0_mtc0(0,2,x)
> +#define mips32_xchmvpconf0(x)          _m32c0_mxc0(0,2,x)
> +
> +#define mips32_getmvpconf1()           _m32c0_mfc0(0,3)
> +#define mips32_setmvpconf1(x)          _m32c0_mtc0(0,3,x)
> +#define mips32_xchmvpconf1(x)          _m32c0_mxc0(0,3,x)
> +
> +#define mips32_getvpecontrol()         _m32c0_mfc0(1,1)
> +#define mips32_setvpecontrol(x)                _m32c0_mtc0(1,1,x)
> +#define mips32_xchvpecontrol(x)                _m32c0_mxc0(1,1,x)
> +
> +#define mips32_getvpeconf0()           _m32c0_mfc0(1,2)
> +#define mips32_setvpeconf0(x)          _m32c0_mtc0(1,2,x)
> +#define mips32_xchvpeconf0(x)          _m32c0_mxc0(1,2,x)
> +
> +#define mips32_getvpeconf1()           _m32c0_mfc0(1,3)
> +#define mips32_setvpeconf1(x)          _m32c0_mtc0(1,3,x)
> +#define mips32_xchvpeconf1(x)          _m32c0_mxc0(1,3,x)
> +
> +#define mips32_getyqmask()             _m32c0_mfc0(1,4)
> +#define mips32_setyqmask(x)            _m32c0_mtc0(1,4,x)
> +#define mips32_xchyqmask(x)            _m32c0_mxc0(1,4,x)
> +
> +#define mips32_getvpeschedule()                _m32c0_mfc0(1,5)
> +#define mips32_setvpeschedule(x)       _m32c0_mtc0(1,5,x)
> +#define mips32_xchvpeschedule(x)       _m32c0_mxc0(1,5,x)
> +
> +#define mips32_getvpeschefback()        _m32c0_mfc0(1,6)
> +#define mips32_setvpeschefback(x)       _m32c0_mtc0(1,6,x)
> +#define mips32_xchvpeschefback(x)       _m32c0_mxc0(1,6,x)
> +
> +#define mips32_getvpeopt()             _m32c0_mfc0(1,7)
> +#define mips32_setvpeopt(x)            _m32c0_mtc0(1,7,x)
> +#define mips32_xchvpeopt(x)            _m32c0_mxc0(1,7,x)
> +
> +#define mips32_gettcstatus()           _m32c0_mfc0(2,1)
> +#define mips32_settcstatus(x)          _m32c0_mtc0(2,1,x)
> +#define mips32_xchtcstatus(x)          _m32c0_mxc0(2,1,x)
> +
> +#define mips32_gettcbind()             _m32c0_mfc0(2,2)
> +#define mips32_settcbind(x)            _m32c0_mtc0(2,2,x)
> +#define mips32_xchtcbind(x)            _m32c0_mxc0(2,2,x)
> +
> +#define mips32_gettcrestart()          _m32c0_mfc0(2,3)
> +#define mips32_settcrestart(x)         _m32c0_mtc0(2,3,x)
> +#define mips32_xchtcrestart(x)         _m32c0_mxc0(2,3,x)
> +
> +#define mips32_gettchalt()             _m32c0_mfc0(2,4)
> +#define mips32_settchalt(x)            _m32c0_mtc0(2,4,x)
> +#define mips32_xchtchalt(x)            _m32c0_mxc0(2,4,x)
> +
> +#define mips32_gettccontext()          _m32c0_mfc0(2,5)
> +#define mips32_settccontext(x)         _m32c0_mtc0(2,5,x)
> +#define mips32_xchtccontext(x)         _m32c0_mxc0(2,5,x)
> +
> +#define mips32_gettcschedule()         _m32c0_mfc0(2,6)
> +#define mips32_settcschedule(x)                _m32c0_mtc0(2,6,x)
> +#define mips32_xchtcschedule(x)                _m32c0_mxc0(2,6,x)
> +
> +#define mips32_gettcschefback()                _m32c0_mfc0(2,7)
> +#define mips32_settcschefback(x)        _m32c0_mtc0(2,7,x)
> +#define mips32_xchtcschefback(x)        _m32c0_mxc0(2,7,x)
> +
> +#define mips32_getsrsconf0()           _m32c0_mfc0(6,1)
> +#define mips32_setsrsconf0(x)          _m32c0_mtc0(6,1,x)
> +#define mips32_xchsrsconf0(x)          _m32c0_mxc0(6,1,x)
> +
> +#define mips32_getsrsconf1()           _m32c0_mfc0(6,2)
> +#define mips32_setsrsconf1(x)          _m32c0_mtc0(6,2,x)
> +#define mips32_xchsrsconf1(x)          _m32c0_mxc0(6,2,x)
> +
> +#define mips32_getsrsconf2()           _m32c0_mfc0(6,3)
> +#define mips32_setsrsconf2(x)          _m32c0_mtc0(6,3,x)
> +#define mips32_xchsrsconf2(x)          _m32c0_mxc0(6,3,x)
> +
> +#define mips32_getsrsconf3()           _m32c0_mfc0(6,4)
> +#define mips32_setsrsconf3(x)          _m32c0_mtc0(6,4,x)
> +#define mips32_xchsrsconf3(x)          _m32c0_mxc0(6,4,x)
> +
> +#define mips32_getsrsconf4()           _m32c0_mfc0(6,5)
> +#define mips32_setsrsconf4(x)          _m32c0_mtc0(6,5,x)
> +#define mips32_xchsrsconf4(x)          _m32c0_mxc0(6,5,x)
> +
> +#if !__mips16
> +/* Access to other VPE/TC registers */
> +
> +/* move from gpr */
> +#define _m32c0_mftgpr(rt) \
> +__extension__ ({ \
> +       unsigned long __res; \
> +       __asm__ __volatile__( \
> +               ".set push\n" \
> +               ".set noat\n" \
> +               "mftgpr\t%0,$" #rt "\n" \
> +               ".set pop\n" \
> +               : "=d" (__res)); \
> +       __res; \
> +})
> +
> +/* move to gpr */
> +#define _m32c0_mttgpr(rd,v) \
> +do { \
> +       __asm__ __volatile__( \
> +               ".set push\n" \
> +               ".set noat\n" \
> +               "mttgpr\t%z0,$" #rd "\n" \
> +               ".set pop\n" \
> +               : : "dJ" (v)); \
> +} while (0)
> +
> +/* move from cp0 */
> +#define _m32c0_mftc0(rt,sel) \
> +__extension__ ({ \
> +       unsigned long  __res; \
> +       __asm__ __volatile__( \
> +               "mftc0\t%0,$" #rt "," #sel \
> +               : "=d" (__res)); \
> +       __res; \
> +})
> +
> +/* move to cp0 */
> +#define _m32c0_mttc0(rd,sel,v) \
> +do { \
> +       __asm__ __volatile__( \
> +               "%(mttc0\t %z0,$" #rd "," #sel "; ehb%)" \
> +               : : "dJ" (v)); \
> +} while (0)
> +#endif /* ! __mips16 */
> +
> +/*
> + * targeted VPE register macros
> + */
> +#define mips32_mt_settarget(tc) \
> +       mips32_setvpecontrol ( \
> +               (mips32_getvpecontrol () & ~(VPECONTROL_TARGTC)) \
> +               | ((tc) << VPECONTROL_TARGTC_SHIFT))
> +
> +#define mips32_mt_gettarget() \
> +       ((mips32_getvpecontrol () & (VPECONTROL_TARGTC)) \
> +        >> VPECONTROL_TARGTC_SHIFT)
> +
> +/*
> + * Before using any mips32_mt_ macros you should ensure the
> + * destination VPE and TC are set with a call to mips32_mt_settarget()
> + */
> +
> +/*
> + * Non-MT CP0 registers
> + */
> +#define mips32_mt_getc0status()                _m32c0_mftc0(12, 0)
> +#define mips32_mt_setc0status(val)     _m32c0_mttc0(12, 0, val)
> +#define mips32_mt_getc0cause()         _m32c0_mftc0(13, 0)
> +#define mips32_mt_setc0cause(val)      _m32c0_mttc0(13, 0, val)
> +#define mips32_mt_getc0config()                _m32c0_mftc0(16, 0)
> +#define mips32_mt_setc0config(val)     _m32c0_mttc0(16, 0, val)
> +#define mips32_mt_getc0config1()       _m32c0_mftc0(16, 1)
> +#define mips32_mt_setc0config1(val)    _m32c0_mttc0(16, 1, val)
> +#define mips32_mt_getc0ebase()         _m32c0_mftc0(15, 1)
> +#define mips32_mt_setc0ebase(val)      _m32c0_mttc0(15, 1, val)
> +
> +/*
> + * Non-MT GPR registers
> + */
> +#define mips32_mt_getsp()              _m32c0_mftgpr(29)
> +#define mips32_mt_setsp(val)           _m32c0_mttgpr(29, val)
> +#define mips32_mt_getgp()              _m32c0_mftgpr(28)
> +#define mips32_mt_setgp(val)           _m32c0_mttgpr(28, val)
> +
> +/*
> + * VPE
> + */
> +#define mips32_mt_getvpecontrol()      _m32c0_mftc0(1, 1)
> +#define mips32_mt_setvpecontrol(val)   _m32c0_mttc0(1, 1, val)
> +#define mips32_mt_getvpeconf0()                _m32c0_mftc0(1, 2)
> +#define mips32_mt_setvpeconf0(val)     _m32c0_mttc0(1, 2, val)
> +
> +/*
> + * TC
> + */
> +#define mips32_mt_gettcstatus()        _m32c0_mftc0(2, 1)
> +#define mips32_mt_settcstatus(val)     _m32c0_mttc0(2, 1, val)
> +#define mips32_mt_gettcbind()          _m32c0_mftc0(2, 2)
> +#define mips32_mt_settcbind(val)       _m32c0_mttc0(2, 2, val)
> +#define mips32_mt_gettcrestart()       _m32c0_mftc0(2, 3)
> +#define mips32_mt_settcrestart(val)    _m32c0_mttc0(2, 3, val)
> +#define mips32_mt_gettchalt()          _m32c0_mftc0(2, 4)
> +#define mips32_mt_settchalt(val)       _m32c0_mttc0(2, 4, val)
> +#define mips32_mt_gettccontext()       _m32c0_mftc0(2, 5)
> +#define mips32_mt_settccontext(val)    _m32c0_mttc0(2, 5, val)
> +
> +
> +/*
> + * MT Intrinsics
> + */
> +#define mips_mt_fork(a, pv, cv)                                        \
> +__extension__ ({                                               \
> +    void * __a = (a);                                          \
> +    unsigned int __cv = (cv);                                  \
> +    unsigned int __res = (pv);                                         \
> +    __asm__ __volatile (".set push; .set mt; fork %0,%1,%z2; .set pop" \
> +                       : "+d" (__res)                          \
> +                       : "d" (__a), "dJ" (__cv));              \
> +    __res;                                                     \
> +})
> +
> +#define mips_mt_yield(yq)                                      \
> +__extension__ ({                                               \
> +    unsigned int __yq = (yq);                                  \
> +    unsigned int __res;                                        \
> +    __asm__ __volatile (".set push; .set mt; yield %0,%z1; .set pop" \
> +                       : "=d" (__res)                          \
> +                       : "dJ" (__yq));                         \
> +    __res;                                                     \
> +})
> +
> +#define mips_mt_dmt()                                          \
> +__extension__ ({                                               \
> +    unsigned int __res;                                        \
> +    __asm__ __volatile (".set push; .set mt; dmt %0; .set pop" \
> +                       : "=d" (__res));                        \
> +    mips32_jr_hb();                                            \
> +    __res & VPECONTROL_TE;                                     \
> +})
> +
> +#define mips_mt_emt()                                          \
> +__extension__ ({                                               \
> +    unsigned int __res;                                        \
> +    __asm__ __volatile (".set push; .set mt; emt %0; ehb; .set pop" \
> +                       : "=d" (__res));                        \
> +    __res & VPECONTROL_TE;                                     \
> +})
> +
> +#define mips_mt_dvpe()                                                 \
> +__extension__ ({                                               \
> +    unsigned int __res;                                        \
> +    __asm__ __volatile (".set push; .set mt; dvpe %0; .set pop"        \
> +                       : "=d" (__res));                        \
> +    mips32_jr_hb();                                            \
> +    __res & MVPCONTROL_EVP;                                    \
> +})
> +
> +#define mips_mt_evpe()                                                 \
> +__extension__ ({                                               \
> +    unsigned int __res;                                        \
> +    __asm__ __volatile (".set push; .set mt; evpe %0; ehb; .set pop" \
> +                       : "=d" (__res));                        \
> +    __res & MVPCONTROL_EVP;                                    \
> +})
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _MIPS_MT_H_ */
> diff --git a/libgloss/mips/include/mips/notlb.h
> b/libgloss/mips/include/mips/notlb.h
> new file mode 100644
> index 000000000..2a6c1b439
> --- /dev/null
> +++ b/libgloss/mips/include/mips/notlb.h
> @@ -0,0 +1,115 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _NOTLB_H_
> +#define _NOTLB_H_
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef ROM_BASE
> +#define ROM_BASE       0xbfc00000      /* standard ROM base address */
> +#endif
> +
> +#ifdef __ASSEMBLER__
> +
> +/*
> + * Stub 32-bit memory regions
> + */
> +#define        KSEG0_BASE      0x80000000
> +#define        KSEG1_BASE      0xa0000000
> +#define KSEG0_SIZE     0x20000000
> +#define KSEG1_SIZE     0x20000000
> +#define RVEC_BASE      ROM_BASE
> +
> +/*
> + * Translate a kernel address in KSEG0 or KSEG1 to a real
> + * physical address and back.
> + */
> +#define KVA_TO_PA(v)   ((v) & 0x1fffffff)
> +#define PA_TO_KVA0(pa) ((pa) | 0x80000000)
> +#define PA_TO_KVA1(pa) ((pa) | 0xa0000000)
> +
> +/* translate between KSEG0 and KSEG1 addresses */
> +#define KVA0_TO_KVA1(v)        ((v) | 0x20000000)
> +#define KVA1_TO_KVA0(v)        ((v) & ~0x20000000)
> +
> +#else /* __ASSEMBLER__ */
> +/*
> + * Standard address types
> + */
> +#ifndef _PADDR_T_DEFINED_
> +typedef unsigned long          paddr_t;        /* a physical address */
> +#define _PADDR_T_DEFINED_
> +#endif
> +#ifndef _VADDR_T_DEFINED_
> +typedef unsigned long          vaddr_t;        /* a virtual address */
> +#define _VADDR_T_DEFINED_
> +#endif
> +
> +/*
> + * Stub 32-bit memory regions
> + */
> +#define KSEG0_BASE     ((void  *)0x80000000)
> +#define KSEG1_BASE     ((void  *)0xa0000000)
> +#define KSEG0_SIZE     0x20000000u
> +#define KSEG1_SIZE     0x20000000u
> +
> +#define RVEC_BASE      ((void *)ROM_BASE)      /* reset vector base */
> +
> +/*
> + * Translate a kernel virtual address in KSEG0 or KSEG1 to a real
> + * physical address and back.
> + */
> +#define KVA_TO_PA(v)   ((paddr_t)(v) & 0x1fffffff)
> +#define PA_TO_KVA0(pa) ((void *) ((pa) | 0x80000000))
> +#define PA_TO_KVA1(pa) ((void *) ((pa) | 0xa0000000))
> +
> +/* translate between KSEG0 and KSEG1 virtual addresses */
> +#define KVA0_TO_KVA1(v)        ((void *) ((unsigned)(v) | 0x20000000))
> +#define KVA1_TO_KVA0(v)        ((void *) ((unsigned)(v) & ~0x20000000))
> +
> +/* Test for KSEGS */
> +#define IS_KVA(v)      ((int)(v) < 0)
> +#define IS_KVA0(v)     (((unsigned)(v) >> 29) == 0x4)
> +#define IS_KVA1(v)     (((unsigned)(v) >> 29) == 0x5)
> +#define IS_KVA01(v)    (((unsigned)(v) >> 30) == 0x2)
> +
> +/* convert register type to address and back */
> +#define VA_TO_REG(v)   ((long)(v))             /* sign-extend 32->64 */
> +#define REG_TO_VA(v)   ((void *)(long)(v))     /* truncate 64->32 */
> +
> +#endif /* __ASSEMBLER__ */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +#endif /* _NOTLB_H_*/
> diff --git a/libgloss/mips/include/mips/prid.h
> b/libgloss/mips/include/mips/prid.h
> new file mode 100644
> index 000000000..2bf017cf1
> --- /dev/null
> +++ b/libgloss/mips/include/mips/prid.h
> @@ -0,0 +1,130 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_PRID_H_
> +#define _MIPS_PRID_H_
> +
> +/*
> + * MIPS CPU types
> + */
> +#define        PRID_R2000      0x01    /* MIPS R2000 CPU
>  ISA I   */
> +#define        PRID_R3000      0x02    /* MIPS R3000 CPU
>  ISA I   */
> +#define        PRID_R6000      0x03    /* MIPS R6000 CPU
>  ISA II  */
> +#define        PRID_R4000      0x04    /* MIPS R4000/4400 CPU
> ISA III */
> +#define PRID_LR33K     0x05    /* LSI Logic R3000 derivate     ISA I   */
> +#define        PRID_R6000A     0x06    /* MIPS R6000A CPU
> ISA II  */
> +#define        PRID_R3IDT      0x07    /* IDT R3000 derivates
> ISA I   */
> +#define         PRID_R3IDT_R3041  0x07   /* R3041 (cp_rev field) */
> +#define         PRID_R3IDT_R36100 0x10   /* R36100 (cp_rev field) */
> +#define        PRID_R10000     0x09    /* MIPS R10000/T5 CPU
>  ISA IV  */
> +#define        PRID_R4200      0x0a    /* MIPS R4200 CPU (ICE)
>  ISA III */
> +#define PRID_R4300     0x0b    /* NEC VR4300 CPU               ISA III */
> +#define PRID_R4100     0x0c    /* NEC VR4100 CPU               ISA III */
> +#define        PRID_R8000      0x10    /* MIPS R8000 Blackbird/TFP
>  ISA IV  */
> +#define        PRID_RC6457X    0x15    /* IDT RC6457X CPU
> ISA IV  */
> +#define        PRID_RC3233X    0x18    /* IDT RC3233X CPU
> ISA MIPS32 */
> +#define        PRID_R4600      0x20    /* QED R4600 Orion
> ISA III */
> +#define        PRID_R4700      0x21    /* QED R4700 Orion
> ISA III */
> +#define        PRID_R3900      0x22    /* Toshiba/Philips R3900 CPU
> ISA I   */
> +#define        PRID_R4650      0x22    /* QED R4650/R4640 CPU
> ISA III */
> +#define        PRID_R5000      0x23    /* MIPS R5000 CPU
>  ISA IV  */
> +#define        PRID_RC3236X    0x26    /* IDT RC3236X CPU
> ISA MIPS32 */
> +#define        PRID_RM7000     0x27    /* QED RM7000 CPU
>  ISA IV  */
> +#define        PRID_RM52XX     0x28    /* QED RM52XX CPU
>  ISA IV  */
> +#define        PRID_RC6447X    0x30    /* IDT RC6447X CPU
> ISA III */
> +#define        PRID_R5400      0x54    /* NEC Vr5400 CPU
>  ISA IV  */
> +#define        PRID_R5500      0x55    /* NEC Vr5500 CPU
>  ISA IV  */
> +#define PRID_JADE      0x80    /* MIPS Jade (obsolete name)    ISA MIPS32
> */
> +#define PRID_4KC       0x80    /* MIPS 4Kc (TLB)               ISA MIPS32
> */
> +#define PRID_5KC       0x81    /* MIPS 5Kc                     ISA MIPS64
> */
> +#define PRID_20KC      0x82    /* MIPS 20Kc                    ISA MIPS64
> */
> +#define PRID_4KMP      0x83    /* MIPS 4Kp/4Km (FM)            ISA MIPS32
> */
> +#define PRID_4KEC      0x84    /* MIPS 4KEc (TLB)              ISA MIPS32
> */
> +#define PRID_4KEMP     0x85    /* MIPS 4KEm/4KEp (FM)          ISA MIPS32
> */
> +#define PRID_4KSC      0x86    /* MIPS 4KSc                    ISA MIPS32
> */
> +#define PRID_M4K       0x87    /* MIPS M4K                     ISA
> MIPS32r2 */
> +#define PRID_25KF      0x88    /* MIPS 25Kf                    ISA MIPS64
> */
> +#define PRID_5KE       0x89    /* MIPS 5KE                     ISA
> MIPS64r2 */
> +#define PRID_4KEC_R2   0x90    /* MIPS 4KEc (TLB)              ISA
> MIPS32r2 */
> +#define PRID_4KEMP_R2  0x91    /* MIPS 4KEm/4KEp (FM)          ISA
> MIPS32r2 */
> +#define PRID_4KSD      0x92    /* MIPS 4KSd                    ISA
> MIPS32r2 */
> +#define PRID_24K       0x93    /* MIPS 24K                     ISA
> MIPS32r2 */
> +#define PRID_34K       0x95    /* MIPS 34K                     ISA
> MIPS32r2 */
> +#define PRID_24KE      0x96    /* MIPS 24KE                    ISA
> MIPS32r2 */
> +#define PRID_74K       0x97    /* MIPS 74K                     ISA
> MIPS32r2 */
> +#define PRID_1004K     0x99    /* MIPS 1004K                   ISA
> MIPS32r2 */
> +#define PRID_1074K      0x9A    /* MIPS 1074K                   ISA
> MIPS32r2 */
> +#define PRID_M14K       0x9B    /* MIPS M14K                    ISA
> MIPS32r2 */
> +#define PRID_M14KC      0x9C    /* MIPS M14KC                   ISA
> MIPS32r2 */
> +#define PRID_M14KE      0x9D    /* MIPS M14KE                   ISA
> MIPS32r2 */
> +#define PRID_M14KEC     0x9E    /* MIPS M14KEC                  ISA
> MIPS32r2 */
> +#define PRID_INTERAPTIV_UP 0xA0    /* MIPS INTERAPTIV UP        ISA
> MIPS32r2 */
> +#define PRID_INTERAPTIV_MP 0xA1    /* MIPS INTERAPTIV MP        ISA
> MIPS32r2 */
> +#define PRID_PROAPTIV_UP   0xA2    /* MIPS PROAPTIV UP          ISA
> MIPS32r2 */
> +#define PRID_PROAPTIV_MP   0xA3    /* MIPS PROAPTIV MP          ISA
> MIPS32r2 */
> +#define PRID_M5100      0xA6    /* MIPS WARRIOR M5100           ISA
> MIPS32r2 */
> +#define PRID_M5150      0xA7    /* MIPS WARRIOR M5150           ISA
> MIPS32r2 */
> +#define PRID_P5600      0xA8    /* MIPS WARRIOR P5600           ISA
> MIPS32r2 */
> +#define PRID_I6400      0xA9    /* MIPS I6400                   ISA
> MIPS64r6 */
> +
> +/*
> + * MIPS FPU types
> + */
> +#define        PRID_SOFT       0x00    /* Software emulation
>  ISA I   */
> +#define        PRID_R2360      0x01    /* MIPS R2360 FPC
>  ISA I   */
> +#define        PRID_R2010      0x02    /* MIPS R2010 FPC
>  ISA I   */
> +#define        PRID_R3010      0x03    /* MIPS R3010 FPC
>  ISA I   */
> +#define        PRID_R6010      0x04    /* MIPS R6010 FPC
>  ISA II  */
> +#define        PRID_R4010      0x05    /* MIPS R4000/R4400 FPC
>  ISA II  */
> +#define PRID_LR33010   0x06    /* LSI Logic derivate           ISA I   */
> +#define        PRID_R10010     0x09    /* MIPS R10000/T5 FPU
>  ISA IV  */
> +#define        PRID_R4210      0x0a    /* MIPS R4200 FPC (ICE)
>  ISA III */
> +#define PRID_UNKF1     0x0b    /* unnanounced product cpu      ISA III */
> +#define        PRID_R8010      0x10    /* MIPS R8000 Blackbird/TFP
>  ISA IV  */
> +#define        PRID_RC6457XF   0x15    /* IDT RC6457X FPU
> ISA IV  */
> +#define        PRID_R4610      0x20    /* QED R4600 Orion
> ISA III */
> +#define        PRID_R3SONY     0x21    /* Sony R3000 based FPU
>  ISA I   */
> +#define        PRID_R3910      0x22    /* Toshiba/Philips R3900 FPU
> ISA I   */
> +#define        PRID_R5010      0x23    /* MIPS R5000 FPU
>  ISA IV  */
> +#define        PRID_RM7000F    0x27    /* QED RM7000 FPU
>  ISA IV  */
> +#define        PRID_RM52XXF    0x28    /* QED RM52X FPU
> ISA IV  */
> +#define        PRID_RC6447XF   0x30    /* IDT RC6447X FPU
> ISA III */
> +#define        PRID_R5400F     0x54    /* NEC Vr5400 FPU
>  ISA IV  */
> +#define        PRID_R5500F     0x55    /* NEC Vr5500 FPU
>  ISA IV  */
> +#define PRID_20KCF     0x82    /* MIPS 20Kc FPU                ISA MIPS64
> */
> +#define PRID_5KF       0x81    /* MIPS 5Kf FPU                 ISA MIPS64
> */
> +#define PRID_25KFF     0x88    /* MIPS 25Kf FPU                ISA MIPS64
> */
> +#define PRID_5KEF      0x89    /* MIPS 5KEf FPU                ISA
> MIPS64r2 */
> +#define PRID_24KF      0x93    /* MIPS 24Kf FPU                ISA
> MIPS32r2 */
> +#define PRID_34KF      0x95    /* MIPS 34K FPU                 ISA
> MIPS32r2 */
> +#define PRID_24KEF     0x96    /* MIPS 24KE FPU                ISA
> MIPS32r2 */
> +#define PRID_74KF      0x97    /* MIPS 74K FPU                 ISA
> MIPS32r2 */
> +
> +#endif /*  _MIPS_PRID_H_ */
> diff --git a/libgloss/mips/include/mips/regdef.h
> b/libgloss/mips/include/mips/regdef.h
> new file mode 100644
> index 000000000..f901c3043
> --- /dev/null
> +++ b/libgloss/mips/include/mips/regdef.h
> @@ -0,0 +1,133 @@
> +/*
> + * Copyright 2014-2017, Imagination Technologies Limited and/or its
> + *                      affiliated group companies.
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + * 3. Neither the name of the copyright holder nor the names of its
> + * contributors may be used to endorse or promote products derived from
> this
> + * software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> +*/
> +
> +#ifndef _MIPS_REGDEF_H_
> +#define _MIPS_REGDEF_H_
> +
> +#define zero   $0
> +
> +#define AT     $1
> +
> +#define v0     $2
> +#define v1     $3
> +#define va0    $2
> +#define va1    $3
> +
> +#define vt0    $2
> +#define vt1    $3
> +
> +#define a0     $4
> +#define a1     $5
> +#define a2     $6
> +#define        a3      $7
> +
> +#if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI
> +#define a4     $8
> +#define a5     $9
> +#define a6     $10
> +#define        a7      $11
> +#define t0     $12
> +#define t1     $13
> +#define t2     $14
> +#define t3     $15
> +#define ta0    $8      /* alias for $a4 */
> +#define ta1    $9      /* alias for $a5 */
> +#define ta2    $10     /* alias for $a6 */
> +#define ta3    $11     /* alias for $a7 */
> +#else
> +#define t0     $8
> +#define t1     $9
> +#define t2     $10
> +#define t3     $11
> +#define t4     $12
> +#define t5     $13
> +#define t6     $14
> +#define t7     $15
> +#define ta0    $12     /* alias for $t4 */
> +#define ta1    $13     /* alias for $t5 */
> +#define ta2    $14     /* alias for $t6 */
> +#define ta3    $15     /* alias for $t7 */
> +#endif
> +
> +#define s0     $16
> +#define s1     $17
> +#define s2     $18
> +#define s3     $19
> +#define s4     $20
> +#define s5     $21
> +#define s6     $22
> +#define s7     $23
> +#define s8     $30             /* == fp */
> +
> +#define t8     $24
> +#define t9     $25
> +#define k0     $26
> +#define k1     $27
> +
> +#define gp     $28
> +
> +#define sp     $29
> +#define fp     $30
> +#define ra     $31
> +
> +#define r0     $0
> +#define r1     $1
> +#define r2     $2
> +#define r3     $3
> +#define r4     $4
> +#define r5     $5
> +#define r6     $6
> +#define r7     $7
> +#define r8     $8
> +#define r9     $9
> +#define r10    $10
> +#define r11    $11
> +#define r12    $12
> +#define r13    $13
> +#define r14    $14
> +#define r15    $15
> +#define r16    $16
> +#define r17    $17
> +#define r18    $18
> +#define r19    $19
> +#define r20    $20
> +#define r21    $21
> +#define r22    $22
> +#define r23    $23
> +#define r24    $24
> +#define r25    $25
> +#define r26    $26
> +#define r27    $27
> +#define r28    $28
> +#define r29    $29
> +#define r30    $30
> +#define r31    $31
> +
> +#endif /*_MIPS_REGDEF_H_*/
> diff --git a/libgloss/mips/include/mips/version.h
> b/libgloss/mips/include/mips/version.h
> new file mode 100644
> index 000000000..d2ca5679d
> --- /dev/null
> +++ b/libgloss/mips/include/mips/version.h
> @@ -0,0 +1,4 @@
> +/* This file just defines the current version number of MIPS HAL
> library.  */
> +
> +#define __MIPS_HAL_VERSION__ "3.0.0"
> +
> diff --git a/libgloss/mips/malta32-yamon.ld
> b/libgloss/mips/malta32-yamon.ld
> new file mode 100644
> index 000000000..5175071c2
> --- /dev/null
> +++ b/libgloss/mips/malta32-yamon.ld
> @@ -0,0 +1,318 @@
> +/*
> + * A malta based target independent link script to produce UHI
> + * compliant binaries with varying levels of system initialization
> + * support.
> + */
> +
> +__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start;
> +ENTRY(__entry)
> +OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips",
> "elf32-tradlittlemips")
> +GROUP(-lc -lyamon -luhi -lgcc -lhal)
> +SEARCH_DIR(.)
> +
> +/* Define where the yamon entry point table is */
> +__yamon_functions = 0x9fc00500;
> +
> +__DYNAMIC  =  0;
> +STARTUP(crt0.o)
> +/* Force the exception handler to be registered */
> +EXTERN(__register_excpt_handler)
> +/* Force the exception handler to be included in the link */
> +EXTERN(__exception_entry)
> +/*
> + * Require verbose exceptions. This can be changed to pull in
> + * __exception_handle_quiet to reduce code size but be less
> + * informative
> + */
> +EXTERN(__exception_handle_verbose)
> +/* Force the interrupt handlers to be included in the link */
> +EXTERN(__isr_vec)
> +/* Force ISRs 0-7 to be included in the link */
> +EXTERN(_isr_vec_7)
> +/* Require the UHI getargs support */
> +EXTERN(__getargs)
> +/* Include the breakpoint exception handler.  */
> +EXTERN (__uhi_break);
> +
> +/*
> + * Set the location of the top of the stack.  A value of 0 means
> + * that it will be automatically placed at the highest address
> + * available as described by the __memory_* setttings
> + */
> +PROVIDE (__stack = 0);
> +
> +/* Size of the memory returned by _get_ram_range */
> +PROVIDE (__memory_size = 3M);
> +
> +/* Base of the memory returned by _get_ram_range */
> +PROVIDE (__memory_base = 0x80000000);
> +
> +/* Stride length for tlb software invalidate for tlbinvf
> + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
> + * differently in the index register. Either sets LSB or ways LSB.
> + *
> + * By setting this to 1 we presume that sets come first. The default boot
> + * code will decrement this value from the Number of TLB entries.
> + */
> +PROVIDE (__tlb_stride_length = 1);
> +
> +/* By default, XPA is not used even if available. To enable XPA,
> + * __enable_xpa should be 1.
> + */
> +PROVIDE (__enable_xpa = 0);
> +
> +/*
> + * 0 = Do not use exception handler present in boot for UHI
> + * 1 = Use exception handler present in boot for UHI if BEV is 0 at
> + *     startup
> + * 2 = Always use exception handler present in boot for UHI
> + */
> +PROVIDE (__use_excpt_boot = 0);
> +/*
> + * Include the code to be able to return to boot context.  This is
> + * necessary if __use_excpt_boot != 0.
> + */
> +EXTERN (__register_excpt_boot);
> +
> +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
> +       "Registration for boot context is required for UHI chaining")
> +
> +/* Control if subnormal floating-point values are flushed to zero in
> +   hardware.  This applies to both FPU and MSA operations.  */
> +PROVIDE (__flush_to_zero = 1);
> +
> +/* Set up the public symbols depending on whether the user has chosen
> +   quiet or verbose exception handling above */
> +EXTERN (__exception_handle);
> +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
> +                                     ? __exception_handle_quiet
> +                                     : __exception_handle_verbose));
> +PROVIDE(_mips_handle_exception = __exception_handle);
> +
> +/*
> + * Initalize some symbols to be zero so we can reference them in the
> + * crt0 without core dumping. These functions are all optional, but
> + * we do this so we can have our crt0 always use them if they exist.
> + * This is so BSPs work better when using the crt0 installed with gcc.
> + * We have to initalize them twice, so we multiple object file
> + * formats, as some prepend an underscore.
> + */
> +PROVIDE (hardware_exit_hook = 0);
> +PROVIDE (hardware_hazard_hook = 0);
> +PROVIDE (hardware_init_hook = 0);
> +PROVIDE (software_init_hook = 0);
> +
> +/* The default base address for application code is 0x80200000 which
> +   leaves 2M of space at the start of KSEG0 for a bootloader. */
> +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000);
> +/* Set default vector spacing to 32 bytes. */
> +PROVIDE (__isr_vec_space = 32);
> +/* Leave space for 9 vector entries by default. 8 entry points and one
> +   fallback handler. */
> +PROVIDE (__isr_vec_count = 9);
> +/*
> + * The start of flash must be set if including boot code.  By default
> + * the use of boot code will mean that application code is copied
> + * from flash to RAM at runtime before being executed.
> + */
> +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 :
> __app_start);
> +
> +SECTIONS
> +{
> +  /* Start of bootrom */
> +  .bootrom 0x9fc00000 : /* Runs uncached (from 0x9fc00000) until I$ is
> +                          initialized. */
> +  AT (__flash_start)
> +  {
> +    *(.reset)          /* Reset entry point. */
> +    *(.boot)           /* Boot code. */
> +    . = ALIGN(8);
> +  } = 0
> +
> +  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
> +
> +  /* Start of the application */
> +  .exception_vector ALIGN(__app_start, 0x1000) :
> +  AT (__flash_app_start)
> +  {
> +    __excpt_ebase = ABSOLUTE(.);
> +    __base = .;
> +    KEEP(* (.text.__exception_entry))
> +    . = __base + 0x200;
> +    KEEP(* (SORT(.text.__isr_vec*)))
> +    /* Leave space for all the vector entries */
> +    . = __base + 0x200 + (__isr_vec_space * __isr_vec_count);
> +    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
> +                              ? __isr_vec_sw1 - __isr_vec_sw0
> +                              : __isr_vec_space),
> +          "Actual ISR vector spacing does not match __isr_vec_space");
> +    ASSERT(__base + 0x200 == (DEFINED(__isr_vec_sw0)
> +                             ? __isr_vec_sw0 & 0xfffffffe : __base +
> 0x200),
> +          "__isr_vec_sw0 is not placed at EBASE + 0x200");
> +    . = ALIGN(8);
> +  } = 0
> +
> +  .text : {
> +     _ftext = . ;
> +    PROVIDE (eprol  =  .);
> +    *(.text)
> +    *(.text.*)
> +    *(.gnu.linkonce.t.*)
> +    *(.mips16.fn.*)
> +    *(.mips16.call.*)
> +  }
> +  .init : {
> +    KEEP (*(.init))
> +  }
> +  .fini : {
> +    KEEP (*(.fini))
> +  }
> +  .rel.sdata : {
> +    PROVIDE (__runtime_reloc_start = .);
> +    *(.rel.sdata)
> +    PROVIDE (__runtime_reloc_stop = .);
> +  }
> +  PROVIDE (etext  =  .);
> +  _etext  =  .;
> +
> +  .eh_frame_hdr : { *(.eh_frame_hdr) }
> +  .eh_frame : { KEEP (*(.eh_frame)) }
> +  .gcc_except_table : { *(.gcc_except_table) }
> +  .jcr : { KEEP (*(.jcr)) }
> +  .ctors    :
> +  {
> +    /* gcc uses crtbegin.o to find the start of
> +       the constructors, so we make sure it is
> +       first.  Because this is a wildcard, it
> +       doesn't matter if the user does not
> +       actually link against crtbegin.o; the
> +       linker won't look for a file to match a
> +       wildcard.  The wildcard also means that it
> +       doesn't matter which directory crtbegin.o
> +       is in.  */
> +
> +    KEEP (*crtbegin.o(.ctors))
> +
> +    /* We don't want to include the .ctor section from
> +       from the crtend.o file until after the sorted ctors.
> +       The .ctor section from the crtend file contains the
> +       end of ctors marker and it must be last */
> +
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
> +    KEEP (*(SORT(.ctors.*)))
> +    KEEP (*(.ctors))
> +  }
> +
> +  .dtors    :
> +  {
> +    KEEP (*crtbegin.o(.dtors))
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
> +    KEEP (*(SORT(.dtors.*)))
> +    KEEP (*(.dtors))
> +  }
> +
> +  . = .;
> +  .MIPS.abiflags : {
> +    __MIPS_abiflags_start = .;
> +    *(.MIPS.abiflags)
> +    __MIPS_abiflags_end = .;
> +  }
> +  .rodata : {
> +    *(.rdata)
> +    *(.rodata)
> +    *(.rodata.*)
> +    *(.gnu.linkonce.r.*)
> +  }
> +   . = ALIGN(16);
> +   _fdata = .;
> +  .data : {
> +    *(.data)
> +    *(.data.*)
> +    *(.gnu.linkonce.d.*)
> +  }
> +  . = ALIGN(8);
> +  MIPS_REVISION = DEFINED (__mips_isa_rev) ? ABSOLUTE(__mips_isa_rev) : 0;
> +  GP_OFFSET = (MIPS_REVISION < 7) ? 0x8000 : 0;
> +  _gp = . + GP_OFFSET;
> +  __global = _gp;
> +  .lit8 : {
> +    *(.lit8)
> +  }
> +  .lit4 : {
> +    *(.lit4)
> +  }
> +  .sdata : {
> +    *(.sdata)
> +    *(.sdata.*)
> +    *(.gnu.linkonce.s.*)
> +  }
> +  . = ALIGN(4);
> +  PROVIDE (edata  =  .);
> +  _edata  =  .;
> +  _fbss = .;
> +  .sbss : {
> +    *(.sbss)
> +    *(.sbss.*)
> +    *(.gnu.linkonce.sb.*)
> +    *(.scommon)
> +  }
> +  .bss : {
> +    _bss_start = . ;
> +    *(.bss)
> +    *(.bss.*)
> +    *(.gnu.linkonce.b.*)
> +    *(COMMON)
> +  }
> +
> +  . = ALIGN(4);
> +  PROVIDE (end = .);
> +  _end = .;
> +  /* Now place the data that is only needed within start.S and can be
> +     overwritten by the heap.  */
> +  .startdata : {
> +    *(.startdata)
> +  }
> +
> +  /* DWARF debug sections.
> +     Symbols in the DWARF debugging sections are relative to
> +     the beginning of the section so we begin them at 0.  */
> +
> +  /* DWARF 1 */
> +  .debug          0 : { *(.debug) }
> +  .line           0 : { *(.line) }
> +
> +  /* GNU DWARF 1 extensions */
> +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
> +  .debug_sfnames  0 : { *(.debug_sfnames) }
> +
> +  /* DWARF 1.1 and DWARF 2 */
> +  .debug_aranges  0 : { *(.debug_aranges) }
> +  .debug_pubnames 0 : { *(.debug_pubnames) }
> +
> +  /* DWARF 2 */
> +  .debug_info     0 : { *(.debug_info) }
> +  .debug_abbrev   0 : { *(.debug_abbrev) }
> +  .debug_line     0 : { *(.debug_line) }
> +  .debug_frame    0 : { *(.debug_frame) }
> +  .debug_str      0 : { *(.debug_str) }
> +  .debug_loc      0 : { *(.debug_loc) }
> +  .debug_macinfo  0 : { *(.debug_macinfo) }
> +  .debug_ranges   0 : { *(.debug_ranges) }
> +
> +  /* SGI/MIPS DWARF 2 extensions */
> +  .debug_weaknames 0 : { *(.debug_weaknames) }
> +  .debug_funcnames 0 : { *(.debug_funcnames) }
> +  .debug_typenames 0 : { *(.debug_typenames) }
> +  .debug_varnames  0 : { *(.debug_varnames) }
> +
> +  /* Special sections generated by gcc */
> +  /* Newer GNU linkers strip by default */
> +  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
> +  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
> +  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
> +  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
> +  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
> +  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
> +  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
> +  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
> +}
> diff --git a/libgloss/mips/regs.S b/libgloss/mips/regs.S
> index e4b134307..ac2935465 100644
> --- a/libgloss/mips/regs.S
> +++ b/libgloss/mips/regs.S
> @@ -98,7 +98,10 @@
>  #define SR_SX          0x00000040      /* Supervisor extended addressing
> enabled */
>  #define SR_UX          0x00000020      /* User extended addressing
> enabled */
>
> -#define SR_MSA         0x08000000      /* MSA ASE */
> +#define SR_IE          0x00000001      /* Interrupt enable */
> +
> +#define SR_MX          0x01000000      /* MDMX or DSP ASE */
> +#define CFG5_MSAEN     0x08000000      /* MSA ASE */
>
>  /* Standard (R4000) cache operations. Taken from "MIPS R4000
>     Microprocessor User's Manual" 2nd edition: */
> diff --git a/libgloss/mips/syscalls.c b/libgloss/mips/syscalls.c
> deleted file mode 100644
> index 3ab543674..000000000
> --- a/libgloss/mips/syscalls.c
> +++ /dev/null
> @@ -1,45 +0,0 @@
> -#include <_ansi.h>
> -#include <sys/types.h>
> -#include <sys/stat.h>
> -
> -#include "regs.S"
> -
> -extern char _end[];
> -
> -/* FIXME: This is not ideal, since we do a get_mem_info() call for
> -   every sbrk() call. */
> -char *
> -sbrk (nbytes)
> -     int nbytes;
> -{
> -  static char *heap_ptr = _end;
> -  static char *heap_start = _end;
> -  char        *base;
> -  struct s_mem {
> -    unsigned int size;
> -    unsigned int icsize;
> -    unsigned int dcsize;
> -  } mem;
> -  unsigned int avail = 0;
> -
> -  /* The sizeof (s_mem.size) must be 4 bytes.  The compiler should be
> -     able to eliminate this check */
> -  if (sizeof (unsigned int) != 4)
> -    return (char *)-1;
> -
> -  get_mem_info(&mem);
> -  /* NOTE: The value returned from the get_mem_info call is the amount
> -     of memory, and not the address of the (last byte + 1) */
> -
> -  if (((size_t)heap_ptr >= heap_start) && ((size_t)heap_ptr < (heap_start
> + mem.size))) {
> -    avail = (heap_start + mem.size) - (size_t)heap_ptr;
> -    base = heap_ptr;
> -  } /* else will fail since "nbytes" will be greater than zeroed "avail"
> value */
> -
> -  if ((nbytes > avail) || (heap_ptr + nbytes < _end))
> -   base = (char *)-1;
> -  else
> -   heap_ptr += nbytes;
> -
> -  return base;
> -}
> diff --git a/libgloss/mips/uhi32.ld b/libgloss/mips/uhi32.ld
> new file mode 100644
> index 000000000..d9df8e5e0
> --- /dev/null
> +++ b/libgloss/mips/uhi32.ld
> @@ -0,0 +1,322 @@
> +/*
> + * A platform and target independent link script to produce UHI
> + * compliant binaries with varying levels of system initialization
> + * support.
> + */
> +
> +__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start;
> +ENTRY(__entry)
> +OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips",
> "elf32-tradlittlemips")
> +GROUP(-lc -luhi -lgcc -lhal)
> +SEARCH_DIR(.)
> +__DYNAMIC  =  0;
> +STARTUP(crt0.o)
> +/* Force the exception handler to be registered */
> +EXTERN(__register_excpt_handler)
> +/* Force the exception handler to be included in the link */
> +EXTERN(__exception_entry)
> +/*
> + * Require verbose exceptions. This can be changed to pull in
> + * __exception_handle_quiet to reduce code size but be less
> + * informative
> + */
> +EXTERN(__exception_handle_verbose)
> +/* Force ISRs 0-7 to be included in the link */
> +EXTERN(__isr_vec_007)
> +/* Require the UHI getargs support */
> +EXTERN(__getargs)
> +/* Include the breakpoint exception handler.  */
> +EXTERN (__uhi_break);
> +
> +/*
> + * Set the location of the top of the stack.  A value of 0 means
> + * that it will be automatically placed at the highest address
> + * available as described by the __memory_* setttings
> + */
> +PROVIDE (__stack = 0);
> +
> +/* Size of the memory returned by _get_ram_range */
> +PROVIDE (__memory_size = 3M);
> +
> +/* Base of the memory returned by _get_ram_range */
> +PROVIDE (__memory_base = 0x80000000);
> +
> +/* Stride length for tlb software invalidate for tlbinvf
> + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
> + * differently in the index register. Either sets LSB or ways LSB.
> + *
> + * By setting this to 1 we presume that sets come first. The default boot
> + * code will decrement this value from the Number of TLB entries.
> + */
> +PROVIDE (__tlb_stride_length = 1);
> +
> +/* By default, XPA is not used even if available. To enable XPA,
> + * __enable_xpa should be 1.
> + */
> +PROVIDE (__enable_xpa = 0);
> +
> +/*
> + * 0 = Do not use exception handler present in boot for UHI
> + * 1 = Use exception handler present in boot for UHI if BEV is 0 at
> + *     startup
> + * 2 = Always use exception handler present in boot for UHI
> + */
> +PROVIDE (__use_excpt_boot = 1);
> +/*
> + * Include the code to be able to return to boot context.  This is
> + * necessary if __use_excpt_boot != 0.
> + */
> +EXTERN (__register_excpt_boot);
> +
> +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
> +       "Registration for boot context is required for UHI chaining")
> +
> +/* Control if subnormal floating-point values are flushed to zero in
> +   hardware.  This applies to both FPU and MSA operations.  */
> +PROVIDE (__flush_to_zero = 1);
> +
> +/* Set up the public symbols depending on whether the user has chosen
> +   quiet or verbose exception handling above */
> +EXTERN (__exception_handle);
> +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
> +                                     ? __exception_handle_quiet
> +                                     : __exception_handle_verbose));
> +PROVIDE(_mips_handle_exception = __exception_handle);
> +
> +/*
> + * Initalize some symbols to be zero so we can reference them in the
> + * crt0 without core dumping. These functions are all optional, but
> + * we do this so we can have our crt0 always use them if they exist.
> + * This is so BSPs work better when using the crt0 installed with gcc.
> + * We have to initalize them twice, so we multiple object file
> + * formats, as some prepend an underscore.
> + */
> +PROVIDE (hardware_exit_hook = 0);
> +PROVIDE (hardware_hazard_hook = 0);
> +PROVIDE (hardware_init_hook = 0);
> +PROVIDE (software_init_hook = 0);
> +
> +/* The default base address for application code is 0x80200000 which
> +   leaves 2M of space at the start of KSEG0 for a bootloader. */
> +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000);
> +/* Set default vector spacing to 32 bytes. */
> +PROVIDE (__isr_vec_space = 32);
> +/* Leave space for 9 vector entries by default. 8 entry points and one
> +   fallback handler. */
> +PROVIDE (__isr_vec_count = 9);
> +/*
> + * The start of flash must be set if including boot code.  By default
> + * the use of boot code will mean that application code is copied
> + * from flash to RAM at runtime before being executed.
> + */
> +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 :
> __app_start);
> +/* Set the default execution address for boot code. */
> +PROVIDE (__bev_override = 0x9fc00000);
> +
> +SECTIONS
> +{
> +  /* Start of bootrom */
> +  .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is
> +                              initialized. */
> +  AT (__flash_start)
> +  {
> +    *(.reset)          /* Reset entry point. */
> +    *(.boot)           /* Boot code. */
> +    . = ALIGN(8);
> +  } = 0
> +
> +  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
> +
> +  __aligned_app_start = DEFINED(__xip)
> +                       ? __bev_override + SIZEOF(.bootrom)
> +                       : ALIGN(__app_start, 0x1000);
> +
> +  PROVIDE (__ebase_size = 0x200);
> +
> +  /* Start of the application */
> +  .exception_vector __aligned_app_start :
> +  AT (__flash_app_start)
> +  {
> +    PROVIDE (__excpt_ebase = ABSOLUTE(.));
> +    __base = .;
> +    KEEP(* (.text.__exception_entry))
> +    . = __base + __ebase_size;
> +    KEEP(* (SORT(.text.__isr_vec*)))
> +    /* Leave space for all the vector entries */
> +    . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count);
> +    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
> +                              ? __isr_vec_sw1 - __isr_vec_sw0
> +                              : __isr_vec_space),
> +          "Actual ISR vector spacing does not match __isr_vec_space");
> +    ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0)
> +                                    ? __isr_vec_sw0 & 0xfffffffe
> +                                    : __base + __ebase_size),
> +          "__isr_vec_sw0 is not placed at EBASE + 0x200");
> +    . = ALIGN(8);
> +  } = 0
> +
> +  .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector))
> {
> +     _ftext = . ;
> +    PROVIDE (eprol  =  .);
> +    *(.text)
> +    *(.text.*)
> +    *(.gnu.linkonce.t.*)
> +    *(.mips16.fn.*)
> +    *(.mips16.call.*)
> +  }
> +  .init . : AT (LOADADDR (.text) + SIZEOF(.text)) {
> +    KEEP (*(.init))
> +  }
> +  .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) {
> +    KEEP (*(.fini))
> +  }
> +  .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) {
> +    PROVIDE (__runtime_reloc_start = .);
> +    *(.rel.sdata)
> +    PROVIDE (__runtime_reloc_stop = .);
> +  }
> +  PROVIDE (etext  =  .);
> +  _etext  =  .;
> +
> +  .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) {
> *(.eh_frame_hdr) }
> +  .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) {
> KEEP (*(.eh_frame)) }
> +  .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) {
> *(.gcc_except_table) }
> +  .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table))
> { KEEP (*(.jcr)) }
> +  .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr))
> +  {
> +    /* gcc uses crtbegin.o to find the start of
> +       the constructors, so we make sure it is
> +       first.  Because this is a wildcard, it
> +       doesn't matter if the user does not
> +       actually link against crtbegin.o; the
> +       linker won't look for a file to match a
> +       wildcard.  The wildcard also means that it
> +       doesn't matter which directory crtbegin.o
> +       is in.  */
> +
> +    KEEP (*crtbegin.o(.ctors))
> +
> +    /* We don't want to include the .ctor section from
> +       from the crtend.o file until after the sorted ctors.
> +       The .ctor section from the crtend file contains the
> +       end of ctors marker and it must be last */
> +
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
> +    KEEP (*(SORT(.ctors.*)))
> +    KEEP (*(.ctors))
> +  }
> +
> +  .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors))
> +  {
> +    KEEP (*crtbegin.o(.dtors))
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
> +    KEEP (*(SORT(.dtors.*)))
> +    KEEP (*(.dtors))
> +  }
> +
> +  . = .;
> +  .MIPS.abiflags : {
> +    __MIPS_abiflags_start = .;
> +    *(.MIPS.abiflags)
> +    __MIPS_abiflags_end = .;
> +  }
> +  .rodata : {
> +    *(.rdata)
> +    *(.rodata)
> +    *(.rodata.*)
> +    *(.gnu.linkonce.r.*)
> +  }
> +   . = ALIGN(16);
> +   _fdata = .;
> +  .data : {
> +    *(.data)
> +    *(.data.*)
> +    *(.gnu.linkonce.d.*)
> +  }
> +  . = ALIGN(8);
> +  _gp = . + 0x8000;
> +  __global = _gp;
> +  .lit8 : {
> +    *(.lit8)
> +  }
> +  .lit4 : {
> +    *(.lit4)
> +  }
> +  .sdata : {
> +    *(.sdata)
> +    *(.sdata.*)
> +    *(.gnu.linkonce.s.*)
> +  }
> +  . = ALIGN(4);
> +  PROVIDE (edata  =  .);
> +  _edata  =  .;
> +  _fbss = .;
> +  .sbss : {
> +    *(.sbss)
> +    *(.sbss.*)
> +    *(.gnu.linkonce.sb.*)
> +    *(.scommon)
> +  }
> +  .bss : {
> +    _bss_start = . ;
> +    *(.bss)
> +    *(.bss.*)
> +    *(.gnu.linkonce.b.*)
> +    *(COMMON)
> +  }
> +
> +  . = ALIGN(4);
> +  PROVIDE (end = .);
> +  _end = .;
> +  /* Now place the data that is only needed within start.S and can be
> +     overwritten by the heap.  */
> +  .startdata : {
> +    *(.startdata)
> +  }
> +
> +  /* We do not support any runtime relocation handling with this script.
> */
> +  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
> +
> +  /* DWARF debug sections.
> +     Symbols in the DWARF debugging sections are relative to
> +     the beginning of the section so we begin them at 0.  */
> +
> +  /* DWARF 1 */
> +  .debug          0 : { *(.debug) }
> +  .line           0 : { *(.line) }
> +
> +  /* GNU DWARF 1 extensions */
> +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
> +  .debug_sfnames  0 : { *(.debug_sfnames) }
> +
> +  /* DWARF 1.1 and DWARF 2 */
> +  .debug_aranges  0 : { *(.debug_aranges) }
> +  .debug_pubnames 0 : { *(.debug_pubnames) }
> +
> +  /* DWARF 2 */
> +  .debug_info     0 : { *(.debug_info) }
> +  .debug_abbrev   0 : { *(.debug_abbrev) }
> +  .debug_line     0 : { *(.debug_line) }
> +  .debug_frame    0 : { *(.debug_frame) }
> +  .debug_str      0 : { *(.debug_str) }
> +  .debug_loc      0 : { *(.debug_loc) }
> +  .debug_macinfo  0 : { *(.debug_macinfo) }
> +  .debug_ranges   0 : { *(.debug_ranges) }
> +
> +  /* SGI/MIPS DWARF 2 extensions */
> +  .debug_weaknames 0 : { *(.debug_weaknames) }
> +  .debug_funcnames 0 : { *(.debug_funcnames) }
> +  .debug_typenames 0 : { *(.debug_typenames) }
> +  .debug_varnames  0 : { *(.debug_varnames) }
> +
> +  /* Special sections generated by gcc */
> +  /* Newer GNU linkers strip by default */
> +  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
> +  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
> +  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
> +  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
> +  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
> +  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
> +  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
> +  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
> +}
> diff --git a/libgloss/mips/uhi64_64.ld b/libgloss/mips/uhi64_64.ld
> new file mode 100644
> index 000000000..15aeb2ecc
> --- /dev/null
> +++ b/libgloss/mips/uhi64_64.ld
> @@ -0,0 +1,322 @@
> +/*
> + * A platform and target independent link script to produce UHI
> + * compliant binaries with varying levels of system initialization
> + * support.
> + */
> +
> +__entry = DEFINED(__reset_vector) ? 0xffffffffbfc00000 : _start;
> +ENTRY(__entry)
> +OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips",
> "elf64-tradlittlemips")
> +GROUP(-lc -luhi -lgcc -lhal)
> +SEARCH_DIR(.)
> +__DYNAMIC  =  0;
> +STARTUP(crt0.o)
> +/* Force the exception handler to be registered */
> +EXTERN(__register_excpt_handler)
> +/* Force the exception handler to be included in the link */
> +EXTERN(__exception_entry)
> +/*
> + * Require verbose exceptions. This can be changed to pull in
> + * __exception_handle_quiet to reduce code size but be less
> + * informative
> + */
> +EXTERN(__exception_handle_verbose)
> +/* Force ISRs 0-7 to be included in the link */
> +EXTERN(__isr_vec_007)
> +/* Require the UHI getargs support */
> +EXTERN(__getargs)
> +/* Include the breakpoint exception handler.  */
> +EXTERN (__uhi_break);
> +
> +/*
> + * Set the location of the top of the stack.  A value of 0 means
> + * that it will be automatically placed at the highest address
> + * available as described by the __memory_* setttings
> + */
> +PROVIDE (__stack = 0);
> +
> +/* Size of the memory returned by _get_ram_range */
> +PROVIDE (__memory_size = 3M);
> +
> +/* Base of the memory returned by _get_ram_range */
> +PROVIDE (__memory_base = 0xffffffff80000000);
> +
> +/* Stride length for tlb software invalidate for tlbinvf
> + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
> + * differently in the index register. Either sets LSB or ways LSB.
> + *
> + * By setting this to 1 we presume that sets come first. The default boot
> + * code will decrement this value from the Number of TLB entries.
> + */
> +PROVIDE (__tlb_stride_length = 1);
> +
> +/* By default, XPA is not used even if available. To enable XPA,
> + * __enable_xpa should be 1.
> + */
> +PROVIDE (__enable_xpa = 0);
> +
> +/*
> + * 0 = Do not use exception handler present in boot for UHI
> + * 1 = Use exception handler present in boot for UHI if BEV is 0 at
> + *     startup
> + * 2 = Always use exception handler present in boot for UHI
> + */
> +PROVIDE (__use_excpt_boot = 1);
> +/*
> + * Include the code to be able to return to boot context.  This is
> + * necessary if __use_excpt_boot != 0.
> + */
> +EXTERN (__register_excpt_boot);
> +
> +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
> +       "Registration for boot context is required for UHI chaining")
> +
> +/* Control if subnormal floating-point values are flushed to zero in
> +   hardware.  This applies to both FPU and MSA operations.  */
> +PROVIDE (__flush_to_zero = 1);
> +
> +/* Set up the public symbols depending on whether the user has chosen
> +   quiet or verbose exception handling above */
> +EXTERN (__exception_handle);
> +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
> +                                     ? __exception_handle_quiet
> +                                     : __exception_handle_verbose));
> +PROVIDE(_mips_handle_exception = __exception_handle);
> +
> +/*
> + * Initalize some symbols to be zero so we can reference them in the
> + * crt0 without core dumping. These functions are all optional, but
> + * we do this so we can have our crt0 always use them if they exist.
> + * This is so BSPs work better when using the crt0 installed with gcc.
> + * We have to initalize them twice, so we multiple object file
> + * formats, as some prepend an underscore.
> + */
> +PROVIDE (hardware_exit_hook = 0);
> +PROVIDE (hardware_hazard_hook = 0);
> +PROVIDE (hardware_init_hook = 0);
> +PROVIDE (software_init_hook = 0);
> +
> +/* The default base address for application code is 0x80200000 which
> +   leaves 2M of space at the start of KSEG0 for a bootloader. */
> +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0xffffffff80000000
> :0xffffffff80200000);
> +/* Set default vector spacing to 64 bytes. */
> +PROVIDE (__isr_vec_space = 64);
> +/* Leave space for 9 vector entries by default. 8 entry points and one
> +   fallback handler. */
> +PROVIDE (__isr_vec_count = 9);
> +/*
> + * The start of flash must be set if including boot code.  By default
> + * the use of boot code will mean that application code is copied
> + * from flash to RAM at runtime before being executed.
> + */
> +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xffffffffbfc00000 :
> __app_start);
> +/* Set the default execution address for boot code. */
> +PROVIDE (__bev_override = 0xffffffff9fc00000);
> +
> +SECTIONS
> +{
> +  /* Start of bootrom */
> +  .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is
> +                              initialized. */
> +  AT (__flash_start)
> +  {
> +    *(.reset)          /* Reset entry point. */
> +    *(.boot)           /* Boot code. */
> +    . = ALIGN(8);
> +  } = 0
> +
> +  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
> +
> +  __aligned_app_start = DEFINED(__xip)
> +                       ? __bev_override + SIZEOF(.bootrom)
> +                       : ALIGN(__app_start, 0x1000);
> +
> +  PROVIDE (__ebase_size = 0x200);
> +
> +  /* Start of the application */
> +  .exception_vector __aligned_app_start :
> +  AT (__flash_app_start)
> +  {
> +    PROVIDE (__excpt_ebase = ABSOLUTE(.));
> +    __base = .;
> +    KEEP(* (.text.__exception_entry))
> +    . = __base + __ebase_size;
> +    KEEP(* (SORT(.text.__isr_vec*)))
> +    /* Leave space for all the vector entries */
> +    . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count);
> +    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
> +                              ? __isr_vec_sw1 - __isr_vec_sw0
> +                              : __isr_vec_space),
> +          "Actual ISR vector spacing does not match __isr_vec_space");
> +    ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0)
> +                                    ? __isr_vec_sw0
> +                                    : __base + __ebase_size),
> +          "__isr_vec_sw0 is not placed at EBASE + 0x200");
> +    . = ALIGN(8);
> +  } = 0
> +
> +  .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector))
> {
> +     _ftext = . ;
> +    PROVIDE (eprol  =  .);
> +    *(.text)
> +    *(.text.*)
> +    *(.gnu.linkonce.t.*)
> +    *(.mips16.fn.*)
> +    *(.mips16.call.*)
> +  }
> +  .init . : AT (LOADADDR (.text) + SIZEOF(.text)) {
> +    KEEP (*(.init))
> +  }
> +  .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) {
> +    KEEP (*(.fini))
> +  }
> +  .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) {
> +    PROVIDE (__runtime_reloc_start = .);
> +    *(.rel.sdata)
> +    PROVIDE (__runtime_reloc_stop = .);
> +  }
> +  PROVIDE (etext  =  .);
> +  _etext  =  .;
> +
> +  .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) {
> *(.eh_frame_hdr) }
> +  .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) {
> KEEP (*(.eh_frame)) }
> +  .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) {
> *(.gcc_except_table) }
> +  .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table))
> { KEEP (*(.jcr)) }
> +  .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr))
> +  {
> +    /* gcc uses crtbegin.o to find the start of
> +       the constructors, so we make sure it is
> +       first.  Because this is a wildcard, it
> +       doesn't matter if the user does not
> +       actually link against crtbegin.o; the
> +       linker won't look for a file to match a
> +       wildcard.  The wildcard also means that it
> +       doesn't matter which directory crtbegin.o
> +       is in.  */
> +
> +    KEEP (*crtbegin.o(.ctors))
> +
> +    /* We don't want to include the .ctor section from
> +       from the crtend.o file until after the sorted ctors.
> +       The .ctor section from the crtend file contains the
> +       end of ctors marker and it must be last */
> +
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
> +    KEEP (*(SORT(.ctors.*)))
> +    KEEP (*(.ctors))
> +  }
> +
> +  .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors))
> +  {
> +    KEEP (*crtbegin.o(.dtors))
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
> +    KEEP (*(SORT(.dtors.*)))
> +    KEEP (*(.dtors))
> +  }
> +
> +  . = .;
> +  .MIPS.abiflags : {
> +    __MIPS_abiflags_start = .;
> +    *(.MIPS.abiflags)
> +    __MIPS_abiflags_end = .;
> +  }
> +  .rodata : {
> +    *(.rdata)
> +    *(.rodata)
> +    *(.rodata.*)
> +    *(.gnu.linkonce.r.*)
> +  }
> +   . = ALIGN(16);
> +   _fdata = .;
> +  .data : {
> +    *(.data)
> +    *(.data.*)
> +    *(.gnu.linkonce.d.*)
> +  }
> +  . = ALIGN(8);
> +  _gp = . + 0x8000;
> +  __global = _gp;
> +  .lit8 : {
> +    *(.lit8)
> +  }
> +  .lit4 : {
> +    *(.lit4)
> +  }
> +  .sdata : {
> +    *(.sdata)
> +    *(.sdata.*)
> +    *(.gnu.linkonce.s.*)
> +  }
> +  . = ALIGN(4);
> +  PROVIDE (edata  =  .);
> +  _edata  =  .;
> +  _fbss = .;
> +  .sbss : {
> +    *(.sbss)
> +    *(.sbss.*)
> +    *(.gnu.linkonce.sb.*)
> +    *(.scommon)
> +  }
> +  .bss : {
> +    _bss_start = . ;
> +    *(.bss)
> +    *(.bss.*)
> +    *(.gnu.linkonce.b.*)
> +    *(COMMON)
> +  }
> +
> +  . = ALIGN(4);
> +  PROVIDE (end = .);
> +  _end = .;
> +  /* Now place the data that is only needed within start.S and can be
> +     overwritten by the heap.  */
> +  .startdata : {
> +    *(.startdata)
> +  }
> +
> +  /* We do not support any runtime relocation handling with this script.
> */
> +  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
> +
> +  /* DWARF debug sections.
> +     Symbols in the DWARF debugging sections are relative to
> +     the beginning of the section so we begin them at 0.  */
> +
> +  /* DWARF 1 */
> +  .debug          0 : { *(.debug) }
> +  .line           0 : { *(.line) }
> +
> +  /* GNU DWARF 1 extensions */
> +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
> +  .debug_sfnames  0 : { *(.debug_sfnames) }
> +
> +  /* DWARF 1.1 and DWARF 2 */
> +  .debug_aranges  0 : { *(.debug_aranges) }
> +  .debug_pubnames 0 : { *(.debug_pubnames) }
> +
> +  /* DWARF 2 */
> +  .debug_info     0 : { *(.debug_info) }
> +  .debug_abbrev   0 : { *(.debug_abbrev) }
> +  .debug_line     0 : { *(.debug_line) }
> +  .debug_frame    0 : { *(.debug_frame) }
> +  .debug_str      0 : { *(.debug_str) }
> +  .debug_loc      0 : { *(.debug_loc) }
> +  .debug_macinfo  0 : { *(.debug_macinfo) }
> +  .debug_ranges   0 : { *(.debug_ranges) }
> +
> +  /* SGI/MIPS DWARF 2 extensions */
> +  .debug_weaknames 0 : { *(.debug_weaknames) }
> +  .debug_funcnames 0 : { *(.debug_funcnames) }
> +  .debug_typenames 0 : { *(.debug_typenames) }
> +  .debug_varnames  0 : { *(.debug_varnames) }
> +
> +  /* Special sections generated by gcc */
> +  /* Newer GNU linkers strip by default */
> +  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
> +  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
> +  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
> +  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
> +  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
> +  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
> +  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
> +  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
> +}
> diff --git a/libgloss/mips/uhi64_n32.ld b/libgloss/mips/uhi64_n32.ld
> new file mode 100644
> index 000000000..d68f2eaaa
> --- /dev/null
> +++ b/libgloss/mips/uhi64_n32.ld
> @@ -0,0 +1,322 @@
> +/*
> + * A platform and target independent link script to produce UHI
> + * compliant binaries with varying levels of system initialization
> + * support.
> + */
> +
> +__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start;
> +ENTRY(__entry)
> +OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips",
> "elf32-ntradlittlemips")
> +GROUP(-lc -luhi -lgcc -lhal)
> +SEARCH_DIR(.)
> +__DYNAMIC  =  0;
> +STARTUP(crt0.o)
> +/* Force the exception handler to be registered */
> +EXTERN(__register_excpt_handler)
> +/* Force the exception handler to be included in the link */
> +EXTERN(__exception_entry)
> +/*
> + * Require verbose exceptions. This can be changed to pull in
> + * __exception_handle_quiet to reduce code size but be less
> + * informative
> + */
> +EXTERN(__exception_handle_verbose)
> +/* Force ISRs 0-7 to be included in the link */
> +EXTERN(__isr_vec_007)
> +/* Require the UHI getargs support */
> +EXTERN(__getargs)
> +/* Include the breakpoint exception handler.  */
> +EXTERN (__uhi_break);
> +
> +/*
> + * Set the location of the top of the stack.  A value of 0 means
> + * that it will be automatically placed at the highest address
> + * available as described by the __memory_* setttings
> + */
> +PROVIDE (__stack = 0);
> +
> +/* Size of the memory returned by _get_ram_range */
> +PROVIDE (__memory_size = 3M);
> +
> +/* Base of the memory returned by _get_ram_range */
> +PROVIDE (__memory_base = 0x80000000);
> +
> +/* Stride length for tlb software invalidate for tlbinvf
> + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways
> + * differently in the index register. Either sets LSB or ways LSB.
> + *
> + * By setting this to 1 we presume that sets come first. The default boot
> + * code will decrement this value from the Number of TLB entries.
> + */
> +PROVIDE (__tlb_stride_length = 1);
> +
> +/* By default, XPA is not used even if available. To enable XPA,
> + * __enable_xpa should be 1.
> + */
> +PROVIDE (__enable_xpa = 0);
> +
> +/*
> + * 0 = Do not use exception handler present in boot for UHI
> + * 1 = Use exception handler present in boot for UHI if BEV is 0 at
> + *     startup
> + * 2 = Always use exception handler present in boot for UHI
> + */
> +PROVIDE (__use_excpt_boot = 1);
> +/*
> + * Include the code to be able to return to boot context.  This is
> + * necessary if __use_excpt_boot != 0.
> + */
> +EXTERN (__register_excpt_boot);
> +
> +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0,
> +       "Registration for boot context is required for UHI chaining")
> +
> +/* Control if subnormal floating-point values are flushed to zero in
> +   hardware.  This applies to both FPU and MSA operations.  */
> +PROVIDE (__flush_to_zero = 1);
> +
> +/* Set up the public symbols depending on whether the user has chosen
> +   quiet or verbose exception handling above */
> +EXTERN (__exception_handle);
> +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet)
> +                                     ? __exception_handle_quiet
> +                                     : __exception_handle_verbose));
> +PROVIDE(_mips_handle_exception = __exception_handle);
> +
> +/*
> + * Initalize some symbols to be zero so we can reference them in the
> + * crt0 without core dumping. These functions are all optional, but
> + * we do this so we can have our crt0 always use them if they exist.
> + * This is so BSPs work better when using the crt0 installed with gcc.
> + * We have to initalize them twice, so we multiple object file
> + * formats, as some prepend an underscore.
> + */
> +PROVIDE (hardware_exit_hook = 0);
> +PROVIDE (hardware_hazard_hook = 0);
> +PROVIDE (hardware_init_hook = 0);
> +PROVIDE (software_init_hook = 0);
> +
> +/* The default base address for application code is 0x80200000 which
> +   leaves 2M of space at the start of KSEG0 for a bootloader. */
> +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000);
> +/* Set default vector spacing to 32 bytes. */
> +PROVIDE (__isr_vec_space = 32);
> +/* Leave space for 9 vector entries by default. 8 entry points and one
> +   fallback handler. */
> +PROVIDE (__isr_vec_count = 9);
> +/*
> + * The start of flash must be set if including boot code.  By default
> + * the use of boot code will mean that application code is copied
> + * from flash to RAM at runtime before being executed.
> + */
> +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 :
> __app_start);
> +/* Set the default execution address for boot code. */
> +PROVIDE (__bev_override = 0x9fc00000);
> +
> +SECTIONS
> +{
> +  /* Start of bootrom */
> +  .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is
> +                              initialized. */
> +  AT (__flash_start)
> +  {
> +    *(.reset)          /* Reset entry point. */
> +    *(.boot)           /* Boot code. */
> +    . = ALIGN(8);
> +  } = 0
> +
> +  PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start);
> +
> +  __aligned_app_start = DEFINED(__xip)
> +                       ? __bev_override + SIZEOF(.bootrom)
> +                       : ALIGN(__app_start, 0x1000);
> +
> +  PROVIDE (__ebase_size = 0x200);
> +
> +  /* Start of the application */
> +  .exception_vector __aligned_app_start :
> +  AT (__flash_app_start)
> +  {
> +    PROVIDE (__excpt_ebase = ABSOLUTE(.));
> +    __base = .;
> +    KEEP(* (.text.__exception_entry))
> +    . = __base + __ebase_size;
> +    KEEP(* (SORT(.text.__isr_vec*)))
> +    /* Leave space for all the vector entries */
> +    . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count);
> +    ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1)
> +                              ? __isr_vec_sw1 - __isr_vec_sw0
> +                              : __isr_vec_space),
> +          "Actual ISR vector spacing does not match __isr_vec_space");
> +    ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0)
> +                                    ? __isr_vec_sw0
> +                                    : __base + __ebase_size),
> +          "__isr_vec_sw0 is not placed at EBASE + 0x200");
> +    . = ALIGN(8);
> +  } = 0
> +
> +  .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector))
> {
> +     _ftext = . ;
> +    PROVIDE (eprol  =  .);
> +    *(.text)
> +    *(.text.*)
> +    *(.gnu.linkonce.t.*)
> +    *(.mips16.fn.*)
> +    *(.mips16.call.*)
> +  }
> +  .init . : AT (LOADADDR (.text) + SIZEOF(.text)) {
> +    KEEP (*(.init))
> +  }
> +  .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) {
> +    KEEP (*(.fini))
> +  }
> +  .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) {
> +    PROVIDE (__runtime_reloc_start = .);
> +    *(.rel.sdata)
> +    PROVIDE (__runtime_reloc_stop = .);
> +  }
> +  PROVIDE (etext  =  .);
> +  _etext  =  .;
> +
> +  .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) {
> *(.eh_frame_hdr) }
> +  .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) {
> KEEP (*(.eh_frame)) }
> +  .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) {
> *(.gcc_except_table) }
> +  .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table))
> { KEEP (*(.jcr)) }
> +  .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr))
> +  {
> +    /* gcc uses crtbegin.o to find the start of
> +       the constructors, so we make sure it is
> +       first.  Because this is a wildcard, it
> +       doesn't matter if the user does not
> +       actually link against crtbegin.o; the
> +       linker won't look for a file to match a
> +       wildcard.  The wildcard also means that it
> +       doesn't matter which directory crtbegin.o
> +       is in.  */
> +
> +    KEEP (*crtbegin.o(.ctors))
> +
> +    /* We don't want to include the .ctor section from
> +       from the crtend.o file until after the sorted ctors.
> +       The .ctor section from the crtend file contains the
> +       end of ctors marker and it must be last */
> +
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
> +    KEEP (*(SORT(.ctors.*)))
> +    KEEP (*(.ctors))
> +  }
> +
> +  .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors))
> +  {
> +    KEEP (*crtbegin.o(.dtors))
> +    KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
> +    KEEP (*(SORT(.dtors.*)))
> +    KEEP (*(.dtors))
> +  }
> +
> +  . = .;
> +  .MIPS.abiflags : {
> +    __MIPS_abiflags_start = .;
> +    *(.MIPS.abiflags)
> +    __MIPS_abiflags_end = .;
> +  }
> +  .rodata : {
> +    *(.rdata)
> +    *(.rodata)
> +    *(.rodata.*)
> +    *(.gnu.linkonce.r.*)
> +  }
> +   . = ALIGN(16);
> +   _fdata = .;
> +  .data : {
> +    *(.data)
> +    *(.data.*)
> +    *(.gnu.linkonce.d.*)
> +  }
> +  . = ALIGN(8);
> +  _gp = . + 0x8000;
> +  __global = _gp;
> +  .lit8 : {
> +    *(.lit8)
> +  }
> +  .lit4 : {
> +    *(.lit4)
> +  }
> +  .sdata : {
> +    *(.sdata)
> +    *(.sdata.*)
> +    *(.gnu.linkonce.s.*)
> +  }
> +  . = ALIGN(4);
> +  PROVIDE (edata  =  .);
> +  _edata  =  .;
> +  _fbss = .;
> +  .sbss : {
> +    *(.sbss)
> +    *(.sbss.*)
> +    *(.gnu.linkonce.sb.*)
> +    *(.scommon)
> +  }
> +  .bss : {
> +    _bss_start = . ;
> +    *(.bss)
> +    *(.bss.*)
> +    *(.gnu.linkonce.b.*)
> +    *(COMMON)
> +  }
> +
> +  . = ALIGN(4);
> +  PROVIDE (end = .);
> +  _end = .;
> +  /* Now place the data that is only needed within start.S and can be
> +     overwritten by the heap.  */
> +  .startdata : {
> +    *(.startdata)
> +  }
> +
> +  /* We do not support any runtime relocation handling with this script.
> */
> +  /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) }
> +
> +  /* DWARF debug sections.
> +     Symbols in the DWARF debugging sections are relative to
> +     the beginning of the section so we begin them at 0.  */
> +
> +  /* DWARF 1 */
> +  .debug          0 : { *(.debug) }
> +  .line           0 : { *(.line) }
> +
> +  /* GNU DWARF 1 extensions */
> +  .debug_srcinfo  0 : { *(.debug_srcinfo) }
> +  .debug_sfnames  0 : { *(.debug_sfnames) }
> +
> +  /* DWARF 1.1 and DWARF 2 */
> +  .debug_aranges  0 : { *(.debug_aranges) }
> +  .debug_pubnames 0 : { *(.debug_pubnames) }
> +
> +  /* DWARF 2 */
> +  .debug_info     0 : { *(.debug_info) }
> +  .debug_abbrev   0 : { *(.debug_abbrev) }
> +  .debug_line     0 : { *(.debug_line) }
> +  .debug_frame    0 : { *(.debug_frame) }
> +  .debug_str      0 : { *(.debug_str) }
> +  .debug_loc      0 : { *(.debug_loc) }
> +  .debug_macinfo  0 : { *(.debug_macinfo) }
> +  .debug_ranges   0 : { *(.debug_ranges) }
> +
> +  /* SGI/MIPS DWARF 2 extensions */
> +  .debug_weaknames 0 : { *(.debug_weaknames) }
> +  .debug_funcnames 0 : { *(.debug_funcnames) }
> +  .debug_typenames 0 : { *(.debug_typenames) }
> +  .debug_varnames  0 : { *(.debug_varnames) }
> +
> +  /* Special sections generated by gcc */
> +  /* Newer GNU linkers strip by default */
> +  .mdebug.abi32            0 : { KEEP(*(.mdebug.abi32)) }
> +  .mdebug.abiN32           0 : { KEEP(*(.mdebug.abiN32)) }
> +  .mdebug.abi64            0 : { KEEP(*(.mdebug.abi64)) }
> +  .mdebug.abiO64           0 : { KEEP(*(.mdebug.abiO64)) }
> +  .mdebug.eabi32           0 : { KEEP(*(.mdebug.eabi32)) }
> +  .mdebug.eabi64           0 : { KEEP(*(.mdebug.eabi64)) }
> +  .gcc_compiled_long32     0 : { KEEP(*(.gcc_compiled_long32)) }
> +  .gcc_compiled_long64     0 : { KEEP(*(.gcc_compiled_long64)) }
> +}
> --
> 2.25.1
>
>
  

Patch

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