Re: [PATCH 01/21] Add HAL for MIPS architecture
Jeff Johnston <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <CAOox84uBH_8C-rNKadDcyz=zOoRvO9srYJQYoP9n_b_OWsLO6A@mail.gmail.com> |
A few things: 1. You are deleting crt0.S but crt0.o is referenced in various mips .ld files and specified in Makefie.in. Can you clarify? 2. You are adding platform-specific checks to generic libnosys and libgloss fstat files. Please clarify why this is being done since you have a mips-specific fstat file. 3. abiflags.S doesn't have a license header 4. there appears to be examples directories added to mips and to top level libgloss in this patch. Plus, there is a Makefile without generation. -- Jeff J. On Thu, Oct 31, 2024 at 1:51 AM Aleksandar Rikalo <[email protected]> wrote: > From: Jaydeep Patil <[email protected]> > > Signed-off-by: Jaydeep Patil <[email protected]> > Signed-off-by: Aleksandar Rikalo <[email protected]> > --- > libgloss/config/mips.mt | 19 + > libgloss/fstat.c | 3 + > libgloss/libnosys/fstat.c | 3 + > libgloss/mips/Makefile.in | 33 + > libgloss/mips/crt0.S | 316 ---- > .../mips/examples/romable_predef_xip/Makefile | 107 ++ > .../examples/romable_predef_xip/README.txt | 21 + > .../romable_predef_xip/romable_predef_xip.c | 35 + > libgloss/mips/fstat.c | 32 + > libgloss/mips/hal/__exit.c | 50 + > libgloss/mips/hal/abiflags.S | 82 + > libgloss/mips/hal/cache.h | 84 + > libgloss/mips/hal/crt0.S | 313 ++++ > libgloss/mips/hal/get_ram_range.c | 67 + > libgloss/mips/hal/libcm3.a | 36 + > libgloss/mips/hal/link.c | 41 + > libgloss/mips/hal/minicrt.S | 31 + > libgloss/mips/hal/mips64_tlb.c | 221 +++ > libgloss/mips/hal/mips_clean_cache.c | 115 ++ > libgloss/mips/hal/mips_cm3_l2size.c | 90 + > libgloss/mips/hal/mips_dsp.S | 130 ++ > libgloss/mips/hal/mips_excpt_boot.S | 381 ++++ > libgloss/mips/hal/mips_excpt_entry.S | 212 +++ > libgloss/mips/hal/mips_excpt_handler.c | 308 ++++ > libgloss/mips/hal/mips_excpt_isr_fallback.S | 52 + > libgloss/mips/hal/mips_excpt_isr_fragment.S | 73 + > libgloss/mips/hal/mips_excpt_register.S | 147 ++ > libgloss/mips/hal/mips_excpt_timer.S | 103 ++ > libgloss/mips/hal/mips_flush_cache.c | 108 ++ > libgloss/mips/hal/mips_fp.S | 184 ++ > libgloss/mips/hal/mips_intctrl.c | 151 ++ > libgloss/mips/hal/mips_l2size.c | 96 + > libgloss/mips/hal/mips_lock_cache.c | 83 + > libgloss/mips/hal/mips_msa.S | 183 ++ > libgloss/mips/hal/mips_size_cache.c | 108 ++ > libgloss/mips/hal/mips_sync_cache.c | 64 + > libgloss/mips/hal/mips_tlb.c | 479 +++++ > libgloss/mips/hal/mips_xpa.S | 78 + > libgloss/mips/hal/syscalls.c | 51 + > libgloss/mips/include/mips/asm.h | 356 ++++ > libgloss/mips/include/mips/cm3.h | 77 + > libgloss/mips/include/mips/cpu.h | 356 ++++ > libgloss/mips/include/mips/ctx.S | 149 ++ > libgloss/mips/include/mips/dsp.h | 60 + > libgloss/mips/include/mips/endian.h | 96 + > libgloss/mips/include/mips/fgregdef.h | 128 ++ > libgloss/mips/include/mips/fpa.h | 33 + > libgloss/mips/include/mips/hal.h | 452 +++++ > libgloss/mips/include/mips/intctrl.h | 71 + > libgloss/mips/include/mips/m32c0.h | 1607 +++++++++++++++++ > libgloss/mips/include/mips/m32c1.h | 276 +++ > libgloss/mips/include/mips/m32tlb.h | 103 ++ > libgloss/mips/include/mips/m64c0.h | 268 +++ > libgloss/mips/include/mips/m64tlb.h | 106 ++ > libgloss/mips/include/mips/mips32.h | 177 ++ > libgloss/mips/include/mips/mips64.h | 116 ++ > libgloss/mips/include/mips/mt.h | 521 ++++++ > libgloss/mips/include/mips/notlb.h | 115 ++ > libgloss/mips/include/mips/prid.h | 130 ++ > libgloss/mips/include/mips/regdef.h | 133 ++ > libgloss/mips/include/mips/version.h | 4 + > libgloss/mips/malta32-yamon.ld | 318 ++++ > libgloss/mips/regs.S | 5 +- > libgloss/mips/syscalls.c | 45 - > libgloss/mips/uhi32.ld | 322 ++++ > libgloss/mips/uhi64_64.ld | 322 ++++ > libgloss/mips/uhi64_n32.ld | 322 ++++ > 67 files changed, 10996 insertions(+), 362 deletions(-) > delete mode 100644 libgloss/mips/crt0.S > create mode 100644 libgloss/mips/examples/romable_predef_xip/Makefile > create mode 100644 libgloss/mips/examples/romable_predef_xip/README.txt > create mode 100644 > libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c > create mode 100644 libgloss/mips/fstat.c > create mode 100644 libgloss/mips/hal/__exit.c > create mode 100644 libgloss/mips/hal/abiflags.S > create mode 100644 libgloss/mips/hal/cache.h > create mode 100644 libgloss/mips/hal/crt0.S > create mode 100644 libgloss/mips/hal/get_ram_range.c > create mode 100644 libgloss/mips/hal/libcm3.a > create mode 100644 libgloss/mips/hal/link.c > create mode 100644 libgloss/mips/hal/minicrt.S > create mode 100644 libgloss/mips/hal/mips64_tlb.c > create mode 100644 libgloss/mips/hal/mips_clean_cache.c > create mode 100644 libgloss/mips/hal/mips_cm3_l2size.c > create mode 100644 libgloss/mips/hal/mips_dsp.S > create mode 100644 libgloss/mips/hal/mips_excpt_boot.S > create mode 100644 libgloss/mips/hal/mips_excpt_entry.S > create mode 100644 libgloss/mips/hal/mips_excpt_handler.c > create mode 100644 libgloss/mips/hal/mips_excpt_isr_fallback.S > create mode 100644 libgloss/mips/hal/mips_excpt_isr_fragment.S > create mode 100644 libgloss/mips/hal/mips_excpt_register.S > create mode 100644 libgloss/mips/hal/mips_excpt_timer.S > create mode 100644 libgloss/mips/hal/mips_flush_cache.c > create mode 100644 libgloss/mips/hal/mips_fp.S > create mode 100644 libgloss/mips/hal/mips_intctrl.c > create mode 100644 libgloss/mips/hal/mips_l2size.c > create mode 100644 libgloss/mips/hal/mips_lock_cache.c > create mode 100644 libgloss/mips/hal/mips_msa.S > create mode 100644 libgloss/mips/hal/mips_size_cache.c > create mode 100644 libgloss/mips/hal/mips_sync_cache.c > create mode 100644 libgloss/mips/hal/mips_tlb.c > create mode 100644 libgloss/mips/hal/mips_xpa.S > create mode 100644 libgloss/mips/hal/syscalls.c > create mode 100644 libgloss/mips/include/mips/asm.h > create mode 100644 libgloss/mips/include/mips/cm3.h > create mode 100644 libgloss/mips/include/mips/cpu.h > create mode 100644 libgloss/mips/include/mips/ctx.S > create mode 100644 libgloss/mips/include/mips/dsp.h > create mode 100644 libgloss/mips/include/mips/endian.h > create mode 100644 libgloss/mips/include/mips/fgregdef.h > create mode 100644 libgloss/mips/include/mips/fpa.h > create mode 100644 libgloss/mips/include/mips/hal.h > create mode 100644 libgloss/mips/include/mips/intctrl.h > create mode 100644 libgloss/mips/include/mips/m32c0.h > create mode 100644 libgloss/mips/include/mips/m32c1.h > create mode 100644 libgloss/mips/include/mips/m32tlb.h > create mode 100644 libgloss/mips/include/mips/m64c0.h > create mode 100644 libgloss/mips/include/mips/m64tlb.h > create mode 100644 libgloss/mips/include/mips/mips32.h > create mode 100644 libgloss/mips/include/mips/mips64.h > create mode 100644 libgloss/mips/include/mips/mt.h > create mode 100644 libgloss/mips/include/mips/notlb.h > create mode 100644 libgloss/mips/include/mips/prid.h > create mode 100644 libgloss/mips/include/mips/regdef.h > create mode 100644 libgloss/mips/include/mips/version.h > create mode 100644 libgloss/mips/malta32-yamon.ld > delete mode 100644 libgloss/mips/syscalls.c > create mode 100644 libgloss/mips/uhi32.ld > create mode 100644 libgloss/mips/uhi64_64.ld > create mode 100644 libgloss/mips/uhi64_n32.ld > > diff --git a/libgloss/config/mips.mt b/libgloss/config/mips.mt > index 6ae84b44f..814caf957 100644 > --- a/libgloss/config/mips.mt > +++ b/libgloss/config/mips.mt > @@ -29,3 +29,22 @@ unlink.o: ${srcdir}/../unlink.c > $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $? > write.o: ${srcdir}/../write.c > $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $? > + > +get_ram_range.o: ${srcdir}/hal/get_ram_range.c > + $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $? > +link.o: $(srcdir)/hal/link.c > + $(CC) $(CFLAGS_FOR_TARGET) -O2 $(INCLUDES) -c $(CFLAGS) $? > + > +# Exception and interrupt handling support > +mips_excpt_handler.o: $(srcdir)/hal/mips_excpt_handler.c > + $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -DVERBOSE_EXCEPTIONS=1 > -O2 $(INCLUDES) -c $(CFLAGS) $< > +mips_excpt_handler_quiet.o: $(srcdir)/hal/mips_excpt_handler.c > + $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c > $(CFLAGS) $< -o $@ > +%.o: $(srcdir)/hal/%.S > + $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c > $(CFLAGS) $< -o $@ > +%.o: $(srcdir)/hal/%.c > + $(CC) $(CFLAGS_FOR_TARGET) $(HALINCLUDE) -O2 $(INCLUDES) -c > $(CFLAGS) $< -o $@ > +mips_excpt_isr_0.o: > + $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $(HALINCLUDE) -c > -DDEF=__isr_vec_0 -DREF=__isr_vec_0 -DISR=_mips_isr_0 -DZERO > ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@ > +mips_excpt_isr_%.o: > + $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) $(HALINCLUDE) -c > -DDEF=__isr_vec_$* -DREF=__isr_vec_$(shell expr $* - 1) -DISR=_mips_isr_$* > ${srcdir}/hal/mips_excpt_isr_fragment.S -o $@ > diff --git a/libgloss/fstat.c b/libgloss/fstat.c > index c9d14d103..d8f94af6f 100644 > --- a/libgloss/fstat.c > +++ b/libgloss/fstat.c > @@ -19,6 +19,9 @@ > * fstat -- Since we have no file system, we just return an error. > */ > int > +#if defined(__mips__) && defined(__mips16) > +__attribute__((nomips16)) > +#endif > fstat (int fd, > struct stat *buf) > { > diff --git a/libgloss/libnosys/fstat.c b/libgloss/libnosys/fstat.c > index c85b9f209..e3d4cec64 100644 > --- a/libgloss/libnosys/fstat.c > +++ b/libgloss/libnosys/fstat.c > @@ -13,6 +13,9 @@ extern int errno; > #include "warning.h" > > int > +#if defined(__mips__) && defined(__mips16) > +__attribute__((nomips16)) > +#endif > _fstat (int fildes, > struct stat *st) > { > diff --git a/libgloss/mips/Makefile.in b/libgloss/mips/Makefile.in > index 4213a1d1f..65581ec71 100644 > --- a/libgloss/mips/Makefile.in > +++ b/libgloss/mips/Makefile.in > @@ -77,11 +77,44 @@ JMR3904OBJS = jmr3904-io.o @MIPS_PART_SPECIFIC_OBJ@ > ${GENOBJS} ${GENOBJS2} > CFEOBJS = cfe.o cfe_api.o cfe_mem.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS} > ${GENOBJS2} > CYGMONOBJS = open.o close.o cygmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS} > > +define GENISROBJ > +$(eval ISROBJS:=)\ > +$(if $(filter ${1},0),,\ > +$(call GENISROBJ_DO,${1})\ > +)\ > +$(eval ISROBJS+=mips_excpt_isr_fallback.o) > +endef > + > +define GENISROBJ_DO > +$(if $(word ${1}, ${ISROBJS}),,\ > +$(eval ISROBJS+=mips_excpt_isr_$(words $(ISROBJS)).o)\ > + $(call GENISROBJ_DO,${1})\ > +) > +endef > + > +$(call GENISROBJ,256) > + > +HALOBJ = mips64_tlb.o mips_clean_cache.o mips_flush_cache.o mips_l2size.o > \ > + mips_lock_cache.o mips_size_cache.o mips_sync_cache.o mips_tlb.o \ > + mips_fp.o mips_msa.o \ > + mips_excpt_entry.o mips_excpt_handler.o mips_excpt_handler_quiet.o \ > + mips_excpt_register.o mips_excpt_boot.o mips_xpa.o \ > + mips_intctrl.o $(ISROBJS) > + > +HALINCLUDE = -I $(srcdir)/include > + > +CM3OBJ_IMPL = mips_cm3_l2size.o init_cm3l2.o > + > +CM3AR = libcm3.a > + > # Nullmon cannot support read and write, but the test cases pull them in > via libs > NULLMONOBJS = nullmon.o @MIPS_PART_SPECIFIC_OBJ@ ${GENOBJS} > > CFLAGS = -g > > +EXAMPLES = custom_excpt fault_recovery interrupt_handler isr_vector_space > \ > + romable romable_minimal romable_predef romable_predef_xip > + > GCC_LDFLAGS = `if [ -d ${objroot}/../gcc ] ; \ > then echo -L${objroot}/../gcc ; fi` > > diff --git a/libgloss/mips/crt0.S b/libgloss/mips/crt0.S > deleted file mode 100644 > index 254998242..000000000 > --- a/libgloss/mips/crt0.S > +++ /dev/null > @@ -1,316 +0,0 @@ > -/* > - * crt0.S -- startup file for MIPS. > - * > - * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support > - * > - * The authors hereby grant permission to use, copy, modify, distribute, > - * and license this software and its documentation for any purpose, > provided > - * that existing copyright notices are retained in all copies and that > this > - * notice is included verbatim in any distributions. No written agreement, > - * license, or royalty fee is required for any of the authorized uses. > - * Modifications to this software may be copyrighted by their authors > - * and need not follow the licensing terms described here, provided that > - * the new terms are clearly indicated on the first page of each file > where > - * they apply. > - */ > - > -/* This file does not use any floating-point ABI. */ > - .gnu_attribute 4,0 > - > -#ifdef __mips16 > -/* This file contains 32 bit assembly code. */ > - .set nomips16 > -#endif > - > -#include "regs.S" > -#include "abiflags.S" > - > -/* > - * Set up some room for a stack. We just grab a chunk of memory. > - */ > -#define STACK_SIZE 0x4000 > -#define GLOBAL_SIZE 0x2000 > - > -#define STARTUP_STACK_SIZE 0x0100 > - > -/* This is for referencing addresses that are not in the .sdata or > - .sbss section under embedded-pic, or before we've set up gp. */ > -#ifdef __mips_embedded_pic > -# ifdef __mips64 > -# define LA(t,x) la t,x-PICBASE ; daddu t,s0,t > -# else > -# define LA(t,x) la t,x-PICBASE ; addu t,s0,t > -# endif > -#else /* __mips_embedded_pic */ > -# define LA(t,x) la t,x > -#endif /* __mips_embedded_pic */ > - > - .comm __memsize, 12 > - .comm __lstack, STARTUP_STACK_SIZE > - > - .text > - .align 2 > - > -/* Without the following nop, GDB thinks _start is a data variable. > - * This is probably a bug in GDB in handling a symbol that is at the > - * start of the .text section. > - */ > - nop > - > - .globl hardware_hazard_hook .text > - .globl _start > - .ent _start > -_start: > -#ifdef __mips_embedded_pic > -#define PICBASE start_PICBASE > - .set noreorder > - PICBASE = .+8 > - bal PICBASE > - nop > - move s0,$31 > - .set reorder > -#endif > -#if __mips<3 > -# define STATUS_MASK (SR_CU1|SR_PE) > -#else > -/* Post-mips2 has no SR_PE bit. */ > -# ifdef __mips64 > -/* Turn on 64-bit addressing and additional float regs. */ > -# define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX) > -# else > -# if __mips_fpr==32 > -# define STATUS_MASK (SR_CU1) > -# else > -/* Turn on additional float regs. */ > -# define STATUS_MASK (SR_CU1|SR_FR) > -# endif > -# endif > -#endif > - > - /* Clear Cause register. */ > - mtc0 zero,C0_CAUSE > - nop > - > - /* Read MIPS_abiflags structure and set status/config registers > - accordingly. */ > - .weak __MIPS_abiflags_start > - .weak __MIPS_abiflags_end > - LA (t0,__MIPS_abiflags_start) > - LA (t1,__MIPS_abiflags_end) > - addiu t1,t1,-24 > - move v0,zero /* Mask for C0_SR. */ > - > - /* Branch to 1f is the .MIPS.abiflags section is not 24 bytes. > This > - indicates it is either missing or corrupt. */ > - bne t0,t1,1f > - > - /* Check isa_level. */ > - lbu t1,ABIFlags_isa_level(t0) > - sltu v1,t1,3 /* Is MIPS < 3? */ > - xori t1,t1,64 /* Is MIPS64? */ > - beq v1,zero,4f > - li v1,SR_PE > - or v0,v0,v1 /* Enable soft reset. */ > -4: > - li v1,(SR_KX|SR_SX|SR_UX) > - bne t1,zero,5f > - or v0,v0,v1 /* Enable extended addressing. */ > -5: > - /* Check fp_abi. */ > - lbu t1,ABIFlags_fp_abi(t0) > - xori t1,t1,Val_GNU_MIPS_ABI_FP_SOFT > - li v1,SR_CU1 > - beq t1,zero,2f /* Skip MSA and cpr1_size checks. > */ > - or v0,v0,v1 /* Enable co-processor 1. */ > - > - /* Check cpr1_size. */ > - lbu t1,ABIFlags_cpr1_size(t0) > - xori t1,t1,AFL_REG_64 > - li v1,SR_FR > - bne t1,zero,3f > - or v0,v0,v1 /* Enable 64-bit FPU registers. */ > -3: > - /* Check ases. */ > - lw t1,ABIFlags_ases(t0) > - andi t1,t1,AFL_ASE_MSA > - li v1,SR_FR > - beq t1,zero,2f > - or v0,v0,v1 /* Enable 64-bit FPU registers. */ > - li v1,SR_MSA > - .set push > - .set mips32 > - mtc0 v1,C0_CONFIG,5 /* Enable MSA. */ > - .set pop > - b 2f > - > -1: > - /* MIPS_abiflags structure is not available. Set status/config > - registers based on flags defined by compiler. */ > -#ifdef __mips_soft_float > - li v0,(STATUS_MASK-(STATUS_MASK & SR_CU1)) > -#else > - li v0,STATUS_MASK > -#endif > - > -2: > - /* Set C0_SR, */ > - mtc0 v0,C0_SR > - nop > - > - /* Avoid hazard from C0_SR changes. */ > - LA (t0, hardware_hazard_hook) > - beq t0,zero,2f > - jalr t0 > -2: > - > - > -/* Fix high bits, if any, of the PC so that exception handling doesn't get > - confused. */ > - LA (v0, 3f) > - jr v0 > -3: > - LA (gp, _gp) # set the global data > pointer > - .end _start > - > -/* > - * zero out the bss section. > - */ > - .globl __memsize > - .globl get_mem_info .text > - .globl __stack > - .globl __global > - .ent zerobss > -zerobss: > - LA (v0, _fbss) > - LA (v1, _end) > - beq v0,v1,2f > -1: > - addiu v0,v0,4 > - sw zero,-4(v0) > - bne v0,v1,1b > -2: > - la t0, __lstack # make a small stack so we > - addiu sp, t0, STARTUP_STACK_SIZE # can run some C code > - la a0, __memsize # get the usable memory > size > - jal get_mem_info > - > - /* setup the stack pointer */ > - LA (t0, __stack) # is __stack set ? > - bne t0,zero,4f > - > - /* NOTE: a0[0] contains the amount of memory available, and > - not the last memory address. */ > - la a0, __memsize > - lw t0,0(a0) # last address of memory > available > - la t1,K0BASE # cached kernel memory > - addu t0,t0,t1 # get the end of memory > address > - /* Allocate 32 bytes for the register parameters. Allocate 16 > - bytes for a null argv and envp. Round the result up to 64 > - bytes to preserve alignment. */ > - subu t0,t0,64 > -4: > - move sp,t0 # set stack pointer > - .end zerobss > - > -/* > - * initialize target specific stuff. Only execute these > - * functions it they exist. > - */ > - .globl hardware_init_hook .text > - .globl software_init_hook .text > - .type _fini,@function > - .type _init,@function > - .globl atexit .text > - .globl exit .text > - .ent init > -init: > - LA (t9, hardware_init_hook) # init the hardware if > needed > - beq t9,zero,6f > - jalr t9 > -6: > - LA (t9, software_init_hook) # init the hardware if > needed > - beq t9,zero,7f > - jalr t9 > -7: > - LA (a0, _fini) > - jal atexit > - > -#ifdef GCRT0 > - .globl _ftext > - .globl _extext > - LA (a0, _ftext) > - LA (a1, _etext) > - jal monstartup > -#endif > - > - > - jal _init # run global constructors > - > - addiu a1,sp,32 # argv = sp + 32 > - addiu a2,sp,40 # envp = sp + 40 > -#if __mips64 > - sd zero,(a1) # argv[argc] = 0 > - sd zero,(a2) # envp[0] = 0 > -#else > - sw zero,(a1) > - sw zero,(a2) > -#endif > - move a0,zero # set argc to 0 > - jal main # call the program start > function > - > - # fall through to the "exit" routine > - move a0,v0 # pass through the exit > code > - jal exit # call libc exit to run > the G++ > - # destructors > - .end init > - > - > -/* Assume the PICBASE set up above is no longer valid below here. */ > -#ifdef __mips_embedded_pic > -#undef PICBASE > -#endif > - > -/* > - * _exit -- Exit from the application. Normally we cause a user trap > - * to return to the ROM monitor for another run. NOTE: This is > - * the only other routine we provide in the crt0.o object, since > - * it may be tied to the "_start" routine. It also allows > - * executables that contain a complete world to be linked with > - * just the crt0.o object. > - */ > - .globl hardware_exit_hook .text > - .globl _exit > - .ent _exit > -_exit: > -7: > -#ifdef __mips_embedded_pic > - /* Need to reinit PICBASE, since we might be called via exit() > - rather than via a return path which would restore old s0. */ > -#define PICBASE exit_PICBASE > - .set noreorder > - PICBASE = .+8 > - bal PICBASE > - nop > - move s0,$31 > - .set reorder > -#endif > -#ifdef GCRT0 > - LA (t0, _mcleanup) > - jalr t0 > -#endif > - LA (t0, hardware_exit_hook) > - beq t0,zero,1f > - jalr t0 > -1: > - > - # break instruction can cope with 0xfffff, but GAS limits the > range: > - break 1023 > - b 7b # but loop back just > in-case > - .end _exit > - > -/* Assume the PICBASE set up above is no longer valid below here. */ > -#ifdef __mips_embedded_pic > -#undef PICBASE > -#endif > - > -/* EOF crt0.S */ > diff --git a/libgloss/mips/examples/romable_predef_xip/Makefile > b/libgloss/mips/examples/romable_predef_xip/Makefile > new file mode 100644 > index 000000000..c95b186db > --- /dev/null > +++ b/libgloss/mips/examples/romable_predef_xip/Makefile > @@ -0,0 +1,107 @@ > +# Copyright 2015, Imagination Technologies Limited and/or its > +# affiliated group companies. > +# All rights reserved. > +# > +# Redistribution and use in source and binary forms, with or without > +# modification, are permitted provided that the following conditions are > met: > +# > +# 1. Redistributions of source code must retain the above copyright > notice, > +# this list of conditions and the following disclaimer. > +# 2. Redistributions in binary form must reproduce the above copyright > notice, > +# this list of conditions and the following disclaimer in the > documentation > +# and/or other materials provided with the distribution. > +# 3. Neither the name of the copyright holder nor the names of its > +# contributors may be used to endorse or promote products derived from > this > +# software without specific prior written permission. > +# > +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > +# POSSIBILITY OF SUCH DAMAGE. > + > +# Variables that mipshal.mk will expand to compiler/linker arguments > must be > +# defined before inclusion of mipshal.mk > + > +# Indicate the application should start via the reset vector > +ROMABLE = 1 > + > +ifeq ($(CORE), P5600) > + DEFINES = -DC0_CONFIG0_VALUE=0xB6040483 > + DEFINES += -DC0_CONFIG1_VALUE=0xFEA3519B > + DEFINES += -DC0_CONFIG2_VALUE=0x80000000 > + DEFINES += -DC0_CONFIG3_VALUE=0xBF8032A8 > + DEFINES += -DC0_CONFIG4_VALUE=0xc01c0000 > + DEFINES += -DC0_CONFIG5_VALUE=0x10000038 > + DEFINES += -DC0_WATCHHI_VALUE=0x00000000 > + OBJS += init_l23caches_predef.o > + override ABI = 32 > + override ENDIAN = EL > + override MIPS_TOOLCHAIN = mips-mti-elf > + APP_START = 0x80000000 > +else > + ifeq ($(CORE), I6400) > + DEFINES = -DC0_CONFIG0_VALUE=0x80004A05 > + DEFINES += -DC0_CONFIG1_VALUE=0x9EAB559B > + DEFINES += -DC0_CONFIG2_VALUE=0x80000000 > + DEFINES += -DC0_CONFIG3_VALUE=0xFC8031E9 > + DEFINES += -DC0_CONFIG4_VALUE=0xD0FC0227 > + DEFINES += -DC0_CONFIG5_VALUE=0x00000098 > + DEFINES += -DC0_WATCHHI_VALUE=0x80000000 > + DEFINES += -DC0_WATCHHI1_VALUE=0x80000000 > + DEFINES += -DC0_WATCHHI2_VALUE=0x80000000 > + DEFINES += -DC0_WATCHHI3_VALUE=0x00000000 > + DEFINES += -DC0_CMGCRBASE_VALUE=0x01fbf800 > + DEFINES += -DGCR_L2_CONFIG_VALUE=0x00000000 > + OBJS = init_cm3l2_predef.o > + override ABI = 64 > + override ENDIAN = EL > + override MIPS_TOOLCHAIN = mips-img-elf > + APP_START = 0xFFFFFFFF80000000 > + else > + $(error Please specify a core using CORE=(P5600|I6400)) > + endif > +endif > + > +include ${MIPS_ELF_ROOT}/share/mips/rules/mipshal.mk > + > +ifeq ($(ENABLE_XPA), 1) > + DEFINES += -DENABLE_XPA=1 > +endif > + > +OBJS += romable_predef_xip.o reset_predef.o init_caches_predef.o > init_cp0_predef.o > +OBJS += init_tlb_predef.o corecheck_predef.o > +APP = romable_predef_xip.elf > + > +CFLAGS += -g -O1 $(DEFINES) > +LDFLAGS += -g -Wl,--defsym,__getargs=0 > -Wl,--defsym,__exception_handle_verbose=0 > +LDFLAGS += -Wl,--defsym,__register_excpt_boot=0 > -Wl,--defsym,__exception_entry=0 > +LDFLAGS += -Wl,--defsym,__register_excpt_handler=0 > +LDFLAGS += -Wl,--defsym,__isr_vec_007=0 -Wl,--defsym,__uhi_break=0 > +LDFLAGS += -Wl,--defsym,__ebase_size=0 -Wl,--defsym,__isr_vec_count=0 > +LDFLAGS += -Wl,--defsym,__xip=1 > +LDFLAGS += -nostartfiles -nostdlib > + > +all: $(APP) > + > +$(APP): $(OBJS) crt0.o > + $(LD) $(LDFLAGS) $(OBJS) -o $@ > + > +%.o: %.c > + $(CC) $(CFLAGS) -c $^ -o $@ > + > +crt0.o: $(MIPS_ELF_ROOT)/share/mips/hal/minicrt.S > + $(CC) $(CFLAGS) -c $^ -o $@ > + > +%.o: $(MIPS_ELF_ROOT)/share/mips/boot/%.S > + $(CC) $(CFLAGS) -c $^ -o $@ > + > +.PHONY: clean > +clean: > + rm -f $(APP) $(OBJS) crt0.o > diff --git a/libgloss/mips/examples/romable_predef_xip/README.txt > b/libgloss/mips/examples/romable_predef_xip/README.txt > new file mode 100644 > index 000000000..082e8c362 > --- /dev/null > +++ b/libgloss/mips/examples/romable_predef_xip/README.txt > @@ -0,0 +1,21 @@ > +Demonstration of a bootable example built for a specific cpu core, either > the > +P5600 or I6400, relying on compile time CONFIG_XXX values for compile time > +specialization. This variant produces boot code that eXecutes In Place > (XIP) > +rather than copying code to RAM first. It also eliminates all C runtime > +support code leading to a very thin image which puts restrictions on what > C > +features can be used. For example any code reliant on the HEAP is > unsupported, > +constructors and destructors are unsupported and almost all standard > library > +functions are unavailable for the above reasons. > + > +Set environment variable MIPS_ELF_ROOT > + This should be set to the root of the installation directory for > the > + toolchain (that is, below the bin directory) > + > +To build for the P5600 > + # make CORE=P5600 > + > +To build for the I6400 > + # make CORE=I6400 > + > +To delete temporary and built files > + # make clean CORE=P5600 > diff --git > a/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c > b/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c > new file mode 100644 > index 000000000..b436eaed1 > --- /dev/null > +++ b/libgloss/mips/examples/romable_predef_xip/romable_predef_xip.c > @@ -0,0 +1,35 @@ > +/* > + * Copyright 2015, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +int > +main () > +{ > + return 0; > +} > diff --git a/libgloss/mips/fstat.c b/libgloss/mips/fstat.c > new file mode 100644 > index 000000000..d8f94af6f > --- /dev/null > +++ b/libgloss/mips/fstat.c > @@ -0,0 +1,32 @@ > +/* fstat.c -- get status of a file. > + * > + * Copyright (c) 1995 Cygnus Support > + * > + * The authors hereby grant permission to use, copy, modify, distribute, > + * and license this software and its documentation for any purpose, > provided > + * that existing copyright notices are retained in all copies and that > this > + * notice is included verbatim in any distributions. No written agreement, > + * license, or royalty fee is required for any of the authorized uses. > + * Modifications to this software may be copyrighted by their authors > + * and need not follow the licensing terms described here, provided that > + * the new terms are clearly indicated on the first page of each file > where > + * they apply. > + */ > +#include <sys/stat.h> > +#include "glue.h" > + > +/* > + * fstat -- Since we have no file system, we just return an error. > + */ > +int > +#if defined(__mips__) && defined(__mips16) > +__attribute__((nomips16)) > +#endif > +fstat (int fd, > + struct stat *buf) > +{ > + buf->st_mode = S_IFCHR; /* Always pretend to be a tty */ > + buf->st_blksize = 0; > + > + return (0); > +} > diff --git a/libgloss/mips/hal/__exit.c b/libgloss/mips/hal/__exit.c > new file mode 100644 > index 000000000..d6f7c1a3b > --- /dev/null > +++ b/libgloss/mips/hal/__exit.c > @@ -0,0 +1,50 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +/* > + * @Synopsis void __exit (int32_t exit_code); > + * > + * Parameters: > + * $4 - Exit code > + * > + * Return: > + * None > + * > + * @Description Transfer control to the debug port > +*/ > + > +#include <stdint.h> > + > +void > +__exit (int32_t exit_code) > +{ > + return; > +} > + > diff --git a/libgloss/mips/hal/abiflags.S b/libgloss/mips/hal/abiflags.S > new file mode 100644 > index 000000000..953caafb4 > --- /dev/null > +++ b/libgloss/mips/hal/abiflags.S > @@ -0,0 +1,82 @@ > +/* > + * abiflags.S - MIPS ABI flags. > + */ > + > +/* Values for the xxx_size bytes of an ABI flags structure. */ > +#define AFL_REG_NONE 0x00 /* No registers. */ > +#define AFL_REG_32 0x01 /* 32-bit registers. */ > +#define AFL_REG_64 0x02 /* 64-bit registers. */ > +#define AFL_REG_128 0x03 /* 128-bit registers. */ > + > +/* Masks for the ases word of an ABI flags structure. */ > +#define AFL_ASE_DSP 0x00000001 /* DSP ASE. */ > +#define AFL_ASE_DSPR2 0x00000002 /* DSP R2 ASE. */ > +#define AFL_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */ > +#define AFL_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */ > +#define AFL_ASE_MDMX 0x00000010 /* MDMX ASE. */ > +#define AFL_ASE_MIPS3D 0x00000020 /* MIPS-3D ASE. */ > +#define AFL_ASE_MT 0x00000040 /* MT ASE. */ > +#define AFL_ASE_SMARTMIPS 0x00000080 /* SmartMIPS ASE. */ > +#define AFL_ASE_VIRT 0x00000100 /* VZ ASE. */ > +#define AFL_ASE_MSA 0x00000200 /* MSA ASE. */ > +#define AFL_ASE_MIPS16 0x00000400 /* MIPS16 ASE. */ > +#define AFL_ASE_MICROMIPS 0x00000800 /* MICROMIPS ASE. */ > +#define AFL_ASE_XPA 0x00001000 /* XPA ASE. */ > + > +/* Values for the isa_ext word of an ABI flags structure. */ > +#define AFL_EXT_XLR 1 /* RMI Xlr instruction. */ > +#define AFL_EXT_OCTEON2 2 /* Cavium Networks Octeon2. */ > +#define AFL_EXT_OCTEONP 3 /* Cavium Networks OcteonP. */ > +#define AFL_EXT_LOONGSON_3A 4 /* Loongson 3A. */ > +#define AFL_EXT_OCTEON 5 /* Cavium Networks Octeon. */ > +#define AFL_EXT_5900 6 /* MIPS R5900 instruction. */ > +#define AFL_EXT_4650 7 /* MIPS R4650 instruction. */ > +#define AFL_EXT_4010 8 /* LSI R4010 instruction. */ > +#define AFL_EXT_4100 9 /* NEC VR4100 instruction. */ > +#define AFL_EXT_3900 10 /* Toshiba R3900 instruction. */ > +#define AFL_EXT_10000 11 /* MIPS R10000 instruction. */ > +#define AFL_EXT_SB1 12 /* Broadcom SB-1 instruction. */ > +#define AFL_EXT_4111 13 /* NEC VR4111/VR4181 instruction. */ > +#define AFL_EXT_4120 14 /* NEC VR4120 instruction. */ > +#define AFL_EXT_5400 15 /* NEC VR5400 instruction. */ > +#define AFL_EXT_5500 16 /* NEC VR5500 instruction. */ > +#define AFL_EXT_LOONGSON_2E 17 /* ST Microelectronics Loongson 2E. */ > +#define AFL_EXT_LOONGSON_2F 18 /* ST Microelectronics Loongson 2F. */ > + > +/* Values defined for Tag_GNU_MIPS_ABI_FP. */ > +#define Val_GNU_MIPS_ABI_FP_ANY 0 /* Not tagged or not using any ABIs > affected by the differences. */ > +#define Val_GNU_MIPS_ABI_FP_DOUBLE 1 /* Using hard-float > -mdouble-float. */ > +#define Val_GNU_MIPS_ABI_FP_SINGLE 2 /* Using hard-float > -msingle-float. */ > +#define Val_GNU_MIPS_ABI_FP_SOFT 3 /* Using soft-float. */ > +#define Val_GNU_MIPS_ABI_FP_OLD_64 4 /* Using -mips32r2 -mfp64. */ > +#define Val_GNU_MIPS_ABI_FP_XX 5 /* Using -mfpxx */ > +#define Val_GNU_MIPS_ABI_FP_64 6 /* Using -mips32r2 -mfp64. */ > +#define Val_GNU_MIPS_ABI_MSA_ANY 0 /* Not tagged or not using any ABIs > affected by the differences. */ > +#define Val_GNU_MIPS_ABI_MSA_128 1 /* Using 128-bit MSA. */ > + > +/* MIPS ABI flags structure */ > + .struct 0 > +ABIFlags_version: > + .struct ABIFlags_version + 2 > +ABIFlags_isa_level: > + .struct ABIFlags_isa_level + 1 > +ABIFlags_isa_rev: > + .struct ABIFlags_isa_rev + 1 > +ABIFlags_gpr_size: > + .struct ABIFlags_gpr_size + 1 > +ABIFlags_cpr1_size: > + .struct ABIFlags_cpr1_size + 1 > +ABIFlags_cpr2_size: > + .struct ABIFlags_cpr2_size + 1 > +ABIFlags_fp_abi: > + .struct ABIFlags_fp_abi + 1 > +ABIFlags_isa_ext: > + .struct ABIFlags_isa_ext + 4 > +ABIFlags_ases: > + .struct ABIFlags_ases + 4 > +ABIFlags_flags1: > + .struct ABIFlags_flags1 + 4 > +ABIFlags_flags2: > + .struct ABIFlags_flags2 + 4 > + > +/*> EOF abiflags.S <*/ > diff --git a/libgloss/mips/hal/cache.h b/libgloss/mips/hal/cache.h > new file mode 100644 > index 000000000..a8350cc95 > --- /dev/null > +++ b/libgloss/mips/hal/cache.h > @@ -0,0 +1,84 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#define __MIPS_NO_IMPLICIT_EHB /* No implicit EHB after mtc0 */ > +#include <mips/cpu.h> > +#include <mips/cm3.h> > +#include <mips/m32c0.h> > +#include <mips/m64c0.h> > +#include <mips/hal.h> > + > +#if defined(__mips64) || (__mips == 64) > +#define mips_getentryhi() mips64_getentryhi() > +#define mips_setentryhi(v) mips64_setentryhi(v) > +#define mips_getentrylo0() mips64_getentrylo0() > +#define mips_setentrylo0(v) mips64_setentrylo0(v) > +#define mips_getentrylo1() mips64_getentrylo1() > +#define mips_setentrylo1(v) mips64_setentrylo1(v) > +#define mips_getpagemask() mips64_getpagemask() > +#define mips_setpagemask(v) mips64_setpagemask(v) > +#define mips_getindex() mips64_getindex() > +#define mips_setindex(v) mips64_setindex(v) > +#define mips_getcmgcrbase() mips64_get_c0(C0_CMGCRBASE) > +#else > +#define mips_getentryhi() mips32_getentryhi() > +#define mips_setentryhi(v) mips32_setentryhi(v) > +#define mips_getentrylo0() mips32_getentrylo0() > +#define mips_setentrylo0(v) mips32_setentrylo0(v) > +#define mips_getentrylo1() mips32_getentrylo1() > +#define mips_setentrylo1(v) mips32_setentrylo1(v) > +#define mips_getpagemask() mips32_getpagemask() > +#define mips_setpagemask(v) mips32_setpagemask(v) > +#define mips_getindex() mips32_getindex() > +#define mips_setindex(v) mips32_setindex(v) > +#define mips_getcmgcrbase() mips32_get_c0(C0_CMGCRBASE) > +#endif > + > +static inline __attribute__((always_inline)) _MIPS_HAL_NOMIPS16 > +void mips_cache_op (vaddr_t kva, size_t n, int lsize, const int op) > +{ > + vaddr_t addr, maxaddr, mask; > + > + if (n <= 0) > + return; > + > + mask = ~ (lsize - 1); > + addr = (kva & mask) - lsize; > + maxaddr = ((kva + n) - 1) & mask; > + > + do > + { > + addr = addr + lsize; > + mips_cache (op, addr); > + } > + while (addr != maxaddr); > + > + return; > +} > diff --git a/libgloss/mips/hal/crt0.S b/libgloss/mips/hal/crt0.S > new file mode 100644 > index 000000000..07a5cc3ac > --- /dev/null > +++ b/libgloss/mips/hal/crt0.S > @@ -0,0 +1,313 @@ > +/* > + * crt0.S -- startup file for MIPS. > + * > + * Copyright (c) 1995, 1996, 1997, 2001 Cygnus Support > + * Copyright 2016-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * > + * The authors hereby grant permission to use, copy, modify, distribute, > + * and license this software and its documentation for any purpose, > provided > + * that existing copyright notices are retained in all copies and that > this > + * notice is included verbatim in any distributions. No written agreement, > + * license, or royalty fee is required for any of the authorized uses. > + * Modifications to this software may be copyrighted by their authors > + * and need not follow the licensing terms described here, provided that > + * the new terms are clearly indicated on the first page of each file > where > + * they apply. > + */ > + > +/* This file does not use any floating-point ABI. */ > + .gnu_attribute 4,0 > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include "abiflags.S" > + > +MIPS_NOMIPS16 > + > +#define STARTUP_STACK_SIZE 0x40 /* Temporary stack size to run C > code */ > + > + .section .startdata, "aw", @nobits > + .balign 16 > + .space STARTUP_STACK_SIZE > +__lstack: # Points to the end of the stack > +__ram_extent: > + .space 8 > + > + .data > + > + .balign SZREG > +__temp_space: /* Temporary space to save arguments */ > + .space SZREG * 3 > + > + .text > + .align 2 > + > +/* > + * Without the following nop, GDB thinks _start is a data variable. > + * This is probably a bug in GDB in handling a symbol that is at the > + * start of the .text section. > + */ > + nop > + > + .globl hardware_hazard_hook .text > + .globl _start > + .ent _start > +_start: > +#if __mips<3 > +# define STATUS_MASK (SR_CU1|SR_PE) > +#else > +/* Post-mips2 has no SR_PE bit. */ > +# ifdef __mips64 > +/* Turn on 64-bit addressing and additional float regs. */ > +# define STATUS_MASK (SR_CU1|SR_FR|SR_KX|SR_SX|SR_UX) > +# else > +# if __mips_fpr==32 > +# define STATUS_MASK (SR_CU1) > +# else > +/* Turn on additional float regs. */ > +# define STATUS_MASK (SR_CU1|SR_FR) > +# endif > +# endif > +#endif > + > + /* Save argument registers */ > + LA t0, __temp_space > + REG_S a0, (SZREG * 0)(t0) > + REG_S a1, (SZREG * 1)(t0) > + REG_S a2, (SZREG * 2)(t0) > + > + /* > + * Save k0, k1, ra and sp and register > + * default exception handler. > + */ > + .weak __register_excpt_handler > + LA t9, __register_excpt_handler > + beqz t9, 1f > + move a0, ra /* save ra */ > + jalr t9 > + b 2f > +1: > + /* Clear Cause register. */ > + mtc0 zero,C0_CAUSE > + move va0,zero /* Mask for C0_SR. */ > +2: > + /* Read MIPS_abiflags structure and set status/config registers > + accordingly. */ > + .weak __MIPS_abiflags_start > + .weak __MIPS_abiflags_end > + LA t0,__MIPS_abiflags_start > + LA t1,__MIPS_abiflags_end > + PTR_ADDU t1,t1,-24 > + > + /* Branch to 1f is the .MIPS.abiflags section is not 24 bytes. > This > + indicates it is either missing or corrupt. */ > + bne t0,t1,1f > + > + /* Check isa_level. */ > + lbu t1,ABIFlags_isa_level(t0) > + sltu t2,t1,3 /* Is MIPS < 3? */ > + xori t1,t1,64 /* Is MIPS64? */ > + beq t2,zero,3f > + li t2,SR_PE > + or va0,va0,t2 /* Enable soft reset. */ > +3: > + li t2,(SR_KX|SR_SX|SR_UX) > + bne t1,zero,3f > + or va0,va0,t2 /* Enable extended addressing. */ > +3: > + /* Check DSP,DSP2,MDMX ase. */ > + lw t1,ABIFlags_ases(t0) > + andi t1,t1,(AFL_ASE_DSP|AFL_ASE_DSPR2|AFL_ASE_MDMX) > + li t2,SR_MX > + beq t1,zero,3f > + or va0,va0,t2 > +3: > + /* Check fp_abi. */ > + lbu t1,ABIFlags_fp_abi(t0) > + xori t1,t1,Val_GNU_MIPS_ABI_FP_SOFT > + li t2,SR_CU1 > + beq t1,zero,2f /* Skip MSA and cpr1_size checks. > */ > + or va0,va0,t2 /* Enable co-processor 1. */ > + > + /* Check cpr1_size. */ > + lbu t1,ABIFlags_cpr1_size(t0) > + xori t1,t1,AFL_REG_64 > + li t2,SR_FR > + bne t1,zero,3f > + or va0,va0,t2 /* Enable 64-bit FPU registers. */ > +3: > + /* Check MSA ASE. */ > + lw t1,ABIFlags_ases(t0) > + andi t1,t1,AFL_ASE_MSA > + li t2,SR_FR > + beq t1,zero,2f > + or va0,va0,t2 /* Enable 64-bit FPU registers. */ > + li t2,CFG5_MSAEN > + mtc0 t2,C0_CONFIG,5 /* Enable MSA. */ > + b 2f > + > +1: > + /* MIPS_abiflags structure is not available. Set status/config > + registers based on flags defined by compiler. */ > +#ifdef __mips_soft_float > + li va0,(STATUS_MASK-(STATUS_MASK & SR_CU1)) > +#else > + li va0,STATUS_MASK > +#endif > + > +2: > + /* Set C0_SR, */ > + mtc0 va0,C0_SR > + ehb > + > + /* set the global data pointer */ > + LA gp, _gp > + .end _start > + > +/* > + * zero out the bss section. > + */ > + .globl _get_ram_info .text > + .globl __stack > + .globl __global > + .ent zerobss > +zerobss: > + LA t0, _fbss > + LA t1, _end > + beq t0,t1,1f > +2: > + PTR_ADDU t0,t0,4 > + sw zero,-4(t0) > + bne t0,t1,2b > +1: > + /* setup the stack pointer */ > + LA t0, __stack /* is __stack set? */ > + bne t0,zero,1f > + > + LA sp, __lstack /* make a small stack so > we can */ > + /* run some C code */ > + li a0,0 /* no need for the ram > base */ > + LA a1, __ram_extent /* storage for the extent > of ram */ > + jal _get_ram_range > + > + /* NOTE: a0[0] contains the last address+1 of memory. */ > + LA a0, __ram_extent > + PTR_L t0,0(a0) /* the extent of ram */ > + lw $0,-4(t0) /* check for valid memory > */ > + /* Allocate 32 bytes for the register parameters. Allocate 16 > + bytes for a null argv and envp. Round the result up to 64 > + bytes to preserve alignment. */ > +1: > + PTR_ADDU t0,t0,-64 > + move sp,t0 /* set stack pointer */ > + .end zerobss > + > +/* > + * initialize target specific stuff. Only execute these > + * functions it they exist. > + */ > + .globl hardware_init_hook .text > + .globl software_init_hook .text > + .type _fini,@function > + .type _init,@function > + .globl atexit .text > + .globl exit .text > + .ent init > +init: > + /* Init the hardware if needed */ > + LA t9, hardware_init_hook > + beq t9,zero,1f > + jalr t9 > +1: > + /* Init the software if needed */ > + LA t9, software_init_hook > + beq t9,zero,1f > + jalr t9 > +1: > + /* Register exit handlers */ > + LA a0, _fini > + jal atexit > + > + /* run global constructors */ > + jal _init > + > + /* Restore argument registers */ > + LA t0, __temp_space > + REG_L a0,(SZREG * 0)(t0) > + REG_L a1,(SZREG * 1)(t0) > + REG_L a2,(SZREG * 2)(t0) > + > + /* Convert pointers potentially */ > + .weak __convert_argv_pointers > + LA t0, __convert_argv_pointers > + beqz t0, 1f > + jalr t0 > +1: > + /* if a0 > 0 then we have arguments ready in a0 to a2 registers */ > + bgtz a0,.Lmain > + /* if a0 == 0 then no arguments have been set up */ > + beqz a0, 1f > + /* if a0 < -1 then we have undefined behaviour so assume no > + arguments have been set up */ > + addiu t0, a0, 1 > + bltz t0, 1f > + > + /* a0 == -1 */ > + .weak __getargs > + LA t0, __getargs > + beqz t0, 1f > + jalr t0 /* get arguments */ > + b .Lmain > +1: > + /* no arguments */ > + move a0,zero /* set argc to 0 */ > + PTR_ADDU a1,sp,32 /* argv = sp + 32 */ > + PTR_ADDU a2,sp,40 /* envp = sp + 40 */ > + REG_S zero,(a1) /* argv[argc] = 0 */ > + REG_S zero,(a2) /* envp[0] = 0 */ > + > +.Lmain: > + jal main /* call the program start > function */ > + move a0,va0 /* pass through the exit > code */ > + jal exit /* call libc exit to run > the G++ */ > + /* destructors */ > + .end init > + > +/* > + * _exit -- Exit from the application. Normally we cause a user trap > + * to return to the ROM monitor for another run. NOTE: This is > + * the only other routine we provide in the crt0.o object, since > + * it may be tied to the "_start" routine. It also allows > + * executables that contain a complete world to be linked with > + * just the crt0.o object. > + */ > + .globl hardware_exit_hook .text > + .globl _exit > + .ent _exit > +_exit: > +1: > + /* Save exit code */ > + LA t0, __temp_space > + REG_S a0,0(t0) > + > + LA t0, hardware_exit_hook > + beq t0,zero,2f > + jalr t0 > +2: > + > + /* Restore return value from main */ > + LA t0, __temp_space > + REG_L a0,0(t0) > + > + .global __exit .text > + jal __exit > + > + /* The BREAK instruction can cope with 0xfffff, but GAS limits the > + range */ > + break 1023 > + b 1b # but loop back just > in-case > + .end _exit > + > +/* EOF crt0.S */ > diff --git a/libgloss/mips/hal/get_ram_range.c > b/libgloss/mips/hal/get_ram_range.c > new file mode 100644 > index 000000000..0a484c303 > --- /dev/null > +++ b/libgloss/mips/hal/get_ram_range.c > @@ -0,0 +1,67 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <_ansi.h> > +#include <sys/types.h> > +#include <sys/stat.h> > + > +#if _MIPS_SIM == _ABI64 > +# define K0BASE 0xFFFFFFFF80000000LL > +#else > +# define K0BASE 0x80000000 > +#endif > +void > +_get_ram_range (void **ram_base, void **ram_extent) > +{ > + struct s_mem > + { > + unsigned int size; > + unsigned int icsize; > + unsigned int dcsize; > + } mem; > + void get_mem_info (struct s_mem*); > + > + /* The sizeof (s_mem.size) must be 4 bytes. The compiler should be > + able to eliminate this check */ > + if (sizeof (unsigned int) != 4) > + { > + *ram_extent = 0; > + return; > + } > + > + get_mem_info (&mem); > + > + /* NOTE: The value returned from the get_mem_info call is the amount > + of memory, and not the address of the (last byte + 1) */ > + > + if (ram_base) > + *ram_base = (void*)K0BASE; > + *ram_extent = (void*)(long)(K0BASE + mem.size); > +} > diff --git a/libgloss/mips/hal/libcm3.a b/libgloss/mips/hal/libcm3.a > new file mode 100644 > index 000000000..3d7534f57 > --- /dev/null > +++ b/libgloss/mips/hal/libcm3.a > @@ -0,0 +1,36 @@ > +/* > + * Copyright 2015, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +/* > + * libcm3.a - Create a reference to __cache_size_hook near the > + * start of the link to include the actual implementation. > + */ > +EXTERN (__cache_size_hook); > +GROUP(-lcm3_impl); > diff --git a/libgloss/mips/hal/link.c b/libgloss/mips/hal/link.c > new file mode 100644 > index 000000000..56254c0b1 > --- /dev/null > +++ b/libgloss/mips/hal/link.c > @@ -0,0 +1,41 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <errno.h> > + > +int > +link (const char *oldname, const char *newname) > +{ > + (void) oldname; > + (void) newname; > + errno = EIO; > + return -1; > +} > + > diff --git a/libgloss/mips/hal/minicrt.S b/libgloss/mips/hal/minicrt.S > new file mode 100644 > index 000000000..fa4759499 > --- /dev/null > +++ b/libgloss/mips/hal/minicrt.S > @@ -0,0 +1,31 @@ > +#include <mips/asm.h> > +#include <mips/regdef.h> > + > +LEAF(_start) > + /* Preserve return address */ > + move s0, ra > + /* Set up global pointer for small data access */ > + LA gp, _gp > + /* Set up stack pointer */ > + LA sp, __stack > + /* Zero the BSS */ > + LA v0, _fbss > + LA v1, _end > + beq v0,v1,2f > +1: > + addiu v0,v0,4 > + sw zero,-4(v0) > + bne v0,v1,1b > +2: > + /* Set arguments to be null for main */ > + li a0, 0 > + > + /* Reserve the ABI required argument area */ > + addiu sp, sp, -(NARGSAVE * SZARG) > + /* Jump to C code */ > + jal main > + > + /* Return to boot */ > + move ra, s0 > + jr ra > +END(_start) > diff --git a/libgloss/mips/hal/mips64_tlb.c > b/libgloss/mips/hal/mips64_tlb.c > new file mode 100644 > index 000000000..8bcaf1554 > --- /dev/null > +++ b/libgloss/mips/hal/mips64_tlb.c > @@ -0,0 +1,221 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > +#include <mips/hal.h> > + > +/* Writes hi, lo0, lo1 and mask into the TLB entry specified by index */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +m64_tlbwi2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1, > + unsigned long long mask, > + int index) > +{ > + mips64_setentryhi (hi); > + mips64_setentrylo0 (lo0); > + mips64_setentrylo1 (lo1); > + mips64_setpagemask (mask); > + mips64_setindex (index); > + mips_ehb (); > + mips_tlbwi (); > + return; > +} > + > +/* > + * Writes hi, lo0, lo1 and mask into the TLB entry specified by the > + * Random register. > +*/ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +m64_tlbwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1, > + unsigned long long mask) > +{ > + mips64_setentryhi (hi); > + mips64_setentrylo0 (lo0); > + mips64_setentrylo1 (lo1); > + mips64_setpagemask (mask); > + mips_ehb (); > + mips_tlbwr (); > + return; > +} > + > +/* > + * Probes the TLB for an entry matching hi and if present rewrites that > entry, > + * otherwise updates a random entry. A safe way to update the TLB. > +*/ > +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +m64_tlbrwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1, > + unsigned long long mask) > +{ > + tlbhi64_t prev_hi; > + int index; > + > + prev_hi = mips64_getentryhi (); > + mips64_setentryhi (hi); > + > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + > + index = mips64_getindex (); > + > + mips64_setentrylo0 (lo0); > + mips64_setentrylo1 (lo1); > + mips64_setpagemask (mask); > + > + mips_ehb (); /* mtc0 hazard on tlbwi/tlbwr */ > + > + if (index < 0) > + mips_tlbwr (); > + else > + mips_tlbwi (); > + > + mips64_setentryhi (prev_hi); > + > + return index; > +} > + > +/* > + * Reads the TLB entry specified index, and returns the EntryHi, > + * EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmask > + * respectively. > +*/ > +void _MIPS_HAL_NOMIPS16 > +m64_tlbri2 (tlbhi64_t *phi, tlblo64_t *plo0, tlblo64_t *plo1, > + unsigned long long *pmask, int index) > +{ > + mips64_setindex (index); > + mips_ehb (); /* mtc0 hazard on tlbr */ > + mips_tlbr (); > + mips_ehb (); /* tlbr hazard on mfc0 */ > + *phi = mips64_getentryhi (); > + *plo0 = mips64_getentrylo0 (); > + *plo1 = mips64_getentrylo1 (); > + *pmask = mips64_getpagemask (); > + return; > +} > + > +/* > + * Probes the TLB for an entry matching hi and returns its index, or -1 if > + * not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of > the > + * entry are also returned in *plo0, *plo1 and *pmask respectively. > +*/ > +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +m64_tlbprobe2 (tlbhi64_t hi, tlblo64_t *plo0, tlblo64_t *plo1, > + unsigned long long *pmask) > +{ > + tlbhi64_t prev_hi; > + int index; > + > + prev_hi = mips64_getentryhi (); > + mips64_setentryhi (hi); > + > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + > + index = mips64_getindex (); > + > + if (index >= 0) > + { > + mips_tlbr (); > + mips_ehb (); /* tlbr hazard on mfc0 */ > + *plo0 = mips64_getentrylo0 (); > + *plo1 = mips64_getentrylo1 (); > + *pmask = mips64_getpagemask (); > + } > + else > + index = -1; > + > + mips64_setentryhi (prev_hi); > + > + return index; > +} > + > +/* Probes the TLB for an entry matching hi, and if present invalidates it > */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +m64_tlbinval (tlbhi64_t hi) > +{ > + int index, tmp_idx; > + tlbhi64_t prev_hi, tmp_hi; > + register const unsigned long zero = 0; > + unsigned long cfg; > + > + prev_hi = mips64_getentryhi (); > + mips64_setentryhi (hi); > + > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + > + index = mips64_getindex (); > + > + if (index < 0) > + goto restore; > + > + mips64_setentrylo0 (zero); > + mips64_setentrylo1 (zero); > + > + /* Check if Config4 is implemented */ > + cfg = mips64_getconfig3 (); > + if ((cfg & CFG3_M) != 0) > + { > + cfg = mips64_getconfig4 (); > + if ((cfg & CFG4_IE_MASK) != 0) > + { > + tmp_hi = C0_ENTRYHI_EHINV_MASK; > + goto do_tlbwi; > + } > + } > + > + tmp_hi = (tlbhi64_t) ((unsigned long) KSEG0_BASE - 0x4000); > + > + do > + { > + tmp_hi = tmp_hi + 0x4000; > + mips64_setentryhi (tmp_hi); > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + tmp_idx = mips64_getindex (); > + } > + while (tmp_idx >= 0); > + > + mips64_setindex (index); /* restore Index */ > + > +do_tlbwi: > + mips64_setentryhi (tmp_hi); > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbwi (); > + mips_ehb (); /* tlbwi hazard on mfc0 */ > + > +restore: > + mips64_setentryhi (prev_hi); /* restore EntryHi */ > + > + return; > +} > diff --git a/libgloss/mips/hal/mips_clean_cache.c > b/libgloss/mips/hal/mips_clean_cache.c > new file mode 100644 > index 000000000..2b98307f3 > --- /dev/null > +++ b/libgloss/mips/hal/mips_clean_cache.c > @@ -0,0 +1,115 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <mips/hal.h> > +#include "cache.h" > + > +/* Writeback and invalidate address range in all caches */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_clean_cache (vaddr_t kva, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If D-cache is present */ > + if (mips_dcache_linesize > 0) > + mips_cache_op (kva, n, mips_dcache_linesize, Hit_Writeback_Inv_D); > + > + /* If I-cache is present */ > + if (mips_icache_linesize > 0) > + mips_cache_op (kva, n, mips_icache_linesize, Hit_Invalidate_I); > + > + /* If L2-cache is present */ > + if (mips_scache_linesize > 0) > + mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S); > + > + mips_sync (); > + return; > +} > + > +/* Writeback and invalidate address range in I-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_clean_icache (vaddr_t kva, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If I-cache is present */ > + if (mips_icache_linesize > 0) > + mips_cache_op (kva, n, mips_icache_linesize, Hit_Invalidate_I); > + > + /* If L2-cache is present */ > + if (mips_scache_linesize > 0) > + mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S); > + > + mips_sync (); > + return; > +} > + > +/* Writeback and invalidate address range in D-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_clean_dcache (vaddr_t kva, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If D-cache is present */ > + if (mips_dcache_linesize > 0) > + mips_cache_op (kva, n, mips_dcache_linesize, Hit_Writeback_Inv_D); > + > + /* If L2-cache is present */ > + if (mips_scache_linesize > 0) > + mips_cache_op (kva, n, mips_scache_linesize, Hit_Writeback_Inv_S); > + > + mips_sync (); > + return; > +} > + > +/* > + * Invalidate but don't writeback address range in data caches > + * Only safe if region is totally cache-line aligned. > +*/ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_clean_dcache_nowrite (vaddr_t kva, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If D-cache is present */ > + if (mips_dcache_linesize > 0) > + mips_cache_op (kva, n, mips_dcache_linesize, Hit_Invalidate_D); > + > + /* If L2-cache is present */ > + if (mips_scache_linesize > 0) > + mips_cache_op (kva, n, mips_scache_linesize, Hit_Invalidate_S); > + > + mips_sync (); > + return; > +} > diff --git a/libgloss/mips/hal/mips_cm3_l2size.c > b/libgloss/mips/hal/mips_cm3_l2size.c > new file mode 100644 > index 000000000..7006ecbeb > --- /dev/null > +++ b/libgloss/mips/hal/mips_cm3_l2size.c > @@ -0,0 +1,90 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > + > +_MIPS_HAL_NOMIPS16 > +void __def_cache_size_hook (void); > + > +/* > + * Routine for calculating L2 cache size from CM3 configuration > + * registers. Sizing information is stored directly to memory. > +*/ > +void _MIPS_HAL_NOMIPS16 > +__cache_size_hook (void) > +{ > + unsigned long cm_gcr_base, cm_gcr_l2_config; > + int associ; > + > + /* > + * Fall back to Config2 based L2 if Config3[M] or Config4[M] > + * or Config5[L2C] is not present. > + */ > + if ((mips32_getconfig3 () & CFG3_M) == 0 > + || (mips32_getconfig4 () & CFG4_M) == 0 > + || (mips32_getconfig5 () & CFG5_L2C) == 0) > + { > + __def_cache_size_hook (); > + return; > + } > + > + /* Read CMGCRBase to find CMGCR_BASE_ADDR */ > + cm_gcr_base = (mips_getcmgcrbase () << 4) | 0xB0000000UL; > + > + /* Read GCR_L2_CONFIG */ > + cm_gcr_l2_config = * ((unsigned long *) (cm_gcr_base + GCR_L2_CONFIG)); > + > + /* Extract line size */ > + mips_scache_linesize = (cm_gcr_l2_config & GCR_L2_SL_MASK) >> > GCR_L2_SL_SHIFT; > + > + /* Check for no cache */ > + if (mips_scache_linesize == 0) > + return; > + > + /* Now have true L2 line size */ > + mips_scache_linesize = 2 << mips_scache_linesize; > + > + /* Extract sets/way */ > + mips_scache_ways = (cm_gcr_l2_config & GCR_L2_SS_MASK) >> > GCR_L2_SS_SHIFT; > + > + /* Now we have true L2 sets/way */ > + mips_scache_ways = 64 << mips_scache_ways; > + > + /* Extract L2 associativity */ > + associ = (cm_gcr_l2_config & GCR_L2_SA_MASK) >> GCR_L2_SA_SHIFT; > + > + /* Get total number of sets */ > + associ = (associ + 1) * mips_scache_ways; > + > + /* L2 cache size */ > + mips_scache_size = mips_scache_linesize * associ; > + > + return; > +} > diff --git a/libgloss/mips/hal/mips_dsp.S b/libgloss/mips/hal/mips_dsp.S > new file mode 100644 > index 000000000..a383ba739 > --- /dev/null > +++ b/libgloss/mips/hal/mips_dsp.S > @@ -0,0 +1,130 @@ > +/* > + * Copyright 2016-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +.set nomips16 > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > +#include <mips/endian.h> > + > +# > +# FUNCTION: _dsp_save > +# DESCRIPTION: save the DSP context. > +# RETURNS: int > +# 0: No context saved > +# CTX_*: Type of conext stored > +# > +LEAF(_dsp_save) > + move a1, a0 > + PTR_S zero, LINKCTX_NEXT(a1) > + move va0, zero > + > + /* Test for DSP support */ > + mfc0 t0, C0_CONFIG3 > + ext t0, t0, CFG3_DSPP_SHIFT, 1 > + beqz t0, 1f > + > + /* Test for DSP enabled */ > + mfc0 t0, C0_STATUS > + ext t0, t0, SR_MX_SHIFT, 1 > + beqz t0, 1f > + > + li va0, LINKCTX_TYPE_DSP > + .set push > + .set dsp > + rddsp t1 > + mfhi t2, $ac1 > + mflo t3, $ac1 > + mfhi t4, $ac2 > + mflo t5, $ac2 > + mfhi t6, $ac3 > + mflo t7, $ac3 > + .set pop > + sw t1, DSPCTX_DSPC(a1) > + sw t2, DSPCTX_HI1(a1) > + sw t3, DSPCTX_LO1(a1) > + sw t4, DSPCTX_HI2(a1) > + sw t5, DSPCTX_LO2(a1) > + sw t6, DSPCTX_HI3(a1) > + sw t7, DSPCTX_LO3(a1) > + REG_S va0, LINKCTX_ID(a1) > +1: > + jr ra > +END(_dsp_save) > + > +# > +# FUNCTION: _dsp_load > +# DESCRIPTION: load the DSP context. > +# RETURNS: int > +# 0: Unrecognised context > +# CTX_*: Type of context restored > +# > +LEAF(_dsp_load) > + move a1, a0 > + REG_L va0, LINKCTX_ID(a1) > + li v1, LINKCTX_TYPE_DSP > + bne va0,v1,1f > + > + /* Test for DSP support */ > + mfc0 t0, C0_CONFIG3 > + ext t0, t0, CFG3_DSPP_SHIFT, 1 > + beqz t0, 1f > + > + /* Force on DSP */ > + di t3 > + ehb > + or t3, t3, SR_MX > + mtc0 t3, C0_STATUS > + ehb > + > + lw t1, DSPCTX_DSPC(a1) > + lw t2, DSPCTX_HI1(a1) > + lw t3, DSPCTX_LO1(a1) > + lw t4, DSPCTX_HI2(a1) > + lw t5, DSPCTX_LO2(a1) > + lw t6, DSPCTX_HI3(a1) > + lw t7, DSPCTX_LO3(a1) > + .set push > + .set dsp > + wrdsp t1 > + mthi t2, $ac1 > + mtlo t3, $ac1 > + mthi t4, $ac2 > + mtlo t5, $ac2 > + mthi t6, $ac3 > + mtlo t7, $ac3 > + .set pop > + jr ra > +1: > + /* Don't recognise this context, fail */ > + move va0, zero > + jr ra > +END(_dsp_load) > diff --git a/libgloss/mips/hal/mips_excpt_boot.S > b/libgloss/mips/hal/mips_excpt_boot.S > new file mode 100644 > index 000000000..08ab1b579 > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_boot.S > @@ -0,0 +1,381 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > +#include <mips/endian.h> > + > +MIPS_NOMIPS16 > + > + # Create space to store k0, k1, ra and sp > + .data > + .global __start_ctx > + .balign SZREG > +__start_ctx: > + .space SZREG * 18 > +#define start_ctx_sr (SZREG * 0) > +#define start_ctx_s0 (SZREG * 1) > +#define start_ctx_s1 (SZREG * 2) > +#define start_ctx_s2 (SZREG * 3) > +#define start_ctx_s3 (SZREG * 4) > +#define start_ctx_s4 (SZREG * 5) > +#define start_ctx_s5 (SZREG * 6) > +#define start_ctx_s6 (SZREG * 7) > +#define start_ctx_s7 (SZREG * 8) > +#define start_ctx_k0 (SZREG * 9) > +#define start_ctx_k1 (SZREG * 10) > +#define start_ctx_gp (SZREG * 11) > +#define start_ctx_sp (SZREG * 12) > +#define start_ctx_fp (SZREG * 13) > +#define start_ctx_ra (SZREG * 14) > +#define start_ctx_ictl (SZREG * 15) > +#define start_ctx_ebase (SZREG * 16) /* saved EBASE */ > +#define chain_ebase (SZREG * 17) /* chained EBASE */ > + > +#if defined (__mips_micromips) > + .space SZREG > +#define start_ctx_conf3 (SZREG * 18) /* saved Config3 $16,3 for > micromips */ > +#endif > + > +# > +# FUNCTION: void* __register_excpt_boot (void*, int, void*) > +# > +# DESCRIPTION: Save all boot state. Some state is already clobbered but > passed > +# in as arguments: > +# a0 = Boot ra > +# a1 = Boot SR > +# a2 = caller's RA (to be returned back) > +# > +WLEAF(__register_excpt_boot) > + .set push > + .set noat > + > + /* Save C0_SR IE and BEV */ > + LA t1, __start_ctx > + REG_S a0, start_ctx_ra(t1) > + REG_S a1, start_ctx_sr(t1) > + > + REG_S s0, start_ctx_s0(t1) > + REG_S s1, start_ctx_s1(t1) > + REG_S s2, start_ctx_s2(t1) > + REG_S s3, start_ctx_s3(t1) > + REG_S s4, start_ctx_s4(t1) > + REG_S s5, start_ctx_s5(t1) > + REG_S s6, start_ctx_s6(t1) > + REG_S s7, start_ctx_s7(t1) > + REG_S k0, start_ctx_k0(t1) > + REG_S k1, start_ctx_k1(t1) > + REG_S gp, start_ctx_gp(t1) > + REG_S sp, start_ctx_sp(t1) > + REG_S fp, start_ctx_fp(t1) > + > +#if defined (__mips_micromips) > + /* Save Config3 */ > + mfc0 t0, C0_CONFIG3 > + REG_S t0, start_ctx_conf3(t1) > +#endif > + mfc0 t0, C0_INTCTL > + REG_S t0, start_ctx_ictl(t1) > + > + /* Save C0_EBASE */ > + PTR_MFC0 t2, C0_EBASE > + REG_S t2, start_ctx_ebase(t1) > + > + /* Check if we booted with BEV==1 */ > + ext t3, a1, SR_BEV_SHIFT, 1 > + beqz t3, 1f > + > + /* > + * BEV==0 - set chain_ebase to 0xbfc00200 > + * Apply the offset of 0x200 so that the boot vector entries line > up > + * with the offsets in a non-boot vectora. > + */ > + li t2, 0xbfc00200 > + > + /* No - set chain_ebase to C0_EBASE */ > +1: REG_S t2, chain_ebase(t1) > + > + /* Return the third argument */ > + move va0, a2 > + jr ra > + > + .set pop > +WEND(__register_excpt_boot) > + > +# > +# FUNCTION: int __return_to_boot (int) > +# > +# DESCRIPTION: This is used if UHI EXIT was not handled. Return back to > +# caller of _start. > +# a0 = exit code to return to caller > +# > +WLEAF(__return_to_boot) > + .set push > + .set noat > + /* Disable interrupts for safety */ > + di > + ehb > + /* Set BEV=1 to allow changing EBASE */ > + mfc0 t0, C0_SR > + li t1, SR_BEV > + or t0, t0, t1 > + mtc0 t0, C0_SR > + ehb > + > + /* Restore C0_EBASE */ > + LA t0, __start_ctx > + REG_L t0, start_ctx_ebase(t0) > + /* Set the write gate to potentially change upper bits */ > + ori t1, t0, EBASE_WG > + PTR_MTC0 t1, C0_EBASE > + ehb > + /* Check if the write gate was set on startup */ > + andi t1, t0, EBASE_WG > + bnez t1, 1f > + > + /* If write gate wasn't set then clear the write gate again */ > + PTR_MTC0 t0, C0_EBASE > + ehb > + > +1: /* Restore original state */ > + LA t0, __start_ctx > + REG_L s0, start_ctx_s0(t0) > + REG_L s1, start_ctx_s1(t0) > + REG_L s2, start_ctx_s2(t0) > + REG_L s3, start_ctx_s3(t0) > + REG_L s4, start_ctx_s4(t0) > + REG_L s5, start_ctx_s5(t0) > + REG_L s6, start_ctx_s6(t0) > + REG_L s7, start_ctx_s7(t0) > + REG_L k0, start_ctx_k0(t0) > + REG_L k1, start_ctx_k1(t0) > + REG_L gp, start_ctx_gp(t0) > + REG_L sp, start_ctx_sp(t0) > + REG_L fp, start_ctx_fp(t0) > + REG_L ra, start_ctx_ra(t0) > + > +#if defined (__mips_micromips) > + /* Restore Config3 */ > + REG_L t1, start_ctx_conf3(t0) > + mtc0 t1, C0_CONFIG3 > +#endif > + /* Restore IntCtl */ > + REG_L t1, start_ctx_ictl(t0) > + mtc0 t1, C0_INTCTL > + > + REG_L t0, start_ctx_sr(t0) > + > + /* Restore C0_STATUS IE and BEV to boot value */ > + mtc0 t0, C0_SR > + mtc0 zero, C0_CAUSE > + > + /* Return with exit code */ > + move va0, a0 > + MIPS_JRHB(ra) > + .set pop > +WEND(__return_to_boot) > + > +# > +# FUNCTION: void __chain_uhi_excpt (struct gpctx *); > +# > +# DESCRIPTION: Transfer to the exception handler in the boot environment. > +# a0 == pointer to the context to restore > +# > +WLEAF(__chain_uhi_excpt) > + .set push > + .set noat > + > + /* > + * Move context pointer into position. Use $3 as scratch > + * as it is the only register that is clobbered by all > + * UHI calls and is not used as an input. > + */ > + move r3, a0 > + > +#if (__mips_isa_rev < 6) > + REG_L t0, CTX_HI0(r3) > + REG_L t1, CTX_LO0(r3) > + mthi t0 > + mtlo t1 > +#endif > + > + lw t0, CTX_STATUS(r3) > + mtc0 t0, C0_SR > + REG_L t0, CTX_EPC(r3) > + PTR_MTC0 t0, C0_EPC > + ehb > + > + /* Restore the common context */ > + REG_L r1, CTX_REG(1)(r3) > + REG_L r2, CTX_REG(2)(r3) > + REG_L r4, CTX_REG(4)(r3) > + REG_L r5, CTX_REG(5)(r3) > + REG_L r6, CTX_REG(6)(r3) > + REG_L r7, CTX_REG(7)(r3) > + REG_L r8, CTX_REG(8)(r3) > + REG_L r9, CTX_REG(9)(r3) > + REG_L r10, CTX_REG(10)(r3) > + REG_L r11, CTX_REG(11)(r3) > + REG_L r12, CTX_REG(12)(r3) > + REG_L r13, CTX_REG(13)(r3) > + REG_L r14, CTX_REG(14)(r3) > + REG_L r15, CTX_REG(15)(r3) > + REG_L r16, CTX_REG(16)(r3) > + REG_L r17, CTX_REG(17)(r3) > + REG_L r18, CTX_REG(18)(r3) > + REG_L r19, CTX_REG(19)(r3) > + REG_L r20, CTX_REG(20)(r3) > + REG_L r21, CTX_REG(21)(r3) > + REG_L r22, CTX_REG(22)(r3) > + REG_L r23, CTX_REG(23)(r3) > + REG_L r24, CTX_REG(24)(r3) > + REG_L r25, CTX_REG(25)(r3) > + REG_L r28, CTX_REG(28)(r3) > + REG_L r29, CTX_REG(29)(r3) > + REG_L r30, CTX_REG(30)(r3) > + REG_L r31, CTX_REG(31)(r3) > + > + /* Restore chained exception handlers kernel regs */ > + LA r3, __start_ctx > + REG_L k0, start_ctx_k0(r3) > + REG_L k1, start_ctx_k1(r3) > + > +#if defined (__mips_micromips) > + /* OR the address with Config3.ISAOnExc bit */ > + REG_L r3, start_ctx_conf3(r3) > + ext r3, r3, CFG3_IOE_SHIFT, 1 > + beqz r3, 1f > + > + /* Compute exception vector */ > + LA r3, __start_ctx > + REG_L r3, chain_ebase(r3) > + PTR_ADDU r3, r3, 0x181 # OR ISAOnExc bit > + > + /* Chain */ > + jr r3 > +1: > + /* Compute exception vector */ > + LA r3, __start_ctx > +#endif > + > + REG_L r3, chain_ebase(r3) > + PTR_ADDU r3, r3, 0x180 > + > + /* Chain */ > + jr r3 > + > + .set pop > +WEND(__chain_uhi_excpt) > + > +# > +# FUNCTION: int __get_startup_BEV (void) > +# > +# DESCRIPTION: Return value of BEV flag saved in __register_excpt_handler. > +# > +WLEAF(__get_startup_BEV) > + .set push > + .set noat > + > + LA t0, __start_ctx > + REG_L va0, start_ctx_sr(t0) > + li t1, SR_BEV > + and va0, va0, t1 > + jr ra > + > + .set pop > +WEND(__get_startup_BEV) > + > + > +EXPORTS(__MIPS_UHI_BAD_POINTER, 32) > + .ascii "UHI: BAD POINTER\000" > + > +# > +# FUNCTION: __convert_argv_pointers (int, char*[], char*[]) > +# > +# DESCRIPTION: Convert 64-bit pointers to 32-bit. This allocates the new > +# argument structure on the stack and verifies all pointers > are > +# canonical for a 32-bit address space. > +# > +#if _MIPS_SIM==_ABIO32 || _MIPS_SIM==_ABIN32 > +WLEAF(__convert_argv_pointers) > + /* Early out if a0 <= 0 */ > + blez a0, .Lend > + > + /* Verify we came from 64-bit mode */ > + LA t0, __start_ctx > + REG_L t0, start_ctx_sr(t0) > + ext t1, t0, SR_KX_SHIFT, 1 > + beqz t1, .Lend > + > + /* Set up stack pointer */ > + move t0, a0 > + sll t1, t0, 2 > + /* Round to stack alignment */ > + addiu t1, t1, ALSZ > + and t1, t1, ALMASK > + > + PTR_SUBU sp, sp, t1 > + move t2, sp > + move t3, a1 > + li t1, -1 > + > +.Lloop: > +#if BYTE_ORDER == LITTLE_ENDIAN > + lw t8, 0(t3) > + lw t9, 4(t3) > +#elif BYTE_ORDER == BIG_ENDIAN > + lw t9, 0(t3) > + lw t8, 4(t3) > +#else > +#error BYTE_ORDER > +#endif > + /* if s1 != 0 && s1 != 0xFFFFFFFF */ > + beqz t9, .LGoodp > + beq t9, t1, .LGoodp > + /* Overwrite bad pointer with stock bad value */ > + LA t8, __MIPS_UHI_BAD_POINTER > +.LGoodp: > + sw t8, 0(t2) > + > + PTR_ADDU t2, t2, 4 > + PTR_ADDU t3, t3, 8 > + addiu t0, t0, -1 > + bnez t0, .Lloop > + > + move a1, sp > + PTR_SUBU sp, sp, (NARGSAVE*SZARG) > + > + move a2, zero > +.Lend: > + jr ra > +WEND(__convert_argv_pointers) > +#endif /* ABI TEST */ > diff --git a/libgloss/mips/hal/mips_excpt_entry.S > b/libgloss/mips/hal/mips_excpt_entry.S > new file mode 100644 > index 000000000..ddbd2bf9c > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_entry.S > @@ -0,0 +1,212 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#define _FUNCTION_SECTIONS_ > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > +#include <mips/ctx.S> > + > +MIPS_NOMIPS16 > + > +/* Stack adjustment for ABI parameter area. */ > +#define ADJ (NARGSAVE * SZARG) > +/* > + * Round the context size up to a 16-byte boundary which is the maximum > + * stack alignment required for any supported ABI. > + */ > +#define CTX_SIZEROUND ((CTX_SIZE + ALSZ) & ALMASK) > + > +/* > + * Exception entry points. These are designed for use at EBASE when > + * STATUS.BEV is clear. > + * The entry points will either chain on to a user-supplied function > + * or loop indefinitely. > + */ > + > +LEAF(__exception_entry) > + .set push > + .set noat > +.weak _mips_tlb_refill > + _mips_tlb_refill = __exception_save > +__tlb_refill_loop: > + /* > + * Support an alternative entry point at the start of the exception > + * vector. Since the exception vector is normally placed first > + * in the link map this allows a user to start execution from the > + * same address that an executable is loaded to. > + */ > + LA k1, __first_boot > + lw k1, 0(k1) > + beqz k1, 1f > + /* > + * The start code is responsible for clearing __first_boot prior > + * to installing the exception handlers. > + */ > + LA k1, _start > + jr k1 > +1: > + /* Support the case where no handler is defined. */ > + LA k1, _mips_tlb_refill > + beqz k1, __tlb_refill_loop > + jr k1 > + > + .org 0x80 > +.weak _mips_xtlb_refill > + _mips_xtlb_refill = __exception_save > +__xtlb_refill_loop: > + LA k1, _mips_xtlb_refill > + beqz k1, __xtlb_refill_loop > + jr k1 > + > + .org 0x100 > +.weak _mips_cache_error > +__cache_error_loop: > + LA k1, _mips_cache_error > + beqz k1, __cache_error_loop > + jr k1 > + > + .org 0x180 > +.weak _mips_general_exception > +__general_exception_loop: > + /* > + * Free up k1, defering sp adjustment until later. Preserving k1 > + * may be undesirable if an exception occurs due to a corrupt > + * stack but since the default handlers use the user-stack to > + * store the context then there is nothing to lose. > + */ > + REG_S k1, (-CTX_SIZEROUND + CTX_K1)(sp) > + > + LA k1, _mips_general_exception > + beqz k1, __general_exception_loop > + jr k1 > + .set pop > +END(__exception_entry) > + > +/* > + * FUNCTION: __exception_save > + * > + * DESCRIPTION: Saves the GP context to the stack and invokes > + * _mips_handle_exception with appropriate arguments. > +*/ > +ANESTED(__exception_save, _mips_general_exception, CTX_SIZEROUND + ADJ, > zero) > + .globl __exception_save; > + .set push > + .set noat > + > + /* Create pointer to gp_ctx. */ > + PTR_ADDU k1, sp, -CTX_SIZEROUND > + > + /* Save context. */ > + _gpctx_save > + /* va0 now holds C0_STATUS. */ > + > + /* Finish storing the rest of the CP0 registers. */ > + PTR_MFC0 t0, C0_BADVADDR > + REG_S t0, CTX_BADVADDR(k1) > + > +#if __mips_isa_rev < 6 > + move t0, zero > + move t1, zero > + mfc0 t2, C0_CONFIG3 > + ext t3, t2, CFG3_BP_SHIFT, 1 > + beqz t3, 1f > +#else > + /* MIPSR6 guarantees all CP0 regs are defined to at > + least return zero. */ > +#endif > + mfc0 t0, C0_BADPINSTR > +#if __mips_isa_rev < 6 > +1: > + ext t2, t2, CFG3_BI_SHIFT, 1 > + beqz t2, 1f > +#endif > + mfc0 t1, C0_BADINSTR > +1: > + sw t0, CTX_BADPINSTR(k1) > + sw t1, CTX_BADINSTR(k1) > + > + /* Get and store the exception cause. */ > + mfc0 t0, C0_CR > + sw t0, CTX_CAUSE(k1) > + > + /* Extract the cause code for argument 1. */ > + ext a1, t0, CR_X_SHIFT, CR_X_BITS > + > + /* Create the argument space. */ > + addiu sp, k1, -ADJ > + > + /* Clear EXL. Exceptions can now nest. */ > + ins va0, zero, SR_EXL_SHIFT, 1 > + mtc0 va0, C0_SR > + > + /* Move the gp_ctx pointer for argument 0. */ > + addiu a0, sp, ADJ > + > + /* Manually set up the return address to restore the context > below. */ > + LA ra, __exception_restore > + > + /* Call the handler, indirect through t9 albeit not for any > specific > + reason. */ > + LA t9, _mips_handle_exception > + jr t9 > + > + .set pop > +END(__exception_save) > + > +/* > + * FUNCTION: __exception_restore > + * > + * DESCRIPTION: Load the GP context from immediately above the stack > + * pointer and eret. > + */ > +LEAF(__exception_restore) > + .set push > + .set noat > + > + /* Skip past the argument save area and fall through. */ > + addiu a0, sp, ADJ > + > +/* > + * FUNCTION: __gpctx_load_eret > + * > + * DESCRIPTION: Load the GP context from the address in register a0 > + * and eret. > + */ > +AENT(__gpctx_load_eret) > + > + _gpctx_load > + > + /* Return from exception. */ > + eret > + .set pop > +END(__exception_restore) > diff --git a/libgloss/mips/hal/mips_excpt_handler.c > b/libgloss/mips/hal/mips_excpt_handler.c > new file mode 100644 > index 000000000..4c83c9b0a > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_handler.c > @@ -0,0 +1,308 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <stdlib.h> > +#include <unistd.h> > +#include <stdio.h> > +#include <string.h> > +#include <mips/cpu.h> > +#include <mips/fpa.h> > +#include <mips/hal.h> > +#include <mips/uhi_syscalls.h> > + > +/* Defined in .ld file */ > +extern char __use_excpt_boot[]; > +extern char __attribute__((weak)) __flush_to_zero[]; > + > +#ifdef VERBOSE_EXCEPTIONS > +/* > + * Write a string, a formatted number, then a string. > + */ > +static void > +putsnds (const char *pre, reg_t value, int digits, const char *post) > +{ > + char buf[digits]; > + int shift; > + int idx = 0; > + > + if (pre != NULL) > + write (1, pre, strlen (pre)); > + > + for (shift = ((digits - 1) * 4) ; shift >= 0 ; shift -= 4) > + buf[idx++] = "0123456789ABCDEF"[(value >> shift) & 0xf]; > + write (1, buf, digits); > + > + if (post != NULL) > + write (1, post, strlen (post)); > +} > + > +static void > +putsns (const char *pre, reg_t value, const char *post) > +{ > + putsnds (pre, value, sizeof (reg_t) * 2, post); > +} > + > +# define WRITE(MSG) write (1, (MSG), strlen (MSG)) > +# define PUTSNDS(PRE, VALUE, DIGITS, POST) \ > + putsnds ((PRE), (VALUE), (DIGITS), (POST)) > +# define PUTSNS(PRE, VALUE, POST) \ > + putsns ((PRE), (VALUE), (POST)) > + > +#else > + > +# define WRITE(MSG) > +# define PUTSNDS(PRE, VALUE, DIGITS, POST) > +# define PUTSNS(PRE, VALUE, POST) > + > +#endif // !VERBOSE_EXCEPTIONS > + > +/* Handle an exception */ > +#ifdef VERBOSE_EXCEPTIONS > +void _MIPS_HAL_NOMIPS16 > +__exception_handle_verbose (struct gpctx *ctx, int exception) > +#else > +void _MIPS_HAL_NOMIPS16 > +__exception_handle_quiet (struct gpctx *ctx, int exception) > +#endif > +{ > + switch (exception) > + { > + case EXC_MOD: > + WRITE ("TLB modification exception\n"); > + break; > + case EXC_TLBL: > + PUTSNS ("TLB error on load from 0x", ctx->badvaddr, NULL); > + PUTSNS (" @0x", ctx->epc, "\n"); > + break; > + case EXC_TLBS: > + PUTSNS ("TLB error on store to 0x", ctx->badvaddr, NULL); > + PUTSNS (" @0x", ctx->epc, "\n"); > + break; > + case EXC_ADEL: > + PUTSNS ("Address error on load from 0x", ctx->badvaddr, NULL); > + PUTSNS (" @0x", ctx->epc, "\n"); > + break; > + case EXC_ADES: > + PUTSNS ("Address error on store to 0x", ctx->badvaddr, NULL); > + PUTSNS (" @0x", ctx->epc, "\n"); > + break; > + case EXC_IBE: > + WRITE ("Instruction bus error\n"); > + break; > + case EXC_DBE: > + WRITE ("Data bus error\n"); > + break; > + case EXC_SYS: > + /* Process a UHI SYSCALL, all other SYSCALLs should have been > processed > + by our caller. __use_excpt_boot has following values: > + 0 = Do not use exception handler present in boot. > + 1 = Use exception handler present in boot if BEV > + is 0 at startup. > + 2 = Always use exception handler present in boot. */ > + > + /* Special handling for boot/low level failures. */ > + if (ctx->t2[1] == __MIPS_UHI_BOOTFAIL) > + { > + switch (ctx->a[0]) > + { > + case __MIPS_UHI_BF_CACHE: > + WRITE ("L2 cache configuration error\n"); > + break; > + default: > + WRITE ("Unknown boot failure error\n"); > + break; > + } > + > + /* These are unrecoverable. Abort. */ > + ctx->epc = (sreg_t)(long)&__exit; > + /* Exit code of 255 */ > + ctx->a[0] = 0xff; > + return; > + } > + > + if (((long) __use_excpt_boot == 2 > + || ((long) __use_excpt_boot == 1 > + && __get_startup_BEV > + && __get_startup_BEV () == 0)) > + && __chain_uhi_excpt) > + /* This will not return. */ > + __chain_uhi_excpt (ctx); > + else > + __uhi_indirect (ctx); > + return; > + case EXC_BP: > + PUTSNS ("Breakpoint @0x", ctx->epc, "\n"); > + break; > + case EXC_RI: > + PUTSNS ("Illegal instruction @0x", ctx->epc, "\n"); > + break; > + case EXC_CPU: > + PUTSNS ("Coprocessor unusable @0x", ctx->epc, "\n"); > + break; > + case EXC_OVF: > + WRITE ("Overflow\n"); > + break; > + case EXC_TRAP: > + WRITE ("Trap\n"); > + break; > + case EXC_MSAFPE: > +#if MIPS_MSA_USABLE > + if (__flush_to_zero > + && (msa_getsr () & FPA_CSR_UNI_X) > + && (msa_getsr () & FPA_CSR_FS) == 0) > + { > + unsigned int sr = msa_getsr (); > + sr &= ~FPA_CSR_UNI_X; > + sr |= FPA_CSR_FS; > + msa_setsr (sr); > + return; > + } > +#endif > + WRITE ("MSA Floating point error\n"); > + break; > + case EXC_FPE: > + /* Turn on flush to zero the first time we hit an unimplemented > + operation. If we hit it again then stop. */ > + if (__flush_to_zero > + && (fpa_getsr () & FPA_CSR_UNI_X) > + && (fpa_getsr () & FPA_CSR_FS) == 0) > + { > + unsigned int sr = fpa_getsr (); > + sr &= ~FPA_CSR_UNI_X; > + sr |= FPA_CSR_FS; > + fpa_setsr (sr); > + > + return; > + } > + WRITE ("Floating point error\n"); > + break; > + case EXC_IS1: > + WRITE ("Implementation specific exception (16)\n"); > + break; > + case EXC_IS2: > + WRITE ("Implementation specific exception (17)\n"); > + break; > + case EXC_C2E: > + WRITE ("Precise Coprocessor 2 exception\n"); > + break; > + case EXC_TLBRI: > + WRITE ("TLB read inhibit exception\n"); > + break; > + case EXC_TLBXI: > + WRITE ("TLB execute inhibit exception\n"); > + break; > + case EXC_MSAU: > + PUTSNS ("MSA unusable @0x", ctx->epc, "\n"); > + break; > + case EXC_MDMX: > + PUTSNS ("MDMX exception @0x", ctx->epc, "\n"); > + break; > + case EXC_WATCH: > + PUTSNS ("Watchpoint @0x", ctx->epc, "\n"); > + break; > + case EXC_MCHECK: > + WRITE ("Machine check error\n"); > + break; > + case EXC_THREAD: > + WRITE ("Thread exception\n"); > + break; > + case EXC_DSPU: > + WRITE ("DSP unusable\n"); > + break; > + case EXC_RES30: > + WRITE ("Cache error\n"); > + break; > + default: > + PUTSNS ("Unhandled exception ", exception, "\n"); > + } > + > + /* Dump registers */ > + PUTSNS (" 0:\t", 0, "\t"); > + PUTSNS ("at:\t", ctx->at, "\t"); > + PUTSNS ("v0:\t", ctx->v[0], "\t"); > + PUTSNS ("v1:\t", ctx->v[1], "\n"); > + > + PUTSNS ("a0:\t", ctx->a[0], "\t"); > + PUTSNS ("a1:\t", ctx->a[1], "\t"); > + PUTSNS ("a2:\t", ctx->a[2], "\t"); > + PUTSNS ("a3:\t", ctx->a[3], "\n"); > + > + PUTSNS ("t0:\t", ctx->t[0], "\t"); > + PUTSNS ("t1:\t", ctx->t[1], "\t"); > + PUTSNS ("t2:\t", ctx->t[2], "\t"); > + PUTSNS ("t3:\t", ctx->t[3], "\n"); > + > + PUTSNS ("t4:\t", ctx->t[4], "\t"); > + PUTSNS ("t5:\t", ctx->t[5], "\t"); > + PUTSNS ("t6:\t", ctx->t[6], "\t"); > + PUTSNS ("t7:\t", ctx->t[7], "\n"); > + > + PUTSNS ("s0:\t", ctx->s[0], "\t"); > + PUTSNS ("s1:\t", ctx->s[1], "\t"); > + PUTSNS ("s2:\t", ctx->s[2], "\t"); > + PUTSNS ("s3:\t", ctx->s[3], "\n"); > + > + PUTSNS ("s4:\t", ctx->s[4], "\t"); > + PUTSNS ("s5:\t", ctx->s[5], "\t"); > + PUTSNS ("s6:\t", ctx->s[6], "\t"); > + PUTSNS ("s7:\t", ctx->s[7], "\n"); > + > + PUTSNS ("t8:\t", ctx->t2[0], "\t"); > + PUTSNS ("t9:\t", ctx->t2[1], "\t"); > + PUTSNS ("k0:\t", ctx->k[0], "\t"); > + PUTSNS ("k1:\t", ctx->k[1], "\n"); > + > + PUTSNS ("gp:\t", ctx->gp, "\t"); > + PUTSNS ("sp:\t", ctx->sp, "\t"); > + PUTSNS ("fp:\t", ctx->fp, "\t"); > + PUTSNS ("ra:\t", ctx->ra, "\n"); > + > +#if __mips_isa_rev < 6 > + PUTSNS ("hi:\t", ctx->hi, "\t"); > + PUTSNS ("lo:\t", ctx->lo, "\n"); > +#endif > + > + PUTSNS ("epc: \t", ctx->epc, "\n"); > + PUTSNS ("BadVAddr:\t", ctx->badvaddr, "\n"); > + > + PUTSNDS ("Status: \t", ctx->status, 8, "\n"); > + PUTSNDS ("Cause: \t", ctx->cause, 8, "\n"); > + PUTSNDS ("BadInstr: \t", ctx->badinstr, 8, "\n"); > + PUTSNDS ("BadPInstr:\t", ctx->badpinstr, 8, "\n"); > + > + /* Raise UHI exception which may or may not return. */ > + if (__uhi_exception (ctx, UHI_ABI) != 0) > + { > + /* The exception was acknowledged but not handled. Abort. */ > + ctx->epc = (sreg_t)(long)&__exit; > + /* Exit code of 255 */ > + ctx->a[0] = 0xff; > + } > +} > diff --git a/libgloss/mips/hal/mips_excpt_isr_fallback.S > b/libgloss/mips/hal/mips_excpt_isr_fallback.S > new file mode 100644 > index 000000000..d3afce8ec > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_isr_fallback.S > @@ -0,0 +1,52 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#define _FUNCTION_SECTIONS_ > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > + > +.set noat > +MIPS_NOMIPS16 > + > +_TEXT_SECTION_NAMED(__isr_vec_fallback) > + > + /* The alignment used here must match __isr_vec_space. */ > + .balign (SZPTR * 8); > + .globl __isr_vec_fallback; > + .ent __isr_vec_fallback; > +__isr_vec_fallback: > +.weak _mips_interrupt > +1: > + LA k1, _mips_interrupt > + beqz k1, 1b > + jr k1 > +END(__isr_vec_fallback) > diff --git a/libgloss/mips/hal/mips_excpt_isr_fragment.S > b/libgloss/mips/hal/mips_excpt_isr_fragment.S > new file mode 100644 > index 000000000..b7c50de3e > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_isr_fragment.S > @@ -0,0 +1,73 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#define _FUNCTION_SECTIONS_ > + > +#include <mips/regdef.h> > +#include <mips/asm.h> > +#include <mips/cpu.h> > + > +.set noat > +MIPS_NOMIPS16 > + > +.extern __isr_vec_fallback > + > +/* For the vectors shared between VINT and VEIC we rename the numeric > + * vector indices to the named form instead. */ > + > +#define _mips_isr_000 _mips_isr_sw0 > +#define _mips_isr_001 _mips_isr_sw1 > +#define _mips_isr_002 _mips_isr_hw0 > +#define _mips_isr_003 _mips_isr_hw1 > +#define _mips_isr_004 _mips_isr_hw2 > +#define _mips_isr_005 _mips_isr_hw3 > +#define _mips_isr_006 _mips_isr_hw4 > +#define _mips_isr_007 _mips_isr_hw5 > + > +.extern REF > +.weak ISR > + > +#ifdef __mips_micromips > +# define NOP nop32 > +#else > +# define NOP nop > +#endif > + > +_TEXT_SECTION_NAMED(DEF); > +/* The alignment used here must match __isr_vec_space. */ > + .balign (SZPTR * 8); > + .globl DEF; > + .ent DEF; > +DEF: > + NOP /* May become: mtc0 k1, C0_KSCRATCH1 */ > + LA k1, ISR > + beqz k1, __isr_vec_fallback > + jr k1 > +END(DEF) > diff --git a/libgloss/mips/hal/mips_excpt_register.S > b/libgloss/mips/hal/mips_excpt_register.S > new file mode 100644 > index 000000000..1c6bdc04c > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_register.S > @@ -0,0 +1,147 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > + > +MIPS_NOMIPS16 > + > +/* > + * Used to support an alternate entry point that overlays the TLB refill > + * exception entry point. This flag must be cleared before exceptions > + * are ready to be handled. > + */ > +.data > +EXPORTS(__first_boot, 4) > + .word 0x1 > + > +_TEXT_SECTION > + > +/* > + * FUNCTION: __register_excpt_handler > + * > + * DESCRIPTION: Register __exception_entry at EBASE+0x180. Return the new > + * value for C0_SR. > + */ > +WLEAF(__register_excpt_handler) > + .set push > + .set noat > + > + /* Fetch initial status */ > + mfc0 a1, C0_SR > + > + /* > + * Get into a clean state. > + * Important things: base mode is kernel and ERL, ESL, IE are clear > + * Set BEV=1 to allow changing EBASE later. > + */ > + li t0, SR_BEV > + mtc0 t0, C0_SR > + ehb > + > + /* > + * Enable use of a boot state hook > + * a0 = Boot time RA > + * a1 = Boot time SR > + * a2 = Current RA. There is no stack so get the callee to pass > this > + * back. > + */ > +.weak __register_excpt_boot > + LA t0, __register_excpt_boot > + beqz t0, 1f > + move a2, ra > + jalr t0 > + move ra, va0 > +1: > + /* Clear first boot flag */ > + LA t0, __first_boot > + sw zero, 0(t0) > + > + mfc0 t3, C0_CONFIG3 > +#if defined (__mips_micromips) > + /* Set Config3.ISAOnExc for microMIPS */ > + li t0, CFG3_IOE > + or t0, t0, t3 > + mtc0 t0, C0_CONFIG3 > +#endif > + > + /* Set desired EBASE */ > + LA t0, __excpt_ebase > + /* > + * Always set the write gate as the requested EBASE may not be in > kseg0. > + * This may or may not exist in hardware but if it doesn't then the > + * ebase address will simply get masked with inevitable > consequences. > + */ > + ori t0, t0, EBASE_WG > + PTR_MTC0 t0, C0_EBASE > + ehb > + > + /* Set up new empty status value */ > + move va0, zero > + > + /* Set up vector spacing */ > + LA t0, __isr_vec_space > + > + /* Check for vectored interrupt support */ > + andi t1, t3, CFG3_VI | CFG3_VEIC > + /* Skip vector spacing setup if neither VINT nor VEIC is present */ > + beqz t1, 1f > + > + /* Set vector spacing */ > + mfc0 t1, C0_INTCTL > + srl t0, t0, 5 > + ins t1, t0, INTCTL_VS_SHIFT, INTCTL_VS_BITS > + mtc0 t1, C0_INTCTL > + b 2f > +1: > + /* > + * Check non-zero vector spacing without vectored interrupt > support. > + * If so, do not enable interrupts. > + */ > + bnez t0, 3f > +2: > + /* Turn on use of the special exception vector and enable > interrupts */ > + li t0, CR_IV > + mtc0 t0, C0_CAUSE > + ehb > + > + /* Check for VEIC and do not enable interrupts if EIC is active */ > + ext t0, t3, CFG3_VEIC_SHIFT, 1 > + bnez t0, 3f > + > + /* Enable interrupts in the new status value */ > + ori va0, va0, SR_IE > +3: > + jr ra > + > + .set pop > +WEND(__register_excpt_handler) > diff --git a/libgloss/mips/hal/mips_excpt_timer.S > b/libgloss/mips/hal/mips_excpt_timer.S > new file mode 100644 > index 000000000..faccb4185 > --- /dev/null > +++ b/libgloss/mips/hal/mips_excpt_timer.S > @@ -0,0 +1,103 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <mips/cpu.h> > +#include <mips/asm.h> > + > +MIPS_NOMIPS16 > + > +EXPORTS(_count_wrap, 4) > + .word 0x0 > + > +# > +# FUNCTION: > +# > +# DESCRIPTION: > +# > +LEAF(mips_start_minimal_counter) > + di $8 > + ehb > + ori $8, $8, SR_HINT5 > + ori $8, $8, SR_IE > + LA $9, _count_wrap > + sw $0, 0($9) > + li $9, 1 > + mtc0 $9, C0_COUNT > + mtc0 $0, C0_COMPARE > + mtc0 $8, C0_SR > + ehb > + jr $31 > +END(mips_start_minimal_counter) > + > +LEAF(_mips_isr_sw0) > + .set push > + .set noreorder > + .set noat > + LA $k0, _count_wrap > + lw $k1, 0($k0) > + addiu $k1, $k1, 1 > + sw $k1, 0($k0) > + mtc0 $0, C0_COMPARE > + eret > + .set pop > +END(_mips_isr_sw0) > + > +LEAF(_mips_interrupt) > + .set push > + .set noreorder > + .set noat > + LA $k0, _count_wrap > + lw $k1, 0($k0) > + addiu $k1, $k1, 1 > + sw $k1, 0($k0) > + mtc0 $0, C0_COMPARE > + eret > + .set pop > +END(_mips_interrupt) > + > +LEAF(mips_stop_minimal_counter) > + LA $11, _count_wrap > + mfc0 $9, C0_COUNT > + di $8 > + ehb > + lw $11, 0($11) > + li $12, ~SR_HINT5 > + and $8, $8, $12 > + mfc0 $10, C0_COUNT > + sltu $9, $10, $9 > + ori $8, $8, SR_IE > + beqz $9, 1f > + addiu $11, $11, 1 > +1: > + sw $11, 0($4) > + sw $10, 0($5) > + mtc0 $8, C0_SR > + jr $31 > +END(mips_stop_minimal_counter) > diff --git a/libgloss/mips/hal/mips_flush_cache.c > b/libgloss/mips/hal/mips_flush_cache.c > new file mode 100644 > index 000000000..f651e6d51 > --- /dev/null > +++ b/libgloss/mips/hal/mips_flush_cache.c > @@ -0,0 +1,108 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > + > +/* Writeback and invalidate all caches */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_flush_cache (void) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If D-cache is present */ > + if (mips_dcache_size > 0) > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_dcache_size, > + mips_dcache_linesize, Index_Writeback_Inv_D); > + > + /* If I-cache is present */ > + if (mips_icache_size > 0) > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_icache_size, > + mips_icache_linesize, Index_Invalidate_I); > + > + /* If L2-cache is present */ > + if (mips_scache_size > 0) > + { > + mips_sync (); > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size, > + mips_scache_linesize, Index_Writeback_Inv_S); > + } > + > + mips_sync (); > + return; > +} > + > +/* Writeback and invalidate D-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_flush_dcache (void) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If D-cache is present */ > + if (mips_dcache_size > 0) > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_dcache_size, > + mips_dcache_linesize, Index_Writeback_Inv_D); > + > + /* If L2-cache is present */ > + if (mips_scache_size > 0) > + { > + mips_sync (); > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size, > + mips_scache_linesize, Index_Writeback_Inv_S); > + } > + > + mips_sync (); > + return; > +} > + > +/* Writeback and invalidate I-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_flush_icache (void) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If I-cache is present */ > + if (mips_icache_size > 0) > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_icache_size, > + mips_icache_linesize, Index_Invalidate_I); > + > + /* If L2-cache is present */ > + if (mips_scache_size > 0) > + { > + mips_sync (); > + mips_cache_op ((vaddr_t) KSEG0_BASE, mips_scache_size, > + mips_scache_linesize, Index_Writeback_Inv_S); > + } > + > + mips_sync (); > + return; > +} > diff --git a/libgloss/mips/hal/mips_fp.S b/libgloss/mips/hal/mips_fp.S > new file mode 100644 > index 000000000..801ba79e2 > --- /dev/null > +++ b/libgloss/mips/hal/mips_fp.S > @@ -0,0 +1,184 @@ > +/* > + * Copyright 2015-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +.module hardfloat > +.module doublefloat > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > + > +MIPS_NOMIPS16 > + > +#undef fp > + > +/* > + * FUNCTION: _fpctx_save > + * DESCRIPTION: save floating point registers to memory starting > at a0 > + * RETURNS: int > + * 0: No context saved > + * CTX_*: Type of context stored > + */ > +LEAF(_fpctx_save) > + move a1, a0 > + PTR_S zero, LINKCTX_NEXT(a1) > + mfc0 t0, C0_STATUS > + li t1, SR_CU1 > + and t1, t0, t1 > + bnez t1, 1f > + /* FP not enabled, bail out */ > + move va0, zero > + jr ra > + > +1: /* Save FP32 base */ > + li t1, SR_FR > + and t0, t0, t1 > + cfc1 t2, $31 > + REG_S t2, FP32CTX_CSR(a1) > + sdc1 $f0, FP32CTX_0(a1) > + sdc1 $f2, FP32CTX_2(a1) > + sdc1 $f4, FP32CTX_4(a1) > + sdc1 $f6, FP32CTX_6(a1) > + sdc1 $f8, FP32CTX_8(a1) > + sdc1 $f10, FP32CTX_10(a1) > + sdc1 $f12, FP32CTX_12(a1) > + sdc1 $f14, FP32CTX_14(a1) > + sdc1 $f16, FP32CTX_16(a1) > + sdc1 $f18, FP32CTX_18(a1) > + sdc1 $f20, FP32CTX_20(a1) > + sdc1 $f22, FP32CTX_22(a1) > + sdc1 $f24, FP32CTX_24(a1) > + sdc1 $f26, FP32CTX_26(a1) > + sdc1 $f28, FP32CTX_28(a1) > + sdc1 $f30, FP32CTX_30(a1) > + bnez t0, 2f > + li va0, LINKCTX_TYPE_FP32 > + REG_S va0, LINKCTX_ID(a1) > + jr ra > + > +2: /* Save FP64 extra */ > +.set push > +.set fp=64 > + sdc1 $f1, FP64CTX_1(a1) > + sdc1 $f3, FP64CTX_3(a1) > + sdc1 $f5, FP64CTX_5(a1) > + sdc1 $f7, FP64CTX_7(a1) > + sdc1 $f9, FP64CTX_9(a1) > + sdc1 $f11, FP64CTX_11(a1) > + sdc1 $f13, FP64CTX_13(a1) > + sdc1 $f15, FP64CTX_15(a1) > + sdc1 $f17, FP64CTX_17(a1) > + sdc1 $f19, FP64CTX_19(a1) > + sdc1 $f21, FP64CTX_21(a1) > + sdc1 $f23, FP64CTX_23(a1) > + sdc1 $f25, FP64CTX_25(a1) > + sdc1 $f27, FP64CTX_27(a1) > + sdc1 $f29, FP64CTX_29(a1) > + sdc1 $f31, FP64CTX_31(a1) > +.set pop > + li va0, LINKCTX_TYPE_FP64 > + REG_S va0, LINKCTX_ID(a0) > + jr ra > +END(_fpctx_save) > + > +/* > + * FUNCTION: _fpctx_load > + * DESCRIPTION: load floating point registers from context chain > starting at a0 > + * RETURNS: int > + * 0: Unrecognised context > + * CTX_*: Type of context restored > + */ > +LEAF(_fpctx_load) > + move a1, a0 > + REG_L va0, LINKCTX_ID(a1) > + /* Detect type */ > + li t0, LINKCTX_TYPE_FP64 > + li t1, LINKCTX_TYPE_FP32 > + li t2, SR_CU1 > + beq va0, t0, 0f > + beq va0, t1, 1f > + /* Don't recognise this context, fail */ > + move va0, zero > + jr ra > + > +0: /* FP64 context - Enable CU1 */ > + di t3 > + ehb > + or t3, t3, t2 > + mtc0 t3, C0_STATUS > + ehb > + /* Load FP64 extra */ > +.set push > +.set fp=64 > + ldc1 $f1, FP64CTX_1(a1) > + ldc1 $f3, FP64CTX_3(a1) > + ldc1 $f5, FP64CTX_5(a1) > + ldc1 $f7, FP64CTX_7(a1) > + ldc1 $f9, FP64CTX_9(a1) > + ldc1 $f11, FP64CTX_11(a1) > + ldc1 $f13, FP64CTX_13(a1) > + ldc1 $f15, FP64CTX_15(a1) > + ldc1 $f17, FP64CTX_17(a1) > + ldc1 $f19, FP64CTX_19(a1) > + ldc1 $f21, FP64CTX_21(a1) > + ldc1 $f23, FP64CTX_23(a1) > + ldc1 $f25, FP64CTX_25(a1) > + ldc1 $f27, FP64CTX_27(a1) > + ldc1 $f29, FP64CTX_29(a1) > + ldc1 $f31, FP64CTX_31(a1) > +.set pop > +1: /* FP32 context - Enable CU1 */ > + di t3 > + ehb > + or t3, t3, t2 > + mtc0 t3, C0_STATUS > + ehb > + /* Load FP32 base */ > + REG_L t1, FP32CTX_CSR(a1) > + ctc1 t1, $31 > + ldc1 $f0, FP32CTX_0(a1) > + ldc1 $f2, FP32CTX_2(a1) > + ldc1 $f4, FP32CTX_4(a1) > + ldc1 $f6, FP32CTX_6(a1) > + ldc1 $f8, FP32CTX_8(a1) > + ldc1 $f10, FP32CTX_10(a1) > + ldc1 $f12, FP32CTX_12(a1) > + ldc1 $f14, FP32CTX_14(a1) > + ldc1 $f16, FP32CTX_16(a1) > + ldc1 $f18, FP32CTX_18(a1) > + ldc1 $f20, FP32CTX_20(a1) > + ldc1 $f22, FP32CTX_22(a1) > + ldc1 $f24, FP32CTX_24(a1) > + ldc1 $f26, FP32CTX_26(a1) > + ldc1 $f28, FP32CTX_28(a1) > + ldc1 $f30, FP32CTX_30(a1) > + /* Return CTX_FP32/64 */ > + jr ra > +END(_fpctx_load) > diff --git a/libgloss/mips/hal/mips_intctrl.c > b/libgloss/mips/hal/mips_intctrl.c > new file mode 100644 > index 000000000..e1e55b48b > --- /dev/null > +++ b/libgloss/mips/hal/mips_intctrl.c > @@ -0,0 +1,151 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <mips/cpu.h> > +#include <mips/hal.h> > +#include <mips/endian.h> > +#include <mips/intctrl.h> > + > +#define _mips_intpatch_kscratch1 0x00 > +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || defined (__mips_micromips) > +# define _mips_intpatch_isroff1 0x06 > +# define _mips_intpatch_isroff2 0x0a > +# define _mips_intpatch_isroff3 0x12 > +# define _mips_intpatch_isroff4 0x1a > +#else > +# define _mips_intpatch_isroff1 0x04 > +# define _mips_intpatch_isroff2 0x08 > +# define _mips_intpatch_isroff3 0x10 > +# define _mips_intpatch_isroff4 0x1c > +#endif > + > +extern void m32_sync_icache(unsigned kva, size_t n); > + > +void _MIPS_HAL_NOMIPS16 > +_mips_intpatch (const reg_t index, uintptr_t handler, bool > k1_to_kscratch1) > +{ > + extern void *__isr_vec_space; > + uint16_t *patch; > + uint32_t *patch32; > + uintptr_t isrbase = (uintptr_t) (mips32_getebase() & EBASE_BASE) > + + 0x200 + (index * ((uintptr_t) &__isr_vec_space)); > + if (k1_to_kscratch1) > + { > +#ifdef __mips_micromips > + patch = (uint16_t *) (isrbase + _mips_intpatch_kscratch1); > + *(patch++) = 0x037f; > + *(patch) = 0x12fc; > +#else > + patch32 = (uint32_t *) (isrbase + _mips_intpatch_kscratch1); > + *patch32 = 0x409bf802; > +#endif > + } > +#if SZPTR==4 > + handler += (handler & 0x8000) << 1; > + patch = (uint16_t *) (isrbase + _mips_intpatch_isroff1); > + *patch = (uint16_t) (handler >> 16); /* %hi */ > + patch = (uint16_t *) (isrbase + _mips_intpatch_isroff2); > + *patch = (uint16_t) (handler & 0xffff); /* %lo */ > + m32_sync_icache (isrbase, 32); > +#elif SZPTR==8 > + handler += (handler & 0x800080008000) << 1; > + patch = (uint16_t *) (isrbase + _mips_intpatch_isroff1); > + *patch = (uint16_t) (handler >> 48); /* %highest */ > + patch = (uint16_t *) (isrbase + _mips_intpatch_isroff2); > + *patch = (uint16_t) ((handler >> 32) & 0xffff); /* %higher */ > + patch = (uint16_t *) (isrbase + _mips_intpatch_isroff3); > + *patch = (uint16_t) ((handler >> 16) & 0xffff); /* %hi */ > + patch = (uint16_t *) (isrbase + _mips_intpatch_isroff4); > + *patch = (uint16_t) (handler & 0xffff); /* %lo */ > + m32_sync_icache (isrbase, 64); > +#else > +# error "Unknown pointer size" > +#endif > +} > + > +/* > + * Interrupt masking and acknowledging functions - these are weak so they > can > + * be replaced with versions that understand more complex interrupt > models. > + */ > + > +reg_t __attribute__ ((weak)) _MIPS_HAL_NOMIPS16 > +_mips_intmask (const reg_t index, const reg_t enable) > +{ > + register reg_t enbefore, valbefore = 0, indexedbit; > + > + /* > + * Calculate which bit upfront to minimise critical section. > + * Note that this function supports the MCU ASE, unlike the .h files. > + */ > + if ((index >= 0) && (index <= 8)) > + /* Traditional/1st MCU ASE interrupt. */ > + indexedbit = SR_IM0 << index; > + else if (index == 9) > + /* 2nd MCU ASE interrupt. */ > + indexedbit = SR_IM7 << 2; > + > + /* Make sure we can safely adjust the mask. */ > + enbefore = _mips_intdisable (); > + > + /* Make the change. */ > + valbefore = mips32_bcssr (indexedbit, enable ? indexedbit : 0); > + > + /* Go live again. */ > + _mips_intrestore (enbefore); > + > + /* Return true if it was enabled, again outside critical section. */ > + return (valbefore & indexedbit) != 0; > +} > + > +reg_t __attribute__ ((weak)) _MIPS_HAL_NOMIPS16 > +_mips_intack (const reg_t index) > +{ > + reg_t enbefore, indexedbit; > + reg_t valbefore = 0; > + > + /* We only handle software interrupts - bail out otherwise. */ > + if ((index < 0) && (index > 1)) > + return 0; > + > + /* Calculate which bit upfront to minimise critical section. */ > + indexedbit = CR_IP0 << index; > + > + /* Make sure we can safely adjust the state. */ > + enbefore = _mips_intdisable (); > + > + /* Make the change. */ > + valbefore = mips32_bicsr (indexedbit); > + > + /* Go live again. */ > + _mips_intrestore (enbefore); > + > + /* Return true if it was enabled, again outside critical section. */ > + return (valbefore & indexedbit) != 0; > +} > diff --git a/libgloss/mips/hal/mips_l2size.c > b/libgloss/mips/hal/mips_l2size.c > new file mode 100644 > index 000000000..960205ba3 > --- /dev/null > +++ b/libgloss/mips/hal/mips_l2size.c > @@ -0,0 +1,96 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > +#include <mips/uhi_syscalls.h> > + > +static void __attribute__ ((noreturn)) _MIPS_HAL_NOMIPS16 > +__boot_fail (void) > +{ > + register long arg1 asm ("$4") = __MIPS_UHI_BF_CACHE; /* L2 cache > configuration error */ > + register long op asm ("$25") = __MIPS_UHI_BOOTFAIL; > + register long ret asm ("$2") = __MIPS_UHI_SYSCALL_NUM; > + > + __asm__ volatile (" # %0 = bootfail(%0, %1) op=%2\n" > + SYSCALL (__MIPS_UHI_SYSCALL_NUM) > + : "+r" (ret) > + : "r" (arg1), "r" (op)); > + > + __boot_fail (); > +} > + > +/* > + * Internal routine to determine cache sizes by looking at config > + * registers. Sizing information is stored directly to memory. > +*/ > +void _MIPS_HAL_NOMIPS16 > +__def_cache_size_hook (void) > +{ > + /* > + * Fall back to Config2 based L2 if Config3[M] or Config4[M] > + * or Config5[L2C] is not present. > + */ > + if ((mips32_getconfig3 () & CFG3_M) == 0 > + || (mips32_getconfig4 () & CFG4_M) == 0 > + || (mips32_getconfig5 () & CFG5_L2C) == 0) > + { > + unsigned int cfg, tmp1, tmp2; > + > + cfg = mips32_getconfig2 (); > + > + /* Get S-cache line size (log2) */ > + tmp1 = (cfg & CFG2_SL_MASK) >> CFG2_SL_SHIFT; > + if (tmp1 == 0) > + return; /* No S-cache */ > + > + tmp1++; > + > + /* Get number of S-cache ways */ > + mips_scache_ways = ((cfg & CFG2_SA_MASK) >> CFG2_SA_SHIFT) + 1; > + > + /* Total scache size = lines/way * linesize * ways */ > + mips_scache_linesize = 1 << tmp1; > + tmp2 = mips_scache_ways << tmp1; > + > + /* Get scache lines per way */ > + tmp1 = ((cfg & CFG2_SS_MASK) >> CFG2_SS_SHIFT) + 6; > + mips_scache_size = tmp2 << tmp1; > + > + return; > + } > + > + /* > + * No CM3 code supplied but we have a memory mapped L2 config. > + * Report a boot failure through UHI. > + */ > + __boot_fail (); > +} > + > +void __cache_size_hook (void) __attribute__ ((weak, alias > ("__def_cache_size_hook"))); > diff --git a/libgloss/mips/hal/mips_lock_cache.c > b/libgloss/mips/hal/mips_lock_cache.c > new file mode 100644 > index 000000000..475e2e84c > --- /dev/null > +++ b/libgloss/mips/hal/mips_lock_cache.c > @@ -0,0 +1,83 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > + > +/* > + * The MIPS32 cache architecture does support per-line cache locking. > + * If you lock any cache lines, then don't call the mips_flush_cache > + * routine, because these will flush the locked data out of the cache > + * too; use only mips_clean_xcache routines. > +*/ > + > +/* Load and lock a block of data into the D-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_lock_dcache (vaddr_t data, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If D-cache is present */ > + if (mips_dcache_linesize > 0) > + mips_cache_op (data, n, mips_dcache_linesize, Fetch_Lock_D); > + > + mips_sync (); > + return; > +} > + > +/* Load and lock a block of instructions into the I-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_lock_icache (vaddr_t code, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If I-cache is present */ > + if (mips_icache_linesize > 0) > + mips_cache_op (code, n, mips_icache_linesize, Fetch_Lock_I); > + > + mips_sync (); > + return; > +} > + > +/* Load and lock a block of data into the L2-cache */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_lock_scache (vaddr_t data, size_t n) > +{ > + /* Calculate cache sizes */ > + mips_size_cache (); > + > + /* If L2-cache is present */ > + if (mips_scache_linesize > 0) > + mips_cache_op (data, n, mips_scache_linesize, Fetch_Lock_S); > + > + mips_sync (); > + return; > +} > diff --git a/libgloss/mips/hal/mips_msa.S b/libgloss/mips/hal/mips_msa.S > new file mode 100644 > index 000000000..3d59fa179 > --- /dev/null > +++ b/libgloss/mips/hal/mips_msa.S > @@ -0,0 +1,183 @@ > +/* > + * Copyright 2015-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#if __mips_isa_rev < 6 || !defined(__mips_micromips) > +.module hardfloat > +.module doublefloat > +#undef fp > +.module fp=64 > +.module msa > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > + > +MIPS_NOMIPS16 > + > +/* > + * FUNCTION: _msactx_save > + * DESCRIPTION: save MSA registers to memory starting at a0 > + * RETURNS: int > + * 0: No context saved > + * CTX_*: Type of context stored > + */ > +LEAF(_msactx_save) > + move a1, a0 > + PTR_S zero, LINKCTX_NEXT(a1) > + mfc0 t0, C0_CONFIG5 > + ext t0, t0, CFG5_MSAEN_SHIFT, 1 > + bnez t0, 1f > + /* MSA not enabled, bail out */ > + move va0, zero > + jr ra > + > + /* Save FCSR if necessary */ > +1: mfc0 t0, C0_STATUS > + ext t1, t0, SR_CU1_SHIFT, 1 > + lui va0, %hi(LINKCTX_TYPE_MSA) > + beqz t1, 2f > + lui va0, %hi(LINKCTX_TYPE_FMSA) > + cfc1 t2, $31 > + REG_S t2, MSACTX_FCSR(a1) > + /* Save MSA */ > +2: ori va0, va0, %lo(LINKCTX_TYPE_MSA) > + cfcmsa t0, $1 > + REG_S t0, MSACTX_MSACSR(a1) > + st.d $w0, MSACTX_0(a1) > + st.d $w1, MSACTX_1(a1) > + st.d $w2, MSACTX_2(a1) > + st.d $w3, MSACTX_3(a1) > + st.d $w4, MSACTX_4(a1) > + st.d $w5, MSACTX_5(a1) > + st.d $w6, MSACTX_6(a1) > + st.d $w7, MSACTX_7(a1) > + st.d $w8, MSACTX_8(a1) > + st.d $w9, MSACTX_9(a1) > + st.d $w10, MSACTX_10(a1) > + st.d $w11, MSACTX_11(a1) > + st.d $w12, MSACTX_12(a1) > + st.d $w13, MSACTX_13(a1) > + st.d $w14, MSACTX_14(a1) > + st.d $w15, MSACTX_15(a1) > + st.d $w16, MSACTX_16(a1) > + st.d $w17, MSACTX_17(a1) > + st.d $w18, MSACTX_18(a1) > + st.d $w19, MSACTX_19(a1) > + st.d $w20, MSACTX_20(a1) > + st.d $w21, MSACTX_21(a1) > + st.d $w22, MSACTX_22(a1) > + st.d $w23, MSACTX_23(a1) > + st.d $w24, MSACTX_24(a1) > + st.d $w25, MSACTX_25(a1) > + st.d $w26, MSACTX_26(a1) > + st.d $w27, MSACTX_27(a1) > + st.d $w28, MSACTX_28(a1) > + st.d $w29, MSACTX_29(a1) > + st.d $w30, MSACTX_30(a1) > + st.d $w31, MSACTX_31(a1) > + REG_S va0, LINKCTX_ID(a1) > + jr ra > +END(_msactx_save) > + > +/* > + * FUNCTION: _msactx_load > + * DESCRIPTION: load MSA/floating point registers from memory > starting at a0 > + * RETURNS: int > + * 0: Unrecognised context > + * CTX_*: Type of context restored > + */ > +LEAF(_msactx_load) > + move a1, a0 > + REG_L va0, LINKCTX_ID(a1) > + /* Detect type */ > + li t0, LINKCTX_TYPE_FMSA > + li t1, LINKCTX_TYPE_MSA > + li t2, SR_CU1 > + beq va0, t0, 0f > + beq va0, t1, 1f > + /* Don't recognise this context, fail */ > + move va0, zero > + jr ra > + > +0: /* FPU+MSA context - Enable CU1 */ > + di t3 > + ehb > + or t3, t3, t2 > + mtc0 t3, C0_STATUS > + ehb > + REG_L t1, MSACTX_FCSR(a1) > + ctc1 t1, $31 > +1: /* MSA context - Enable MSA */ > + li t3, CFG5_MSAEN > + mfc0 t2, C0_CONFIG5 > + or t2, t3, t2 > + mtc0 t2, C0_CONFIG5 > + ehb > + /* Load MSA */ > + lw t3, MSACTX_MSACSR(a1) > + ctcmsa $1, t3 > + ld.d $w0, MSACTX_0(a1) > + ld.d $w1, MSACTX_1(a1) > + ld.d $w2, MSACTX_2(a1) > + ld.d $w3, MSACTX_3(a1) > + ld.d $w4, MSACTX_4(a1) > + ld.d $w5, MSACTX_5(a1) > + ld.d $w6, MSACTX_6(a1) > + ld.d $w7, MSACTX_7(a1) > + ld.d $w8, MSACTX_8(a1) > + ld.d $w9, MSACTX_9(a1) > + ld.d $w10, MSACTX_10(a1) > + ld.d $w11, MSACTX_11(a1) > + ld.d $w12, MSACTX_12(a1) > + ld.d $w13, MSACTX_13(a1) > + ld.d $w14, MSACTX_14(a1) > + ld.d $w15, MSACTX_15(a1) > + ld.d $w16, MSACTX_16(a1) > + ld.d $w17, MSACTX_17(a1) > + ld.d $w18, MSACTX_18(a1) > + ld.d $w19, MSACTX_19(a1) > + ld.d $w20, MSACTX_20(a1) > + ld.d $w21, MSACTX_21(a1) > + ld.d $w22, MSACTX_22(a1) > + ld.d $w23, MSACTX_23(a1) > + ld.d $w24, MSACTX_24(a1) > + ld.d $w25, MSACTX_25(a1) > + ld.d $w26, MSACTX_26(a1) > + ld.d $w27, MSACTX_27(a1) > + ld.d $w28, MSACTX_28(a1) > + ld.d $w29, MSACTX_29(a1) > + ld.d $w30, MSACTX_30(a1) > + ld.w $w31, MSACTX_31(a1) > + /* Return CTX_(F)MSA */ > + jr ra > +END(_msactx_load) > + > +#endif // __mips_isa_rev < 6 || !defined(__micromips__) > diff --git a/libgloss/mips/hal/mips_size_cache.c > b/libgloss/mips/hal/mips_size_cache.c > new file mode 100644 > index 000000000..74a2c49f0 > --- /dev/null > +++ b/libgloss/mips/hal/mips_size_cache.c > @@ -0,0 +1,108 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > + > +int mips_icache_size = -1; > +int mips_icache_linesize = -1; > +int mips_icache_ways = 1; > + > +int mips_dcache_size = -1; > +int mips_dcache_linesize = -1; > +int mips_dcache_ways = 1; > + > +int mips_scache_size = -1; > +int mips_scache_linesize = -1; > +int mips_scache_ways = 1; > + > +int mips_tcache_size = -1; > +int mips_tcache_linesize = -1; > +int mips_tcache_ways = 1; > + > +extern void __cache_size_hook (void); > + > +/* > + * Size caches without reinitialising and losing dirty cache lines. > + * Update mips_icache_* and mips_dcache_* global variables. > +*/ > +void _MIPS_HAL_NOMIPS16 > +mips_size_cache (void) > +{ > + int lsize, ways; > + unsigned int cfg; > + > + /* Return if sizes are already known */ > + if (mips_icache_size > 0) > + return; > + > + /* Check presence of Config1 */ > + cfg = mips32_getconfig0 (); > + if ((cfg & CFG0_M)) > + { > + /* Check if I-cache is present */ > + cfg = mips32_getconfig1 (); > + lsize = (cfg & CFG1_IL_MASK) >> CFG1_IL_SHIFT; > + if (lsize) > + { > + lsize++; > + > + /* Get number of I-cache ways */ > + ways = ((cfg & CFG1_IA_MASK) >> CFG1_IA_SHIFT) + 1; > + mips_icache_ways = ways; > + mips_icache_linesize = 1 << lsize; > + ways = ways << lsize; > + > + /* Get I-cache lines per way */ > + lsize = ((((cfg & CFG1_IS_MASK) >> CFG1_IS_SHIFT) + 1) & 7) + 5; > + mips_icache_size = ways << lsize; > + } > + > + /* Check if D-cache is present */ > + lsize = (cfg & CFG1_DL_MASK) >> CFG1_DL_SHIFT; > + if (lsize) > + { > + lsize++; > + > + /* Get number of D-cache ways */ > + ways = ((cfg & CFG1_DA_MASK) >> CFG1_DA_SHIFT) + 1; > + mips_dcache_ways = ways; > + mips_dcache_linesize = 1 << lsize; > + ways = ways << lsize; > + > + /* Get D-cache lines per way */ > + lsize = ((((cfg & CFG1_DS_MASK) >> CFG1_DS_SHIFT) + 1) & 7) + 5; > + mips_dcache_size = ways << lsize; > + } > + } > + > + __cache_size_hook (); > + > + return; > +} > diff --git a/libgloss/mips/hal/mips_sync_cache.c > b/libgloss/mips/hal/mips_sync_cache.c > new file mode 100644 > index 000000000..69425fa46 > --- /dev/null > +++ b/libgloss/mips/hal/mips_sync_cache.c > @@ -0,0 +1,64 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > + > +/* Synchronise I-cache for virtual address range */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_sync_icache (vaddr_t kva, size_t n) > +{ > + int step; > + vaddr_t addr, maxaddr, mask; > + > + /* Check for bad size */ > + if (n <= 0) > + return; > + > + /* Get synci step and skip if not required */ > + step = mips_synci_step (); > + if (step == 0) > + return; > + > + mips_sync (); > + > + mask = ~ (step - 1); > + addr = (kva & mask) - step; > + maxaddr = ((kva + n) - 1) & mask; > + > + do > + { > + addr = addr + step; > + mips_synci (addr); > + } > + while (addr != maxaddr); > + > + mips_sync (); > + return; > +} > diff --git a/libgloss/mips/hal/mips_tlb.c b/libgloss/mips/hal/mips_tlb.c > new file mode 100644 > index 000000000..eb43c0483 > --- /dev/null > +++ b/libgloss/mips/hal/mips_tlb.c > @@ -0,0 +1,479 @@ > +/* > + * Copyright 2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include "cache.h" > +#include <mips/hal.h> > +#include <mips/m32tlb.h> > + > +/* Writes hi, lo0, lo1 and mask into the TLB entry specified by index */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_tlbwi2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask, > + int index) > +{ > + mips32_setentryhi (hi); > + mips32_setentrylo0 (lo0); > + mips32_setentrylo1 (lo1); > + mips32_setpagemask (mask); > + mips32_setindex (index); > + mips_ehb (); > + mips_tlbwi (); > + return; > +} > + > +/* > + * Writes hi, lo0, lo1 and mask into the TLB entry specified by the > + * random register. > +*/ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_tlbwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask) > +{ > + mips32_setentryhi (hi); > + mips32_setentrylo0 (lo0); > + mips32_setentrylo1 (lo1); > + mips32_setpagemask (mask); > + mips_ehb (); > + mips_tlbwr (); > + return; > +} > + > +/* > + * Probes the TLB for an entry matching hi and if present rewrites that > entry, > + * otherwise updates a random entry. A safe way to update the TLB. > +*/ > +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_tlbrwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned int mask) > +{ > + int index; > + tlbhi_t prev_hi; > + > + prev_hi = mips32_getentryhi (); > + mips32_setentryhi (hi); > + > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + > + index = mips32_getindex (); > + mips32_setentrylo0 (lo0); > + mips32_setentrylo1 (lo1); > + mips32_setpagemask (mask); > + mips_ehb (); /* mtc0 hazard on tlbwi/tlbwr */ > + > + /* Check if entry matches */ > + if (index >= 0) > + mips_tlbwi (); > + else > + mips_tlbwr (); > + > + mips32_setentryhi (prev_hi); > + > + return index; > +} > + > +/* > + * Reads the TLB entry specified by index, and returns the EntryHi, > + * EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmask > + * respectively. > +*/ > +void _MIPS_HAL_NOMIPS16 > +mips_tlbri2 (tlbhi_t *phi, tlblo_t *plo0, tlblo_t *plo1, > + unsigned int *pmask, int index) > +{ > + mips32_setindex (index); > + mips_ehb (); /* mtc0 hazard on tlbr */ > + mips_tlbr (); > + mips_ehb (); /* tlbr hazard on mfc0 */ > + *phi = mips32_getentryhi (); > + *plo0 = mips32_getentrylo0 (); > + *plo1 = mips32_getentrylo1 (); > + *pmask = mips32_getpagemask (); > + return; > +} > + > +/* > + * Probes the TLB for an entry matching hi and return its index, or -1 if > + * not found. If found, the EntryLo0, EntryLo1 and PageMask parts of the > + * entry are also returned in *plo0, *plo1 and *pmask respectively. > +*/ > +int __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_tlbprobe2 (tlbhi_t hi, tlblo_t *plo0, tlblo_t *plo1, > + unsigned int *pmask) > +{ > + int index; > + tlbhi_t prev_hi; > + > + prev_hi = mips32_getentryhi (); > + mips32_setentryhi (hi); > + > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + > + index = mips32_getindex (); > + > + if (index >= 0) > + { > + mips_tlbr (); > + mips_ehb (); /* tlbr hazard on mfc0 */ > + *plo0 = mips32_getentrylo0 (); > + *plo1 = mips32_getentrylo1 (); > + *pmask = mips32_getpagemask (); > + } > + else > + index = -1; > + > + mips32_setentryhi (prev_hi); /* restore EntryHi */ > + > + return index; > +} > + > +/* Probes the TLB for an entry matching hi, and if present invalidates it > */ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_tlbinval (tlbhi_t hi) > +{ > + int index, tmp_idx; > + tlbhi_t prev_hi, tmp_hi = 0; > + register const int zero = 0; > + unsigned int cfg; > + > + prev_hi = mips32_getentryhi (); > + mips32_setentryhi (hi); > + > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + > + index = mips32_getindex (); > + > + if (index < 0) > + goto restore; > + > + mips32_setentrylo0 (zero); > + mips32_setentrylo1 (zero); > + > + /* Check if Config4 is implemented */ > + cfg = mips32_getconfig3 (); > + if ((cfg & CFG3_M) != 0) > + { > + cfg = mips32_getconfig4 (); > + if ((cfg & CFG4_IE_MASK) != 0) > + { > + tmp_hi = C0_ENTRYHI_EHINV_MASK; > + goto do_tlbwi; > + } > + } > + > + tmp_hi = (tlbhi_t) ((unsigned long) KSEG0_BASE - 0x4000); > + > + do > + { > + tmp_hi = tmp_hi + 0x4000; > + mips32_setentryhi (tmp_hi); > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + tmp_idx = mips32_getindex (); > + } > + while (tmp_idx >= 0); > + > + mips32_setindex (index); /* restore Index */ > + > +do_tlbwi: > + mips32_setentryhi (tmp_hi); > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbwi (); > + mips_ehb (); /* tlbwi hazard on mfc0 */ > + > +restore: > + mips32_setentryhi (prev_hi); /* restore EntryHi */ > + > + return; > +} > + > +/* > + * Return number of entries and sets in TLB. > + * Return number of entries in *pentries and > + * sets in *psets > +*/ > +static void _MIPS_HAL_NOMIPS16 > +mips_tlb_entries_sets (int *pentries, int *psets) > +{ > + int entries = 0, sets = 0, ways = 0; > + unsigned int cfg, cfg1, tcfg, tmp; > + > + cfg = mips32_getconfig (); > + cfg = (cfg & CFG0_MT_MASK) >> CFG0_MT_SHIFT; > + if ((cfg == 0) /* No MMU */ > + || (cfg == (CFG0_MT_FIXED >> CFG0_MT_SHIFT)) /* fixed address > translation */ > + || (cfg == (CFG0_MT_BAT >> CFG0_MT_SHIFT)) /* block address > translator */ > + || ((cfg & ((CFG0_MT_TLB | CFG0_MT_DUAL) >> CFG0_MT_SHIFT)) == 0)) > /* presence of TLB */ > + { > + *pentries = 0; > + *psets = 0; > + return; > + } > + > + cfg1 = mips32_getconfig1 (); > + > + /* > + * As per PRA, field holds number of entries - 1 > + * Standard TLBs and dual TLBs have extension fields. > + */ > + entries = ((cfg1 & CFG1_MMUS_MASK) >> CFG1_MMUSSHIFT) + 1; > + > + tcfg = mips32_getconfig3 (); > + if ((tcfg & CFG3_M) == 0) > + goto doReturn; > + > + tcfg = mips32_getconfig4 (); > + > +#if (__mips_isa_rev < 6) > + tmp = (tcfg & CFG4_MMUED) >> CFG4_MMUED_SHIFT; > + > + /* MMU Extension Definition */ > + if (tmp == (CFG4_MMUED_FTLBVEXT >> CFG4_MMUED_SHIFT)) > + goto doFTLBVTLB; > + > + /* MMUSizeExt */ > + if (tmp == (CFG4_MMUED_SIZEEXT >> CFG4_MMUED_SHIFT)) > + goto doSizeExt; > + > + if (tmp == 0) > + goto doReturn; > + > + goto doFTLBSize; > + > +doSizeExt: > + entries += ((tcfg & CFG4_MMUSE_MASK) >> CFG4_MMUSE_SHIFT) > + << CFG1_MMUS_BITS; > + goto doReturn; > +#endif > + > +doFTLBVTLB: > + entries += ((tcfg & CFG4_VTLBSEXT_MASK) >> CFG4_VTLBSEXT_SHIFT) > + << CFG1_MMUS_BITS; > + > +doFTLBSize: > + /* Skip FTLB size calculations if Config:MT != 4 */ > + if (cfg != (CFG0_MT_DUAL >> CFG0_MT_SHIFT)) > + goto doReturn; > + > + /* Ways */ > + ways = 2 + ((tcfg & CFG4_FTLBW_MASK) >> CFG4_FTLBW_SHIFT); > + > + /* Sets per way */ > + tmp = ((tcfg & CFG4_FTLBS_MASK) >> CFG4_FTLBS_SHIFT); > + sets = 1 << tmp; > + > + /* Total sets */ > + entries += ways << tmp; > + > +doReturn: > + *pentries = entries; > + *psets = sets; > + > + return; > +} > + > +/* > + * Return number of entries in TLB > + * This function is used for both mips64 and mips32 > +*/ > +int _MIPS_HAL_NOMIPS16 > +mips_tlb_size (void) > +{ > + int entries = 0, sets = 0; > + mips_tlb_entries_sets (&entries, &sets); > + (void) sets; > + return entries; > +} > + > +/* > + * Invalidate the whole TLB. > + * This function is used for both mips64 and mips32 > +*/ > +void __attribute__ ((use_hazard_barrier_return)) _MIPS_HAL_NOMIPS16 > +mips_tlbinvalall (void) > +{ > + unsigned int cfg0, cfg; > + unsigned long tmp_hi, tmp_hi2; > + int entries = 0, sets = 0, tlb_stride = 0; > + int end_ptr = 0, index = 0; > + register const unsigned long zero = 0; > + extern void *__tlb_stride_length; > + > + cfg0 = mips32_getconfig (); > + cfg0 = (cfg0 & CFG0_MT_MASK) >> CFG0_MT_SHIFT; > + if ((cfg0 == 0) /* No MMU */ > + || (cfg0 == (CFG0_MT_FIXED >> CFG0_MT_SHIFT)) /* fixed address > translation */ > + || (cfg0 == (CFG0_MT_BAT >> CFG0_MT_SHIFT))) /* block address > translator */ > + goto doReturn; > + > + mips_setentrylo0 (zero); > + mips_setentrylo1 (zero); > + mips_setpagemask (zero); > + > + /* Fetch size & number of sets */ > + mips_tlb_entries_sets (&entries, &sets); > + > + cfg = mips32_getconfig3 (); > + if ((cfg & CFG3_M) == 0) > + goto doBasicInval; > + > + cfg = mips32_getconfig4 (); > + cfg = (cfg & CFG4_IE_MASK) >> CFG4_IE_SHIFT; > + > + /* If Config4[IE] = 0, use old method for invalidation */ > + if (cfg == 0) > + goto doBasicInval; > + > + /* If Config4[IE] = 1, EHINV loop */ > + if (cfg == (CFG4_IE_EHINV >> CFG4_IE_SHIFT)) > + goto doEHINV; > + > + /* If Config[MT] = 1, one instruction required */ > + if (cfg0 == (CFG0_MT_TLB >> CFG0_MT_SHIFT) > + || cfg == (CFG4_IE_INVALL >> CFG4_IE_SHIFT)) > + { > + /* TLB walk done by hardware, Config4[IE] = 3 or Config[MT] = 1 */ > + mips32_setindex (zero); > + mips_ehb (); > + mips_eva_tlbinvf (); > + goto doReturn; > + } > + > + /* > + * TLB walk done by software, Config4[IE] = 2, Config[MT] = 4 > + * > + * One TLBINVF is executed with an index in VTLB range to > + * invalidate all VTLB entries. > + * > + * One TLBINVF is executed per FTLB set. > + * > + * We'll clean out the TLB by computing the Size of the VTLB > + * but not add the 1. This will give us a finger that points > + * at the last VTLB entry. > + */ > + > + /* Clear VTLB */ > + mips32_setindex (zero); > + mips_ehb (); > + mips_eva_tlbinvf (); > + > + tlb_stride = (int) ((unsigned long) &__tlb_stride_length); > + sets = sets * tlb_stride; > + end_ptr = entries - sets; > + > + do > + { > + entries = entries - tlb_stride; > + mips32_setindex (entries); > + mips_ehb (); > + mips_eva_tlbinvf (); > + } > + while (entries != end_ptr); > + > + goto doReturn; > + > +doEHINV: > + /* > + * Config4[IE] = 1. EHINV supported, but not tlbinvf. > + * > + * Invalidate the TLB for R3 onwards by loading EHINV and writing to all > + * TLB entries. > + */ > + index = 0; > + tmp_hi = C0_ENTRYHI_EHINV_MASK; > + mips_setentryhi (tmp_hi); > + do > + { > + mips32_setindex (index); > + mips_ehb (); /* mtc0 hazard on tlbwi */ > + mips_tlbwi (); > + index++; > + } > + while (entries != index); > + > + goto doReturn; > + > +doBasicInval: > + /* > + * Perform a basic invalidation of the TLB for R1 onwards by loading > + * 0x(FFFFFFFF)KSEG0_BASE into EntryHi and writing it into index 0 > + * incrementing by a pagesize, writing into index 1, etc. > + * If large physical addressing is enabled, load 0xFFFFFFFF > + * into the top half of EntryHi. > + */ > + tmp_hi = 0; > + cfg = mips32_getconfig3 (); > + > + /* If XPA is present */ > + if ((cfg & CFG3_LPA) != 0) > + { > + cfg = mips32_getpagegrain (); > + if ((cfg & PAGEGRAIN_ELPA) == 0) > + tmp_hi = 0xFFFFFFFF; > + } > + > + tmp_hi2 = (unsigned long) KSEG0_BASE - 0x4000; > + index = 0; > + > + do > + { > + tmp_hi2 += 0x4000; > + mips_setentryhi (tmp_hi2); > + if (tmp_hi != 0) > + mips32_sethientryhi (tmp_hi); > + mips_ehb (); /* mtc0 hazard on tlbp */ > + mips_tlbp (); > + mips_ehb (); /* tlbp hazard on mfc0 */ > + if (mips32_getindex () == 0) > + continue; > + mips32_setindex (index); > + mips_ehb (); /* mtc0 hazard on tlbwi */ > + mips_tlbwi (); > + index++; > + } > + while (entries != index); > + > +doReturn: > + /* > + * Clear EntryHI. The upper half is cleared > + * autmatically as mtc0 writes zeroes. > + */ > + mips_setentryhi (zero); > + > + return; > +} > + > +_MIPS_HAL_NOMIPS16 > +int m64_tlb_size (void) __attribute__ ((alias ("mips_tlb_size"))); > +_MIPS_HAL_NOMIPS16 > +void m64_tlbinvalall (void) __attribute__ ((alias ("mips_tlbinvalall"))); > diff --git a/libgloss/mips/hal/mips_xpa.S b/libgloss/mips/hal/mips_xpa.S > new file mode 100644 > index 000000000..5f47e8ff3 > --- /dev/null > +++ b/libgloss/mips/hal/mips_xpa.S > @@ -0,0 +1,78 @@ > +/* > + * Copyright 2015-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <mips/regdef.h> > +#include <mips/cpu.h> > +#include <mips/asm.h> > +#include <mips/hal.h> > +#include <mips/endian.h> > + > +MIPS_NOMIPS16 > + > +/* > + * FUNCTION: _xpa_save > + * DESCRIPTION: save the XPA version of badvaddr. > + * RETURNS: int > + * 0: No context saved > + * CTX_*: Type of conext stored > + */ > +LEAF(_xpa_save) > + move a1, a0 > + PTR_S zero, LINKCTX_NEXT(a1) > + /* Test for LPA support */ > + mfc0 t0, C0_CONFIG3 > + ext t0, t0, CFG3_LPA_SHIFT, 1 > + beqz t0, 1f > + /* Test for LPA enabled */ > + mfc0 t0, C0_PAGEGRAIN > + ext t0, t0, PAGEGRAIN_ELPA_SHIFT, PAGEGRAIN_ELPA_BITS > + bnez t0, 2f > + > + /* LPA either unavailable or not enabled - return 0 */ > +1: move va0, zero > + jr ra > + > +2: lui va0, %hi(LINKCTX_TYPE_XPA) > + addiu va0, va0, %lo(LINKCTX_TYPE_XPA) > + mfc0 t0, C0_BADVADDR > + .set push > + .set xpa > + mfhc0 t1, C0_BADVADDR > + .set pop > +#if BYTE_ORDER == BIG_ENDIAN > + sw t0, XPACTX_BADVADDR(a1) > + sw t1, (XPACTX_BADVADDR+4)(a1) > +#else /* BYTE ORDER == LITTLE_ENDIAN */ > + sw t1, XPACTX_BADVADDR(a1) > + sw t0, (XPACTX_BADVADDR+4)(a1) > +#endif > + REG_S va0, LINKCTX_ID(a1) > + jr ra > +END(_xpa_save) > diff --git a/libgloss/mips/hal/syscalls.c b/libgloss/mips/hal/syscalls.c > new file mode 100644 > index 000000000..d296f538f > --- /dev/null > +++ b/libgloss/mips/hal/syscalls.c > @@ -0,0 +1,51 @@ > +#include <_ansi.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <mips/hal.h> > + > +extern char _end[]; > + > +/* FIXME: This is not ideal, since we do a get_ram_range() call for > + every sbrk() call. */ > +char * > +sbrk (int nbytes) > +{ > + static char *heap_ptr = NULL; > + static char *heap_start = NULL; > + static unsigned long heap_size = 0; > + char *base; > + unsigned int avail = 0; > + void *ram_base; > + void *ram_extent; > + > + if (heap_start == NULL) > + { > + _get_ram_range (&ram_base, &ram_extent); > + > + /* If the _end symbol is within the RAM then use _end. */ > + if ((void*)_end > ram_base && (void*)_end < ram_extent) > + { > + heap_start = _end; > + heap_ptr = _end; > + heap_size = ram_extent - (void*)_end; > + } > + else > + { > + heap_start = ram_base; > + heap_ptr = ram_base; > + heap_size = ram_extent - ram_base; > + } > + } > + > + if ((heap_ptr >= heap_start) && (heap_ptr < (heap_start + heap_size))) { > + avail = (heap_start + heap_size) - heap_ptr; > + base = heap_ptr; > + } /* else will fail since "nbytes" will be greater than zeroed "avail" > value */ > + > + if ((nbytes > avail) || (heap_ptr + nbytes < heap_start)) > + base = (char *)-1; > + else > + heap_ptr += nbytes; > + > + return base; > +} > diff --git a/libgloss/mips/include/mips/asm.h > b/libgloss/mips/include/mips/asm.h > new file mode 100644 > index 000000000..ac9157511 > --- /dev/null > +++ b/libgloss/mips/include/mips/asm.h > @@ -0,0 +1,356 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_ASM_H_ > +#define _MIPS_ASM_H_ > + > +/* > + * asm.h: various macros to help assembly language writers > + */ > + > +/* ABI specific stack frame layout and manipulation. */ > +#if _MIPS_SIM==_ABIO32 > +/* Standard O32 */ > +#define SZREG 4 /* saved register size */ > +#define REG_S sw /* store saved register */ > +#define REG_L lw /* load saved register */ > +#define SZARG 4 /* argument register size */ > +#define NARGSAVE 4 /* arg register space on caller > stack */ > +#define ALSZ 7 /* stack alignment - 1 */ > +#define ALMASK (~7) /* stack alignment mask */ > +#define LOG2_STACK_ALGN 3 /* log2(8) */ > +#define SZPTR 4 /* pointer size */ > +#define LOG2_SZPTR 2 /* log2(4) */ > +#define PTR_S sw /* store pointer */ > +#define PTR_L lw /* load pointer */ > +#define PTR_SUBU subu /* decrement pointer */ > +#define PTR_ADDU addu /* increment pointer */ > +#define PTR_MFC0 mfc0 /* access CP0 pointer width register */ > +#define PTR_MTC0 mtc0 /* access CP0 pointer width register */ > +#define LA la /* load an address */ > +#define PTR .word /* pointer type pseudo */ > +#elif _MIPS_SIM==_ABIO64 > +/* Cygnus O64 */ > +#define SZREG 8 /* saved register size */ > +#define REG_S sd /* store saved register */ > +#define REG_L ld /* load saved register */ > +#define SZARG 8 /* argument register size */ > +#define NARGSAVE 4 /* arg register space on caller > stack */ > +#define ALSZ 7 /* stack alignment - 1 */ > +#define ALMASK (~7) /* stack alignment mask */ > +#define LOG2_STACK_ALGN 3 /* log2(8) */ > +#define SZPTR 4 /* pointer size */ > +#define LOG2_SZPTR 2 /* log2(4) */ > +#define PTR_S sw /* store pointer */ > +#define PTR_L lw /* load pointer */ > +#define PTR_SUBU subu /* decrement pointer */ > +#define PTR_ADDU addu /* increment pointer */ > +#define PTR_MFC0 dmfc0 /* access CP0 pointer width register */ > +#define PTR_MTC0 mtc0 /* access CP0 pointer width register */ > +#define LA la /* load an address */ > +#define PTR .word /* pointer type pseudo */ > +#elif _MIPS_SIM==_ABIN32 > +/* Standard N32 */ > +#define SZREG 8 /* saved register size */ > +#define REG_S sd /* store saved register */ > +#define REG_L ld /* load saved register */ > +#define SZARG 8 /* argument register size */ > +#define NARGSAVE 0 /* arg register space on caller > stack */ > +#define ALSZ 15 /* stack alignment - 1 */ > +#define ALMASK (~15) /* stack alignment mask */ > +#define LOG2_STACK_ALGN 4 /* log2(16) */ > +#define SZPTR 4 /* pointer size */ > +#define LOG2_SZPTR 2 /* log2(4) */ > +#define PTR_S sw /* store pointer */ > +#define PTR_L lw /* load pointer */ > +#define PTR_SUBU subu /* decrement pointer (SGI uses sub) */ > +#define PTR_ADDU addu /* increment pointer (SGI uses add) */ > +#define PTR_MFC0 mfc0 /* access CP0 pointer width register */ > +#define PTR_MTC0 mtc0 /* access CP0 pointer width register */ > +#define LA la /* load an address */ > +#define PTR .word /* pointer type pseudo */ > +#elif _MIPS_SIM==_ABI64 > +/* Standard N64 */ > +#define SZREG 8 /* saved register size */ > +#define REG_S sd /* store saved register */ > +#define REG_L ld /* load saved register */ > +#define SZARG 8 /* argument register size */ > +#define NARGSAVE 0 /* arg register space on caller > stack */ > +#define ALSZ 15 /* stack alignment - 1 */ > +#define ALMASK (~15) /* stack alignment mask */ > +#define LOG2_STACK_ALGN 4 /* log2(16) */ > +#define SZPTR 8 /* pointer size */ > +#define LOG2_SZPTR 3 /* log2(8) */ > +#define PTR_S sd /* store pointer */ > +#define PTR_L ld /* load pointer */ > +#define PTR_SUBU dsubu /* decrement pointer */ > +#define PTR_ADDU daddu /* increment pointer */ > +#define PTR_MFC0 dmfc0 /* access CP0 pointer width register */ > +#define PTR_MTC0 dmtc0 /* access CP0 pointer width register */ > +#define LA dla /* load an address */ > +#define PTR .dword /* pointer type pseudo */ > +#else > +#error Unknown ABI > +#endif > + > +#ifdef __ASSEMBLER__ > + > +/* Concatenate two names. */ > +#ifdef __STDC__ > +# define _ASMCONCAT(A, B) A ## B > +#else > +# define _ASMCONCAT(A, B) A/**/B > +#endif > + > +/* Name of reset code section. */ > +#ifndef _RESET_SECTION > +# define _RESET_SECTION .section .reset, "ax", @progbits > +#endif > + > +#ifndef _RESET_SECTION_NAMED > +/* No function section support for now, since binutils fails to cope with > + external branches. */ > +# define _RESET_SECTION_NAMED(name) .pushsection .reset, "ax", @progbits > +#endif > + > +/* Name of boot code section. */ > +#ifndef _BOOT_SECTION > +# define _BOOT_SECTION .section .boot, "ax", @progbits > +#endif > + > +#ifndef _BOOT_SECTION_NAMED > +/* No function section support for now, since binutils fails to cope with > + external branches. */ > +# define _BOOT_SECTION_NAMED(name) .pushsection .boot, "ax", @progbits > +#endif > + > +/* Name of standard code section. */ > +#ifndef _NORMAL_SECTION_UNNAMED > +# define _NORMAL_SECTION_UNNAMED .section .text, "ax", @progbits > +#endif > + > +#ifndef _NORMAL_SECTION_NAMED > +# ifdef _FUNCTION_SECTIONS_ > +# define _NORMAL_SECTION_NAMED(name) .pushsection .text ##.name, "ax", > @progbits > +# else > +# define _NORMAL_SECTION_NAMED(name) .pushsection .text, "ax", @progbits > +# endif > +#endif > + > +/* Default code section. */ > +#ifndef _TEXT_SECTION_NAMED > +# if defined(_RESETCODE) > +# define _TEXT_SECTION_NAMED _RESET_SECTION_NAMED > +# elif defined(_BOOTCODE) > +# define _TEXT_SECTION_NAMED _BOOT_SECTION_NAMED > +# else > +# define _TEXT_SECTION_NAMED _NORMAL_SECTION_NAMED > +# endif > +#endif > + > +#ifndef _TEXT_SECTION > +# if defined(_RESETCODE) > +# define _TEXT_SECTION _RESET_SECTION > +# elif defined(_BOOTCODE) > +# define _TEXT_SECTION _BOOT_SECTION > +# else > +# define _TEXT_SECTION _NORMAL_SECTION_UNNAMED > +# endif > + _TEXT_SECTION > +#endif > + > +/* > + * Leaf functions declarations. > + */ > + > +/* Global leaf function. */ > +#define LEAF(name) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .globl name; \ > + .ent name; \ > +name: > + > +/* Static/Local leaf function. */ > +#define SLEAF(name) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .ent name; \ > +name: > + > +/* Weak leaf function. */ > +#define WLEAF(name) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .weak name; \ > + .ent name; \ > +name: > + > +/* Weak alias leaf function. */ > +#define ALEAF(name,alias) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .weak alias; \ > + .ent name; \ > + alias = name; \ > +name: > + > +/* > + * Alternative function entrypoints. > + */ > + > +/* Global alternative entrypoint. */ > +#define AENT(name) \ > + .globl name; \ > + .aent name; \ > +name: > +#define XLEAF(name) AENT(name) > + > +/* Local/static alternative entrypoint. */ > +#define SAENT(name) \ > + .aent name; \ > +name: > +#define SXLEAF(name) SAENT(name) > + > + > +/* > + * Leaf functions declarations. > + */ > + > +/* Global nested function. */ > +#define NESTED(name, framesz, rareg) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .globl name; \ > + .ent name; \ > + .frame sp, framesz, rareg; \ > +name: > + > +/* Static/Local nested function. */ > +#define SNESTED(name, framesz, rareg) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .ent name; \ > + .frame sp, framesz, rareg; \ > +name: > + > +/* Weak nested function. */ > +#define WNESTED(name, framesz, rareg) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .weak name; \ > + .ent name; \ > + .frame sp, framesz, rareg; \ > +name: > + > +/* Weak alias nested function. */ > +#define ANESTED(name, alias, framesz, rareg) \ > + _TEXT_SECTION_NAMED(name); \ > + .balign 4; \ > + .weak alias; \ > + .ent name; \ > + alias = name; \ > + .frame sp, framesz, rareg; \ > +name: > + > +/* > + * Function termination > + */ > +#define END(name) \ > + .size name,.-name; \ > + .end name; \ > + .popsection > + > +#define SEND(name) END(name) > +#define WEND(name) END(name) > +#define AEND(name,alias) END(name) > + > +/* > + * Global data declaration. > + */ > +#define EXPORT(name) \ > + .globl name; \ > + .type name,@object; \ > +name: > + > +/* > + * Global data declaration with size. > + */ > +#define EXPORTS(name,sz) \ > + .globl name; \ > + .type name,@object; \ > + .size name,sz; \ > +name: > + > +/* > + * Weak data declaration with size. > + */ > +#define WEXPORT(name,sz) \ > + .weak name; \ > + .type name,@object; \ > + .size name,sz; \ > +name: > + > +/* > + * Global data reference with size. > + */ > +#define IMPORT(name, size) \ > + .extern name,size > + > +/* > + * Global zeroed data. > + */ > +#define BSS(name,size) \ > + .type name,@object; \ > + .comm name,size > + > +/* > + * Local zeroed data. > + */ > +#define LBSS(name,size) \ > + .lcomm name,size > + > +/* > + * Insert call to _mcount if profiling. > + */ > +#ifdef __PROFILING__ > +#define _MCOUNT \ > + .set push; \ > + .set noat; \ > + move $1,$31; \ > + jal _mcount; \ > + .set pop > +#else > +#define _MCOUNT > +#endif > + > +#endif /* __ASSEMBLER__ */ > + > +#endif /*_MIPS_ASM_H_*/ > diff --git a/libgloss/mips/include/mips/cm3.h > b/libgloss/mips/include/mips/cm3.h > new file mode 100644 > index 000000000..251d39782 > --- /dev/null > +++ b/libgloss/mips/include/mips/cm3.h > @@ -0,0 +1,77 @@ > +/* > + * Copyright 2015-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _CM3_H_ > +#define _CM3_H_ > + > +#define CMGCR_BASE_ADDR_SHIFT 11 > + > +#define CMGCR_BASE_ADDR_LSHIFT 4 > +/* Offsets of memory-mapped registers */ > +#define GCR_L2_CONFIG 0x130 > +#define GCR_L2_RAM_CONFIG 0x240 > +#define GCR_TAG_ADDR 0x600 > +#define GCR_TAG_STATE 0x608 > +#define GCR_TAG_DATA 0x610 > +#define GCR_TAG_ECC 0x618 > + > +/* Contents of L2 RAM field */ > +#define GCR_L2_RAM_HCID_SHIFT 30 > +#define GCR_L2_RAM_HCID_BITS 1 > +#define GCR_L2_RAM_HCIS_SHIFT 29 > +#define GCR_L2_RAM_HCIS_BITS 1 > + > +/* L2 Configuration Register */ > +#define GCR_L2_REG_EXISTS_MASK 0x80000000 > +#define GCR_L2_REG_EXISTS_SHIFT 31 > +#define GCR_L2_REG_EXISTS_BITS 1 > +#define GCR_L2_LRU_WE_MASK (1<<GCR_L2_LRU_WE_SHIFT) > +#define GCR_L2_LRU_WE_SHIFT 26 > +#define GCR_L2_LRU_WE_BITS 1 > +#define GCR_L2_TAG_WE_MASK (1<<GCR_L2_TAG_WE_SHIFT) > +#define GCR_L2_TAG_WE_SHIFT 25 > +#define GCR_L2_TAG_WE_BITS 1 > +#define GCR_L2_ECC_WE_MASK (1<<GCR_L2_ECC_WE_SHIFT) > +#define GCR_L2_ECC_WE_SHIFT 24 > +#define GCR_L2_ECC_WE_BITS 1 > +#define GCR_L2_BYPASS_MASK (1<<GCR_L2_BYPASS_SHIFT) > +#define GCR_L2_BYPASS_SHIFT 20 > +#define GCR_L2_BYPASS_BITS 1 > +#define GCR_L2_SS_MASK 0x0000F000 > +#define GCR_L2_SS_SHIFT 12 > +#define GCR_L2_SS_BITS 4 > +#define GCR_L2_SL_MASK 0x00000F00 > +#define GCR_L2_SL_SHIFT 8 > +#define GCR_L2_SL_BITS 4 > +#define GCR_L2_SA_MASK 0x000000FF > +#define GCR_L2_SA_SHIFT 0 > +#define GCR_L2_SA_BITS 8 > + > +#endif /* _CM3_H_ */ > diff --git a/libgloss/mips/include/mips/cpu.h > b/libgloss/mips/include/mips/cpu.h > new file mode 100644 > index 000000000..067e1a14c > --- /dev/null > +++ b/libgloss/mips/include/mips/cpu.h > @@ -0,0 +1,356 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _CPU_H_ > +#define _CPU_H_ > + > +#if !defined(__ASSEMBLER__) > +#include <sys/types.h> > +#endif > + > +#ifndef SR_IMASK > +#if __mips == 64 > +#include <mips/m64c0.h> > +#elif __mips == 32 > +#include <mips/m32c0.h> > +#endif > +#endif /* SR_IMASK */ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#if !defined(__ASSEMBLER__) > +/* > + * Generic MIPS cache handling > + * > + * primary: virtual index, physical tag, write back; > + * secondary: physical index, physical tag, write back; > + * pass correct virtual address to primary cache routines. > + */ > + > +#ifdef __mips16 > +# define _MIPS_CPU_NOMIPS16 __attribute__((nomips16)) > +#else > +# define _MIPS_CPU_NOMIPS16 > +#endif > + > +extern int mips_icache_size, mips_icache_linesize, mips_icache_ways; > +extern int mips_dcache_size, mips_dcache_linesize, mips_dcache_ways; > +extern int mips_scache_size, mips_scache_linesize, mips_scache_ways; > +extern int mips_tcache_size, mips_tcache_linesize, mips_tcache_ways; > + > +/* these are now the only standard interfaces to the caches */ > +_MIPS_CPU_NOMIPS16 > +extern void mips_size_cache (void); > +_MIPS_CPU_NOMIPS16 > +extern void mips_flush_cache (void); > +_MIPS_CPU_NOMIPS16 > +extern void mips_flush_dcache (void); > +_MIPS_CPU_NOMIPS16 > +extern void mips_flush_icache (void); > +_MIPS_CPU_NOMIPS16 > +extern void mips_sync_icache (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_clean_cache (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_clean_dcache (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_clean_dcache_nowrite (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_clean_icache (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_lock_dcache (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_lock_icache (vaddr_t, size_t); > +_MIPS_CPU_NOMIPS16 > +extern void mips_lock_scache (vaddr_t, size_t); > + > +/* > + * Other common utilities for all CPUs > + */ > +extern void mips_wbflush (void); > +extern void mips_cycle (unsigned); > +_MIPS_CPU_NOMIPS16 > +extern int mips_tlb_size (void); > + > +/* > + * Coprocessor 0 register manipulation > + * Warning: all non-atomic in face of interrupts. > + */ > +#if defined(_mips_mfc0) > + > +/* exchange (swap) VAL and cp0 register REG */ > +#define _mips_mxc0(reg, val) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _mips_mfc0 (reg); \ > + _mips_mtc0 (reg, (val)); \ > + __o; \ > +}) > + > +/* bit clear non-zero bits from CLR in cp0 register REG */ > +#define _mips_bcc0(reg, clr) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _mips_mfc0 (reg); \ > + _mips_mtc0 (reg, __o & ~(clr)); \ > + __o; \ > +}) > + > +/* bit set non-zero bits from SET in cp0 register REG */ > +#define _mips_bsc0(reg, set) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _mips_mfc0 (reg); \ > + _mips_mtc0 (reg, __o | (set)); \ > + __o; \ > +}) > + > +/* bit clear nz bits in from CLR and set nz bits from SET in REG */ > +#define _mips_bcsc0(reg, clr, set) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _mips_mfc0 (reg); \ > + _mips_mtc0 (reg, (__o & ~(clr)) | (set)); \ > + __o; \ > +}) > + > +/* > + * Standard MIPS CP0 register access functions > + */ > + > +/* CP0 Status register (NOTE: not atomic operations) */ > +#define mips_getsr() _mips_mfc0(C0_SR) > +#define mips_setsr(v) _mips_mtc0(C0_SR,v) > +#define mips_xchsr(v) _mips_mxc0(C0_SR,v) > +#define mips_bicsr(clr) _mips_bcc0(C0_SR,clr) > +#define mips_bissr(set) _mips_bsc0(C0_SR,set) > +#define mips_bcssr(c,s) _mips_bcsc0(C0_SR,c,s) > + > +/* CP0 Cause register (NOTE: not atomic operations) */ > +#define mips_getcr() _mips_mfc0(C0_CR) > +#define mips_setcr(v) _mips_mtc0(C0_CR,v) > +#define mips_xchcr(v) _mips_mxc0(C0_CR,v) > +#define mips_biccr(clr) _mips_bcc0(C0_CR,clr) > +#define mips_biscr(set) _mips_bsc0(C0_CR,set) > +#define mips_bcscr(c,s) _mips_bcsc0(C0_CR,c,s) > + > +/* CP0 PrID register */ > +#define mips_getprid() _mips_mfc0(C0_PRID) > + > +#ifdef C0_COUNT > +/* CP0 Count register */ > +#define mips_getcount() _mips_mfc0(C0_COUNT) > +#define mips_setcount(v) _mips_mtc0(C0_COUNT,v) > +#define mips_xchcount(v) _mips_mxc0(C0_COUNT,v) > +#endif > + > +#ifdef C0_COMPARE > +/* CP0 Compare register*/ > +#define mips_getcompare() _mips_mfc0(C0_COMPARE) > +#define mips_setcompare(v) _mips_mtc0(C0_COMPARE,v) > +#define mips_xchcompare(v) _mips_mxc0(C0_COMPARE,v) > +#endif > + > +#ifdef C0_CONFIG > +/* CP0 Config register */ > +#define mips_getconfig() _mips_mfc0(C0_CONFIG) > +#define mips_setconfig(v) _mips_mtc0(C0_CONFIG,v) > +#define mips_xchconfig(v) _mips_mxc0(C0_CONFIG,v) > +#define mips_bicconfig(c) _mips_bcc0(C0_CONFIG,c) > +#define mips_bisconfig(s) _mips_bsc0(C0_CONFIG,s) > +#define mips_bcsconfig(c,s) _mips_bcsc0(C0_CONFIG,c,s) > +#endif > + > +#ifdef C0_ECC > +/* CP0 ECC register */ > +#define mips_getecc() _mips_mfc0(C0_ECC) > +#define mips_setecc(x) _mips_mtc0(C0_ECC, x) > +#define mips_xchecc(x) _mips_mxc0(C0_ECC, x) > +#endif > + > +#ifdef C0_TAGLO > +/* CP0 TagLo register */ > +#define mips_gettaglo() _mips_mfc0(C0_TAGLO) > +#define mips_settaglo(x) _mips_mtc0(C0_TAGLO, x) > +#define mips_xchtaglo(x) _mips_mxc0(C0_TAGLO, x) > +#endif > + > +#ifdef C0_TAGHI > +/* CP0 TagHi register */ > +#define mips_gettaghi() _mips_mfc0(C0_TAGHI) > +#define mips_settaghi(x) _mips_mtc0(C0_TAGHI, x) > +#define mips_xchtaghi(x) _mips_mxc0(C0_TAGHI, x) > +#endif > + > +#ifdef C0_WATCHLO > +/* CP0 WatchLo register */ > +#define mips_getwatchlo() _mips_mfc0(C0_WATCHLO) > +#define mips_setwatchlo(x) _mips_mtc0(C0_WATCHLO, x) > +#define mips_xchwatchlo(x) _mips_mxc0(C0_WATCHLO, x) > +#endif > + > +#ifdef C0_WATCHHI > +/* CP0 WatchHi register */ > +#define mips_getwatchhi() _mips_mfc0(C0_WATCHHI) > +#define mips_setwatchhi(x) _mips_mtc0(C0_WATCHHI, x) > +#define mips_xchwatchhi(x) _mips_mxc0(C0_WATCHHI, x) > +#endif > + > +#endif /*_mips_mfc0*/ > + > +/* > + * Count-leading zeroes and ones. > + * Simulate with a function call if this CPU hasn't defined a > + * macro with a suitable asm. > + */ > +#if !defined(mips_clz) > +extern unsigned int _mips_clz(unsigned int); > +#define mips_clz(x) _mips_clz(x) > +#define mips_clo(x) _mips_clz(~(x)) > +#else > +#define _mips_have_clz 1 > +#endif > + > +#if !defined(mips_dclz) > +extern unsigned int _mips_dclz(unsigned long long); > +#define mips_dclz(x) _mips_dclz(x) > +#define mips_dclo(x) _mips_dclz(~(x)) > +#else > +#define _mips_have_dclz 1 > +#endif > + > +/* > + * Generic MIPS prefetch instruction for MIPS IV and > + * above. CPU-specific include files must define > + * prefetch "hint" codes. > + */ > +#if __mips >= 4 > +#define _mips_pref(OP,LOC) \ > +do { \ > + __asm__ ("pref %0,%1" : : "n" (OP), "m" (LOC)); \ > +} while (0) > +#else > +/* pref not available for MIPS16 */ > +#define _mips_pref(OP,LOC) (void)0 > +#endif > + > +#ifndef PREF_LOAD > +#define PREF_LOAD 0 > +#endif > +#ifndef PREF_STORE > +#define PREF_STORE 0 > +#endif > +#ifndef PREF_LOAD_STREAMED > +#define PREF_LOAD_STREAMED PREF_LOAD > +#define PREF_STORE_STREAMED PREF_STORE > +#endif > +#ifndef PREF_LOAD_RETAINED > +#define PREF_LOAD_RETAINED PREF_LOAD > +#define PREF_STORE_RETAINED PREF_STORE > +#endif > + > +#define mips_prefetch __builtin_prefetch > + > +#ifdef PREF_WRITEBACK_INVAL > +/* MIPS specific "nudge" (push to memory) operation */ > +#define mips_nudge(ADDR) \ > + _mips_pref(PREF_WRITEBACK_INVAL, *(ADDR)) > +#else > +#define mips_nudge(ADDR) (void)0 > +#endif > + > +#ifdef PREF_PREPAREFORSTORE > +/* MIPS specific "prepare for store" operation */ > +/* XXX Warning - may zero whole cache line, ensure cache line alignment */ > +#define mips_prepare_for_store(ADDR) \ > + _mips_pref(PREF_PREPAREFORSTORE, *(ADDR)) > +#else > +#define mips_prepare_for_store(ADDR) (void)0 > +#endif > + > +/* > + * Default versions of get/put for any MIPS CPU. > + */ > +#ifndef mips_get_byte > +#define mips_get_byte(addr, errp) (*(volatile unsigned char *)(addr)) > +#define mips_get_half(addr, errp) (*(volatile unsigned short > *)(addr)) > +#define mips_get_word(addr, errp) (*(volatile unsigned int *)(addr)) > +#define mips_get_dword(addr, errp) (*(volatile unsigned long long > *)(addr)) > + > +#define mips_put_byte(addr, v) (*(volatile unsigned char *)(addr)=(v), 0) > +#define mips_put_half(addr, v) (*(volatile unsigned short *)(addr)=(v), 0) > +#define mips_put_word(addr, v) (*(volatile unsigned int *)(addr)=(v), 0) > +#define mips_put_dword(addr, v) (*(volatile unsigned long long > *)(addr)=(v), 0) > +#endif /* mips_get_byte */ > + > +/* unoptimisable 2 instruction loop */ > + > +#define mips_cycle(count) \ > + do { \ > + unsigned int __count = (count); \ > + __asm__ volatile ("%(nop; nop; 1: bnez %0,1b; subu %0,1%)" \ > + : "+d" (__count)); \ > + } while (0) > + > +/* default implementation of _mips_intdisable is a function */ > + > +/* There are no microMIPS implementations that support MSA currently. */ > +#if !defined(__mips_micromips) > +# define MIPS_MSA_USABLE 1 > +#else > +# define MIPS_MSA_USABLE 0 > +#endif > + > +#else /* ASSEMBLER */ > + > +/* The correct way to use a hazard barrier return */ > + > +/* JR.HB does not resolve hazards from its delay slot. */ > +#define MIPS_JRHB(REG) \ > + .set push; \ > + .set noreorder; \ > + jr.hb REG; \ > + nop; \ > + .set pop > + > +#define MIPS_NOMICROMIPS \ > + .set nomicromips > + > +#define MIPS_NOMIPS16 \ > + .set nomips16 > + > +#endif /* !ASSEMBLER */ > + > +#ifdef __cplusplus > +} > +#endif > +#endif /*_CPU_H_*/ > diff --git a/libgloss/mips/include/mips/ctx.S > b/libgloss/mips/include/mips/ctx.S > new file mode 100644 > index 000000000..2257f0e33 > --- /dev/null > +++ b/libgloss/mips/include/mips/ctx.S > @@ -0,0 +1,149 @@ > +/* > + * Copyright 2016-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#include <mips/regdef.h> > +#include <mips/asm.h> > +#include <mips/cpu.h> > +#include <mips/hal.h> > + > +/* Save the hard context to a gp_ctx pointed to by k1. > + Leave the value of C0_STATUS in the return register. > + Leave the value of k1 unchanged. */ > + > +.macro _gpctx_save > + /* Save general registers. */ > + REG_S $1, CTX_REG(1) (k1) > + REG_S $2, CTX_REG(2) (k1) > + REG_S $3, CTX_REG(3) (k1) > + REG_S $4, CTX_REG(4) (k1) > + REG_S $5, CTX_REG(5) (k1) > + REG_S $6, CTX_REG(6) (k1) > + REG_S $7, CTX_REG(7) (k1) > + REG_S $8, CTX_REG(8) (k1) > + REG_S $9, CTX_REG(9) (k1) > + REG_S $10, CTX_REG(10) (k1) > + REG_S $11, CTX_REG(11) (k1) > + REG_S $12, CTX_REG(12) (k1) > + REG_S $13, CTX_REG(13) (k1) > + REG_S $14, CTX_REG(14) (k1) > + REG_S $15, CTX_REG(15) (k1) > + REG_S $16, CTX_REG(16) (k1) > + REG_S $17, CTX_REG(17)(k1) > + REG_S $18, CTX_REG(18)(k1) > + REG_S $19, CTX_REG(19)(k1) > + REG_S $20, CTX_REG(20)(k1) > + REG_S $21, CTX_REG(21)(k1) > + REG_S $22, CTX_REG(22)(k1) > + REG_S $23, CTX_REG(23)(k1) > + REG_S $24, CTX_REG(24)(k1) > + REG_S $25, CTX_REG(25)(k1) > + REG_S $26, CTX_REG(26)(k1) > + /* $27/k1 must be saved prior to using this macro. */ > + REG_S $28, CTX_REG(28)(k1) > + REG_S $29, CTX_REG(29)(k1) > + REG_S $30, CTX_REG(30)(k1) > + REG_S $31, CTX_REG(31)(k1) > + PTR_S $0, CTX_LINK(k1) /* Clear the link field. */ > + > + /* Check ISA release and optionally restore HI/LO registers. */ > +#if (__mips_isa_rev < 6) > + mfhi $9 > + REG_S $9, CTX_HI0(k1) > + mflo $10 > + REG_S $10, CTX_LO0(k1) > +#endif > + > + /* Save CP0 registers. */ > + PTR_MFC0 $31, C0_EPC > + REG_S $31, CTX_EPC(k1) > + mfc0 va0, C0_STATUS > + sw va0, CTX_STATUS(k1) > +.endm > + > +/* Restores a gp_ctx pointed to by a0. Leaves interrupts disabled and > + C0_EPC ready to eret. */ > + > +.macro _gpctx_load > + > + /* Check ISA release and optionally restore HI/LO registers. */ > +#if (__mips_isa_rev < 6) > + REG_L $9, CTX_HI0(a0) > + REG_L $10, CTX_LO0(a0) > + mthi $9 > + mtlo $10 > +#endif > + > + /* Restore the general registers. */ > + REG_L $1, CTX_REG(1)(a0) > + REG_L $2, CTX_REG(2)(a0) > + REG_L $3, CTX_REG(3)(a0) > + /* Do not restore $4 until the end. */ > + REG_L $5, CTX_REG(5)(a0) > + REG_L $6, CTX_REG(6)(a0) > + REG_L $7, CTX_REG(7)(a0) > + REG_L $8, CTX_REG(8)(a0) > + REG_L $9, CTX_REG(9)(a0) > + REG_L $10, CTX_REG(10)(a0) > + REG_L $11, CTX_REG(11)(a0) > + REG_L $12, CTX_REG(12)(a0) > + REG_L $13, CTX_REG(13)(a0) > + REG_L $14, CTX_REG(14)(a0) > + REG_L $15, CTX_REG(15)(a0) > + REG_L $16, CTX_REG(16)(a0) > + REG_L $17, CTX_REG(17)(a0) > + REG_L $18, CTX_REG(18)(a0) > + REG_L $19, CTX_REG(19)(a0) > + REG_L $20, CTX_REG(20)(a0) > + REG_L $21, CTX_REG(21)(a0) > + REG_L $22, CTX_REG(22)(a0) > + REG_L $23, CTX_REG(23)(a0) > + REG_L $24, CTX_REG(24)(a0) > + REG_L $25, CTX_REG(25)(a0) > + > + /* Restore CP0 registers, kernel registers and stack with > + interrupts disabled. */ > + di > + lw $27, CTX_STATUS(a0) > + REG_L $26, CTX_EPC(a0) > + mtc0 $27, C0_STATUS > + PTR_MTC0 $26, C0_EPC > + ehb > + > + REG_L $26, CTX_REG(26)(a0) > + REG_L $27, CTX_REG(27)(a0) > + REG_L $28, CTX_REG(28)(a0) > + REG_L $29, CTX_REG(29)(a0) > + REG_L $30, CTX_REG(30)(a0) > + REG_L $31, CTX_REG(31)(a0) > + > + /* Finally restore a0/$4. */ > + REG_L $4, CTX_REG(4)(a0) > + > +.endm > diff --git a/libgloss/mips/include/mips/dsp.h > b/libgloss/mips/include/mips/dsp.h > new file mode 100644 > index 000000000..b10c98561 > --- /dev/null > +++ b/libgloss/mips/include/mips/dsp.h > @@ -0,0 +1,60 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_ASE_H_ > +#define _MIPS_ASE_H_ > + > +/* 32-bit DSP Control register */ > +#define DSPCTL_POS_SHIFT 0 > +#define DSPCTL_POS_MASK 0x0000007f > +#define DSPCTL_SCOUNT_SHIFT 7 > +#define DSPCTL_SCOUNT_MASK 0x00001f80 > +#define DSPCTL_C 0x00002000 > +#define DSPCTL_OU_SHIFT 16 > +#define DSPCTL_OU_MASK 0x00ff0000 > +#define DSPCTL_OU_AC0OVF 0x00010000 > +#define DSPCTL_OU_AC1OVF 0x00020000 > +#define DSPCTL_OU_AC2OVF 0x00040000 > +#define DSPCTL_OU_AC3OVF 0x00080000 > +#define DSPCTL_OU_ALUOVF 0x00100000 > +#define DSPCTL_OU_MULOVF 0x00200000 > +#define DSPCTL_OU_SHFOVF 0x00400000 > +#define DSPCTL_OU_EXTOVF 0x00800000 > +#define DSPCTL_CCOND_SHIFT 24 > +#define DSPCTL_CCOND_MASK 0x0f000000 > + > +/* RDDSP/WRDSP instruction mask bits */ > +#define RWDSP_POS 0x01 > +#define RWDSP_SCOUNT 0x02 > +#define RWDSP_C 0x04 > +#define RWDSP_OU 0x08 > +#define RWDSP_CCOND 0x10 > + > +#endif /* _MIPS_DSP_H_ */ > diff --git a/libgloss/mips/include/mips/endian.h > b/libgloss/mips/include/mips/endian.h > new file mode 100644 > index 000000000..057af7e19 > --- /dev/null > +++ b/libgloss/mips/include/mips/endian.h > @@ -0,0 +1,96 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_ENDIAN_H_ > +#define _MIPS_ENDIAN_H_ > + > +#ifndef __ASSEMBLER__ > +#include <stdint.h> /* get compiler types */ > +#include <sys/types.h> > +#endif > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifndef BYTE_ORDER > +/* > + * Definitions for byte order, > + * according to byte significance from low address to high. > + */ > +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */ > +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) > */ > + > +#if defined(__MIPSEB__) || defined(MIPSEB) > +#define BYTE_ORDER BIG_ENDIAN > +#elif defined(__MIPSEL__) || defined(MIPSEL) > +#define BYTE_ORDER LITTLE_ENDIAN > +#else > +#error BYTE_ORDER > +#endif > + > +#ifndef __ASSEMBLER__ > + > +#if __mips_isa_rev >= 2 && ! __mips16 > + > +/* MIPS32r2 & MIPS64r2 can use the wsbh and rotate instructions, define > + MD_SWAP so that <sys/endian.h> will use them. */ > + > +#define MD_SWAP > + > +#define __swap16md(x) __extension__({ \ > + uint16_t __swap16md_x = (x); \ > + uint16_t __swap16md_v; \ > + __asm__ ("wsbh %0,%1" \ > + : "=d" (__swap16md_v) \ > + : "d" (__swap16md_x)); \ > + __swap16md_v; \ > +}) > + > +#define __swap32md(x) __extension__({ \ > + uint32_t __swap32md_x = (x); \ > + uint32_t __swap32md_v; \ > + __asm__ ("wsbh %0,%1; rotr %0,16" \ > + : "=d" (__swap32md_v) \ > + : "d" (__swap32md_x)); \ > + __swap32md_v; \ > +}) > + > +#endif > +#endif /* __ASSEMBLER__ */ > +#endif /* BYTE_ORDER */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#include <machine/endian.h> > + > +#endif /*_MIPS_ENDIAN_H_*/ > diff --git a/libgloss/mips/include/mips/fgregdef.h > b/libgloss/mips/include/mips/fgregdef.h > new file mode 100644 > index 000000000..b36ea159f > --- /dev/null > +++ b/libgloss/mips/include/mips/fgregdef.h > @@ -0,0 +1,128 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_FPREGDEF_H_ > +#define _MIPS_FPREGDEF_H_ > + > +/* result registers */ > +#define fv0 $f0 > +#define fv1 $f2 > + > +/* argument registers */ > +#define fa0 $f12 > +#if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ > + || (defined _ABI64 && _MIPS_SIM == _ABI64) > +#define fa1 $f13 > +#else > +#define fa1 $f14 > +#endif > + > +#if __mips_fpr == 64 > + > +/* 64-bit f.p. registers (-mips3 and above) */ > + > +/* temporary registers */ > +#define ft0 $f4 > +#define ft1 $f5 > +#define ft2 $f6 > +#define ft3 $f7 > +#define ft4 $f8 > +#define ft5 $f9 > +#define ft6 $f10 > +#define ft7 $f11 > +#define ft8 $f16 > +#define ft9 $f17 > +#define ft10 $f18 > +#define ft11 $f19 > + > +# if (defined _ABIN32 && _MIPS_SIM == _ABIN32) \ > + || (defined _ABI64 && _MIPS_SIM == _ABI64) > +/* saved registers */ > +# define fs0 $f20 > +# define fs1 $f21 > +# define fs2 $f22 > +# define fs3 $f23 > +# define fs4 $f24 > +# define fs5 $f35 > +# define fs6 $f26 > +# define fs7 $f27 > +# define fs8 $f28 > +# define fs9 $f29 > +# define fs10 $f30 > +# define fs11 $f31 > +# else > +/* o32 FP64 */ > +# define ft12 $f21 > +# define ft13 $f23 > +# define ft14 $f35 > +# define ft15 $f27 > +# define ft16 $f29 > +# define ft17 $f31 > +# define fs0 $f20 > +# define fs1 $f22 > +# define fs2 $f24 > +# define fs3 $f26 > +# define fs4 $f28 > +# define fs5 $f30 > +# endif > + > +#else > + > +/* 32-bit f.p. registers */ > + > +/* temporary registers */ > +#define ft0 $f4 > +#define ft1 $f5 > +#define ft2 $f6 > +#define ft3 $f7 > +#define ft4 $f8 > +#define ft5 $f9 > +#define ft6 $f10 > +#define ft7 $f11 > +#define ft8 $f12 > +#define ft9 $f13 > +#define ft10 $f14 > +#define ft11 $f15 > +#define ft12 $f16 > +#define ft13 $f17 > +#define ft14 $f18 > +#define ft15 $f19 > + > +/* saved registers */ > +#define fs0 $f20 > +#define fs1 $f22 > +#define fs2 $f24 > +#define fs3 $f26 > +#define fs4 $f28 > +#define fs5 $f30 > + > +#endif > + > +#endif /*_MIPS_FPREGDEF_H_*/ > diff --git a/libgloss/mips/include/mips/fpa.h > b/libgloss/mips/include/mips/fpa.h > new file mode 100644 > index 000000000..93dde7184 > --- /dev/null > +++ b/libgloss/mips/include/mips/fpa.h > @@ -0,0 +1,33 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#if __mips == 32 || __mips == 64 > +#include <mips/m32c1.h> > +#endif > diff --git a/libgloss/mips/include/mips/hal.h > b/libgloss/mips/include/mips/hal.h > new file mode 100644 > index 000000000..b161dfb89 > --- /dev/null > +++ b/libgloss/mips/include/mips/hal.h > @@ -0,0 +1,452 @@ > +/* > + * Copyright 2014-2018, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _HAL_H > +#define _HAL_H > + > +#include <mips/asm.h> > +#include <mips/m32c0.h> > + > +#if _MIPS_SIM == _ABIO32 > +#define UHI_ABI 0 > +#elif _MIPS_SIM == _ABIN32 > +#define UHI_ABI 1 > +#elif _MIPS_SIM == _ABI64 > +#define UHI_ABI 2 > +#else > +#error "UHI context structure is not defined for current ABI" > +#endif > + > +#define CTX_REG(REGNO) ((SZREG)*((REGNO)-1)) > + > +#define CTX_AT (CTX_REG(1)) > +#define CTX_V0 (CTX_REG(2)) > +#define CTX_V1 (CTX_REG(3)) > +#define CTX_A0 (CTX_REG(4)) > +#define CTX_A1 (CTX_REG(5)) > +#define CTX_A2 (CTX_REG(6)) > +#define CTX_A3 (CTX_REG(7)) > +#if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI > +# define CTX_A4 (CTX_REG(8)) > +# define CTX_A5 (CTX_REG(9)) > +# define CTX_A6 (CTX_REG(10)) > +# define CTX_A7 (CTX_REG(11)) > +# define CTX_T0 (CTX_REG(12)) > +# define CTX_T1 (CTX_REG(13)) > +# define CTX_T2 (CTX_REG(14)) > +# define CTX_T3 (CTX_REG(15)) > +#else > +# define CTX_T0 (CTX_REG(8)) > +# define CTX_T1 (CTX_REG(9)) > +# define CTX_T2 (CTX_REG(10)) > +# define CTX_T3 (CTX_REG(11)) > +# define CTX_T4 (CTX_REG(12)) > +# define CTX_T5 (CTX_REG(13)) > +# define CTX_T6 (CTX_REG(14)) > +# define CTX_T7 (CTX_REG(15)) > +#endif > +#define CTX_S0 (CTX_REG(16)) > +#define CTX_S1 (CTX_REG(17)) > +#define CTX_S2 (CTX_REG(18)) > +#define CTX_S3 (CTX_REG(19)) > +#define CTX_S4 (CTX_REG(20)) > +#define CTX_S5 (CTX_REG(21)) > +#define CTX_S6 (CTX_REG(22)) > +#define CTX_S7 (CTX_REG(23)) > +#define CTX_T8 (CTX_REG(24)) > +#define CTX_T9 (CTX_REG(25)) > +#define CTX_K0 (CTX_REG(26)) > +#define CTX_K1 (CTX_REG(27)) > +#define CTX_GP (CTX_REG(28)) > +#define CTX_SP (CTX_REG(29)) > +#define CTX_FP (CTX_REG(30)) > +#define CTX_RA (CTX_REG(31)) > +#define CTX_EPC (CTX_REG(32)) > +#define CTX_BADVADDR (CTX_REG(33)) > +#define CTX_HI0 (CTX_REG(34)) > +#define CTX_LO0 (CTX_REG(35)) > +#define CTX_HILO_SIZE (2*SZREG) > +#define CTX_LINK (CTX_REG(34)+CTX_HILO_SIZE) > +#define CTX_STATUS ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR) > +#define CTX_CAUSE ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+4) > +#define CTX_BADINSTR ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+8) > +#define CTX_BADPINSTR ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+12) > +#define CTX_SIZE ((CTX_REG(34))+CTX_HILO_SIZE+SZPTR+16) > + > +#define DSPCTX_DSPC ((SZREG)*2) > +#define DSPCTX_HI1 ((SZREG)*3) > +#define DSPCTX_HI2 ((SZREG)*4) > +#define DSPCTX_HI3 ((SZREG)*5) > +#define DSPCTX_LO1 ((SZREG)*6) > +#define DSPCTX_LO2 ((SZREG)*7) > +#define DSPCTX_LO3 ((SZREG)*8) > +#define DSPCTX_SIZE ((SZREG)*9) > + > +#define FP32CTX_CSR ((SZREG)*2) > +#define FP64CTX_CSR ((SZREG)*2) > +#define MSACTX_FCSR ((SZREG)*2) > +#define MSACTX_MSACSR ((SZREG)*3) > + > +#define MSACTX_0 ((SZREG)*4) > +#define MSACTX_1 (MSACTX_0 + (1 * 16)) > +#define MSACTX_2 (MSACTX_0 + (2 * 16)) > +#define MSACTX_3 (MSACTX_0 + (3 * 16)) > +#define MSACTX_4 (MSACTX_0 + (4 * 16)) > +#define MSACTX_5 (MSACTX_0 + (5 * 16)) > +#define MSACTX_6 (MSACTX_0 + (6 * 16)) > +#define MSACTX_7 (MSACTX_0 + (7 * 16)) > +#define MSACTX_8 (MSACTX_0 + (8 * 16)) > +#define MSACTX_9 (MSACTX_0 + (9 * 16)) > +#define MSACTX_10 (MSACTX_0 + (10 * 16)) > +#define MSACTX_11 (MSACTX_0 + (11 * 16)) > +#define MSACTX_12 (MSACTX_0 + (12 * 16)) > +#define MSACTX_13 (MSACTX_0 + (13 * 16)) > +#define MSACTX_14 (MSACTX_0 + (14 * 16)) > +#define MSACTX_15 (MSACTX_0 + (15 * 16)) > +#define MSACTX_16 (MSACTX_0 + (16 * 16)) > +#define MSACTX_17 (MSACTX_0 + (17 * 16)) > +#define MSACTX_18 (MSACTX_0 + (18 * 16)) > +#define MSACTX_19 (MSACTX_0 + (19 * 16)) > +#define MSACTX_20 (MSACTX_0 + (20 * 16)) > +#define MSACTX_21 (MSACTX_0 + (21 * 16)) > +#define MSACTX_22 (MSACTX_0 + (22 * 16)) > +#define MSACTX_23 (MSACTX_0 + (23 * 16)) > +#define MSACTX_24 (MSACTX_0 + (24 * 16)) > +#define MSACTX_25 (MSACTX_0 + (25 * 16)) > +#define MSACTX_26 (MSACTX_0 + (26 * 16)) > +#define MSACTX_27 (MSACTX_0 + (27 * 16)) > +#define MSACTX_28 (MSACTX_0 + (28 * 16)) > +#define MSACTX_29 (MSACTX_0 + (29 * 16)) > +#define MSACTX_30 (MSACTX_0 + (30 * 16)) > +#define MSACTX_31 (MSACTX_0 + (31 * 16)) > +#define MSACTX_SIZE (MSACTX_0 + (32 * 16)) > + > +#define FP32CTX_0 ((SZREG)*4) > +#define FP32CTX_2 (FP32CTX_0 + (1 * 8)) > +#define FP32CTX_4 (FP32CTX_0 + (2 * 8)) > +#define FP32CTX_6 (FP32CTX_0 + (3 * 8)) > +#define FP32CTX_8 (FP32CTX_0 + (4 * 8)) > +#define FP32CTX_10 (FP32CTX_0 + (5 * 8)) > +#define FP32CTX_12 (FP32CTX_0 + (6 * 8)) > +#define FP32CTX_14 (FP32CTX_0 + (7 * 8)) > +#define FP32CTX_16 (FP32CTX_0 + (8 * 8)) > +#define FP32CTX_18 (FP32CTX_0 + (9 * 8)) > +#define FP32CTX_20 (FP32CTX_0 + (10 * 8)) > +#define FP32CTX_22 (FP32CTX_0 + (11 * 8)) > +#define FP32CTX_24 (FP32CTX_0 + (12 * 8)) > +#define FP32CTX_26 (FP32CTX_0 + (13 * 8)) > +#define FP32CTX_28 (FP32CTX_0 + (14 * 8)) > +#define FP32CTX_30 (FP32CTX_0 + (15 * 8)) > +#define FP32CTX_SIZE (FP32CTX_30 + (17 * 8)) > + > +#define FP64CTX_0 ((SZREG)*4) > +#define FP64CTX_2 (FP64CTX_0 + (1 * 8)) > +#define FP64CTX_4 (FP64CTX_0 + (2 * 8)) > +#define FP64CTX_6 (FP64CTX_0 + (3 * 8)) > +#define FP64CTX_8 (FP64CTX_0 + (4 * 8)) > +#define FP64CTX_10 (FP64CTX_0 + (5 * 8)) > +#define FP64CTX_12 (FP64CTX_0 + (6 * 8)) > +#define FP64CTX_14 (FP64CTX_0 + (7 * 8)) > +#define FP64CTX_16 (FP64CTX_0 + (8 * 8)) > +#define FP64CTX_18 (FP64CTX_0 + (9 * 8)) > +#define FP64CTX_20 (FP64CTX_0 + (10 * 8)) > +#define FP64CTX_22 (FP64CTX_0 + (11 * 8)) > +#define FP64CTX_24 (FP64CTX_0 + (12 * 8)) > +#define FP64CTX_26 (FP64CTX_0 + (13 * 8)) > +#define FP64CTX_28 (FP64CTX_0 + (14 * 8)) > +#define FP64CTX_30 (FP64CTX_0 + (15 * 8)) > +#define FP64CTX_1 (FP64CTX_30 + (1 * 8)) > +#define FP64CTX_3 (FP64CTX_30 + (2 * 8)) > +#define FP64CTX_5 (FP64CTX_30 + (3 * 8)) > +#define FP64CTX_7 (FP64CTX_30 + (4 * 8)) > +#define FP64CTX_9 (FP64CTX_30 + (5 * 8)) > +#define FP64CTX_11 (FP64CTX_30 + (6 * 8)) > +#define FP64CTX_13 (FP64CTX_30 + (7 * 8)) > +#define FP64CTX_15 (FP64CTX_30 + (8 * 8)) > +#define FP64CTX_17 (FP64CTX_30 + (9 * 8)) > +#define FP64CTX_19 (FP64CTX_30 + (10 * 8)) > +#define FP64CTX_21 (FP64CTX_30 + (11 * 8)) > +#define FP64CTX_23 (FP64CTX_30 + (12 * 8)) > +#define FP64CTX_25 (FP64CTX_30 + (13 * 8)) > +#define FP64CTX_27 (FP64CTX_30 + (14 * 8)) > +#define FP64CTX_29 (FP64CTX_30 + (15 * 8)) > +#define FP64CTX_31 (FP64CTX_30 + (16 * 8)) > +#define FP64CTX_SIZE (FP64CTX_31 + (17 * 8)) > + > +#define FPCTX_SIZE() (mips_getsr() & SR_FR ? FP64CTX_SIZE : > FP32CTX_SIZE) > + > +#define XPACTX_BADVADDR ((SZREG)*2) > + > +#define LINKCTX_TYPE_MSA 0x004D5341 > +#define LINKCTX_TYPE_FP32 0x46503332 > +#define LINKCTX_TYPE_FP64 0x46503634 > +#define LINKCTX_TYPE_FMSA 0x463D5341 > +#define LINKCTX_TYPE_DSP 0x00445350 > +#define LINKCTX_TYPE_STKSWP 0x53574150 > +#define LINKCTX_TYPE_XPA 0x00585041 > + > +#define LINKCTX_ID ((SZREG)*0) > +#define LINKCTX_NEXT ((SZREG)*1) > + > +#define LINKCTX_TYPE(X) (((struct linkctx *)(X))->id) > + > +#define SWAPCTX_OLDSP ((SZREG)*2) > +#define SWAPCTX_SIZE ((SZREG)*3) > + > +#ifndef __ASSEMBLER__ > + > +#include <stdint.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +struct linkctx; > + > +#define C_CTX_REGNO(REGNO) ((REGNO) - 1) > + > +struct gpctx > +{ > + union > + { > + struct > + { > + reg_t at; > + reg_t v[2]; > +# if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI > + reg_t a[8]; > + reg_t t[4]; > +# else > + reg_t a[4]; > + reg_t t[8]; > +# endif > + reg_t s[8]; > + reg_t t2[2]; > + reg_t k[2]; > + reg_t gp; > + reg_t sp; > + reg_t fp; > + reg_t ra; > + }; > + reg_t r[31]; > + }; > + > + reg_t epc; > + reg_t badvaddr; > + reg_t hi; > + reg_t lo; > + /* This field is for future extension */ > + struct linkctx *link; > + /* Status at the point of the exception. This may not be restored > + on return from exception if running under an RTOS */ > + uint32_t status; > + /* These fields should be considered read-only */ > + uint32_t cause; > + uint32_t badinstr; > + uint32_t badpinstr; > +}; > + > +struct linkctx > +{ > + reg_t id; > + struct linkctx *next; > +}; > + > +struct swapctx > +{ > + struct linkctx link; > + reg_t oldsp; > +}; > + > +static inline void > +_linkctx_append (struct gpctx *gp, struct linkctx *nu) > +{ > + struct linkctx **ctx = (struct linkctx **)&gp->link; > + while (*ctx) > + ctx = &(*ctx)->next; > + *ctx = nu; > +} > + > +struct dspctx > +{ > + struct linkctx link; > + reg_t dspc; > + reg_t hi[3]; > + reg_t lo[3]; > +}; > + > +struct fpctx > +{ > + struct linkctx link; > + reg_t fcsr; > + reg_t reserved; > +}; > + > +typedef char _msareg[16] __attribute__ ((aligned(16))); > + > +struct msactx > +{ > + struct linkctx link; > + reg_t fcsr; > + reg_t msacsr; > + union > + { > + _msareg w[32]; > + double d[64]; > + float s[128]; > + }; > +}; > + > +#define MSAMSACTX_D(CTX, N) (CTX)->w[(N)] > +#define MSACTX_DBL(CTX, N) (CTX)->d[(N) << 1] > +#ifdef __MIPSEL__ > +#define MSACTX_SGL(CTX, N) (CTX)->s[(N) << 2] > +#else > +#define MSACTX_SGL(CTX, N) (CTX)->s[((N) << 2) | 1] > +#endif > + > +struct fp32ctx > +{ > + struct fpctx fp; > + union > + { > + double d[16]; /* even doubles */ > + float s[32]; /* even singles, padded */ > + }; > +}; > + > +#define FP32CTX_DBL(CTX, N) (CTX)->d[(N)] > +#ifdef __MIPSEL__ > +#define FP32CTX_SGL(CTX, N) (CTX)->s[(N)] > +#else > +#define FP32CTX_SGL(CTX, N) (CTX)->s[(N) ^ 1] > +#endif > + > +struct fp64ctx > +{ > + struct fpctx fp; > + union > + { > + double d[32]; /* even doubles, followed by odd doubles */ > + float s[64]; /* even singles, followed by odd singles, padded */ > + }; > +}; > + > +#define FP64CTX_DBL(CTX, N) (CTX)->d[((N) >> 1) + (((N) & 1) << 4)] > +#ifdef __MIPSEL__ > +#define FP64CTX_SGL(CTX, N) (CTX)->s[((N) & ~1) + (((N) & 1) << 5)] > +#else > +#define FP64CTX_SGL(CTX, N) (CTX)->s[((N) | 1) + (((N) & 1) << 5)] > +#endif > + > +struct xpactx > +{ > + struct linkctx link; > + reg64_t badvaddr; > +}; > + > +#ifdef __mips16 > +# define _MIPS_HAL_NOMIPS16 __attribute__((nomips16)) > +#else > +# define _MIPS_HAL_NOMIPS16 > +#endif > + > +extern reg_t _MIPS_HAL_NOMIPS16 > + _dspctx_save (struct dspctx *ptr); > +extern reg_t _MIPS_HAL_NOMIPS16 > + _dspctx_load (struct dspctx *ptr); > + > +extern reg_t _MIPS_HAL_NOMIPS16 > + _xpa_save (struct xpactx *ptr); > + > +extern reg_t _MIPS_HAL_NOMIPS16 > + _fpctx_save (struct fpctx *ptr); > +extern reg_t _MIPS_HAL_NOMIPS16 > + _fpctx_load (struct fpctx *ptr); > +extern reg_t _MIPS_HAL_NOMIPS16 > + _msactx_save (struct msactx *ptr); > +extern reg_t _MIPS_HAL_NOMIPS16 > + _msactx_load (struct msactx *ptr); > + > +/* Fall back exception handlers: > + _mips_handle_exception - May be implemented by a user but is aliased > + to __exception_handle by default. > + __exception_handle - Toolchain provided fallback handler. > +*/ > +extern void _MIPS_HAL_NOMIPS16 > + _mips_handle_exception (struct gpctx *ctx, int exception); > +extern void _MIPS_HAL_NOMIPS16 > + __exception_handle (struct gpctx *ctx, int exception); > + > +/* Obtain the largest available region of RAM */ > +extern void _MIPS_HAL_NOMIPS16 > + _get_ram_range (void **ram_base, void **ram_extent); > + > +/* Invoke a UHI operation via SDBBP using the provided context */ > +extern int _MIPS_HAL_NOMIPS16 > + __uhi_indirect (struct gpctx *); > + > +/* Report an unhandled exception */ > +extern int32_t _MIPS_HAL_NOMIPS16 > + __uhi_exception (struct gpctx *, int32_t); > + > +/* Print a message to a logger. Minimal formatting support for one > + integer argument. */ > +extern int32_t _MIPS_HAL_NOMIPS16 > + __plog (int8_t *, int32_t); > + > +/* Boot context support functions */ > +extern int _MIPS_HAL_NOMIPS16 > + __get_startup_BEV (void) __attribute__((weak)); > +extern int _MIPS_HAL_NOMIPS16 > + __chain_uhi_excpt (struct gpctx *) __attribute__((weak)); > + > +/* Emergency exit, use it when unrecoverable errors occur */ > +extern int _MIPS_HAL_NOMIPS16 > + __exit (int); > + > +/* UHI assert support. This function can return. */ > +extern void _MIPS_HAL_NOMIPS16 > + __uhi_assert (const char *, const char *, int32_t); > + > +#ifdef NDEBUG /* required by ANSI standard */ > +# define uhi_assert(__e) ((void)0) > +#else > +# define uhi_assert(__e) ((__e) ? (void)0 : \ > + __uhi_assert (#__e, __FILE__, __LINE__)) > +#endif > + > +#endif > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif // _HAL_H > diff --git a/libgloss/mips/include/mips/intctrl.h > b/libgloss/mips/include/mips/intctrl.h > new file mode 100644 > index 000000000..7e6c00097 > --- /dev/null > +++ b/libgloss/mips/include/mips/intctrl.h > @@ -0,0 +1,71 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <mips/hal.h> > +#include <stdint.h> > +#include <stdbool.h> > + > +/* > + * Use the macros themselves for idempotency to ease replacement at the OS > + * level. > + */ > +#ifndef _mips_intpatch > +/* > + * Install a handler into the template vector code by patching the address > + * calculation instructions. The INDEX is the interrupt number with SW0 > + * being index 0 and HW5 being index 7, this also applies to EIC vectors > + * where the INDEX represents the vector number. K1_TO_KSCRATCH1 should > be > + * set if an instruction should be injected to move K1 to KSCRATCH1 before > + * clobbering it. > + */ > +_MIPS_HAL_NOMIPS16 > +void _mips_intpatch (const reg_t index, const uintptr_t handler, > + bool k1_to_kscratch1); > +#endif /* _mips_intpatch */ > + > +#ifndef _mips_intmask > +/* > + * Enable or disable an interrupt at INDEX where INDEX has the same > meaning > + * as in _mips_intpatch. Returns nonzero if the interrupt was already > + * enabled. > + */ > +_MIPS_HAL_NOMIPS16 > +reg_t _mips_intmask (const reg_t index, const reg_t enable); > +#endif /* _mips_intmask */ > + > +#ifndef _mips_intack > +/* > + * Acknowledge (clear) an interrupt at INDEX where INDEX has the same > meaning > + * as in _mips_intpatch. Returns nonzero if the interrupt needed > + * acknowledging. > + */ > +_MIPS_HAL_NOMIPS16 > +reg_t _mips_intack (const reg_t index); > +#endif /* _mips_intack */ > diff --git a/libgloss/mips/include/mips/m32c0.h > b/libgloss/mips/include/mips/m32c0.h > new file mode 100644 > index 000000000..67c2c37bd > --- /dev/null > +++ b/libgloss/mips/include/mips/m32c0.h > @@ -0,0 +1,1607 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _M32C0_H_ > +#define _M32C0_H_ > + > +#ifndef _M64C0_H_ > +/* MIPS32-specific MMU interface */ > +#include <mips/m32tlb.h> > +#endif > +/* > + * MIPS32 Exception Codes > + */ > +#define EXC_INTR 0 /* interrupt */ > +#define EXC_MOD 1 /* tlb modification */ > +#define EXC_TLBL 2 /* tlb miss (load/i-fetch) */ > +#define EXC_TLBS 3 /* tlb miss (store) */ > +#define EXC_ADEL 4 /* address error (load/i-fetch) */ > +#define EXC_ADES 5 /* address error (store) */ > +#define EXC_IBE 6 /* bus error (i-fetch) */ > +#define EXC_DBE 7 /* data bus error (load/store) */ > +#define EXC_SYS 8 /* system call */ > +#define EXC_BP 9 /* breakpoint */ > +#define EXC_RI 10 /* reserved instruction */ > +#define EXC_CPU 11 /* coprocessor unusable */ > +#define EXC_OVF 12 /* integer overflow */ > +#define EXC_TRAP 13 /* trap exception */ > +#define EXC_MSAFPE 14 /* MSA floating point exception */ > +#define EXC_FPE 15 /* floating point exception */ > +#define EXC_IS1 16 /* implementation-specific 1 */ > +#define EXC_IS2 17 /* implementation-specific 2 */ > +#define EXC_C2E 18 /* coprocessor 2 exception */ > +#define EXC_TLBRI 19 /* TLB read inhibit */ > +#define EXC_TLBXI 20 /* TLB execute inhibit */ > +#define EXC_MSAU 21 /* MSA unusable exception */ > +#define EXC_MDMX 22 /* mdmx unusable */ > +#define EXC_WATCH 23 /* watchpoint */ > +#define EXC_MCHECK 24 /* machine check */ > +#define EXC_THREAD 25 /* thread */ > +#define EXC_DSPU 26 /* dsp unusable */ > +#define EXC_RES27 27 > +#define EXC_RES28 28 > +#define EXC_RES29 29 > +#define EXC_RES30 30 > +#define EXC_RES31 31 > + > + > +/* > + * MIPS32 Cause Register (CP0 Register 13, Select 0) > + */ > +#define CR_BD 0x80000000 /* branch delay */ > +#define CR_BD_SHIFT 31 > +#define CR_TI 0x40000000 /* timer interrupt (r2) */ > +#define CR_TI_SHIFT 30 > +#define CR_CEMASK 0x30000000 /* coprocessor used */ > +#define CR_CESHIFT 28 > +#define CR_CE_SHIFT 28 > +#define CR_CE_BITS 2 > +#define CR_DC 0x08000000 /* disable count (r2) */ > +#define CR_DC_SHIFT 27 > +#define CR_PCI 0x04000000 /* performance counter i/u (r2) */ > +#define CR_PCI_SHIFT 26 > +#define CR_IV 0x00800000 /* use special i/u vec */ > +#define CR_IV_SHIFT 23 > +#define CR_WP 0x00400000 /* deferred watchpoint */ > +#define CR_WP_SHIFT 22 > +#define CR_FDCI 0x00200000 /* fast debug channned i/u > (r2) */ > +#define CR_FDCI_SHIFT 21 > + > +#define CR_IMASK 0x0000ff00 /* interrupt pending mask */ > +#define CR_IP_MASK 0x0000ff00 > +#define CR_IP_SHIFT 8 > +#define CR_IP_BITS 8 > +#define CR_RIPL 0x0000fc00 > +#define CR_RIPL_SHIFT 10 > +#define CR_RIPL_BITS 6 > + > +/* interrupt pending bits */ > +#define CR_HINT5 0x00008000 /* h/w interrupt 5 */ > +#define CR_HINT4 0x00004000 /* h/w interrupt 4 */ > +#define CR_HINT3 0x00002000 /* h/w interrupt 3 */ > +#define CR_HINT2 0x00001000 /* h/w interrupt 2 */ > +#define CR_HINT1 0x00000800 /* h/w interrupt 1 */ > +#define CR_HINT0 0x00000400 /* h/w interrupt 0 */ > +#define CR_SINT1 0x00000200 /* s/w interrupt 1 */ > +#define CR_SINT0 0x00000100 /* s/w interrupt 0 */ > + > +/* alternative interrupt pending bit naming */ > +#define CR_IP7 0x00008000 > +#define CR_IP6 0x00004000 > +#define CR_IP5 0x00002000 > +#define CR_IP4 0x00001000 > +#define CR_IP3 0x00000800 > +#define CR_IP2 0x00000400 > +#define CR_IP1 0x00000200 > +#define CR_IP0 0x00000100 > + > +#define CR_XMASK 0x0000007c /* exception code mask */ > +#define CR_X_MASK 0x0000007c > +#define CR_X_SHIFT 2 > +#define CR_X_BITS 5 > +#define CR_XCPT(x) ((x)<<2) > + > +/* > + * MIPS32 Status Register (CP0 Register 12, Select 0) > + */ > +#define SR_CU3 0x80000000 /* coprocessor 3 enable */ > +#define SR_CU3_SHIFT 31 > +#define SR_CU2 0x40000000 /* coprocessor 2 enable */ > +#define SR_CU2_SHIFT 30 > +#define SR_CU1 0x20000000 /* coprocessor 1 enable */ > +#define SR_CU1_SHIFT 29 > +#define SR_CU0 0x10000000 /* coprocessor 0 enable */ > + > +#define SR_RP 0x08000000 /* reduce power */ > +#define SR_RP_SHIFT 27 > +#define SR_FR 0x04000000 /* 64-bit fpu registers */ > +#define SR_FR_SHIFT 26 > +#define SR_RE 0x02000000 /* reverse endian (user mode) */ > +#define SR_RE_SHIFT 25 > +#define SR_MX 0x01000000 /* enable MDMX/DSP ASE */ > +#define SR_MX_SHIFT 24 > +#define SR_PX 0x00800000 /* user 64-bit reg / 32-bit addr */ > +#define SR_PX_SHIFT 23 > +#define SR_BEV 0x00400000 /* boot exception vectors */ > +#define SR_BEV_SHIFT 22 > +#define SR_TS 0x00200000 /* TLB shutdown */ > +#define SR_TS_SHIFT 21 > +#define SR_SR 0x00100000 /* soft reset occurred */ > +#define SR_PE 0x00100000 /* soft reset (clear parity error) > */ > +#define SR_SR_SHIFT 20 > +#define SR_NMI 0x00080000 /* NMI occurred */ > +#define SR_NMI_SHIFT 19 > +#define SR_MCU 0x00040000 /* MCU ASE implemented */ > +#define SR_MCU_SHIFT 18 > + > +#define SR_IPL_MASK 0x0000fc00 > +#define SR_IPL_SHIFT 10 > +#define SR_IPL_BITS 6 > +#define SR_IMASK 0x0000ff00 > + > +/* interrupt mask bits */ > +#define SR_HINT5 0x00008000 /* enable h/w interrupt 6 */ > +#define SR_HINT4 0x00004000 /* enable h/w interrupt 5 */ > +#define SR_HINT3 0x00002000 /* enable h/w interrupt 4 */ > +#define SR_HINT2 0x00001000 /* enable h/w interrupt 3 */ > +#define SR_HINT1 0x00000800 /* enable h/w interrupt 2 */ > +#define SR_HINT0 0x00000400 /* enable h/w interrupt 1 */ > +#define SR_SINT1 0x00000200 /* enable s/w interrupt 1 */ > +#define SR_SINT0 0x00000100 /* enable s/w interrupt 0 */ > + > +/* alternative interrupt mask naming */ > +#define SR_IM9 0x00040000 /* 1st MUCON ASE interrupt */ > +#define SR_IM8 0x00010000 /* 2nd MUCON ASE interrupt */ > +#define SR_IM7 0x00008000 > +#define SR_IM6 0x00004000 > +#define SR_IM5 0x00002000 > +#define SR_IM4 0x00001000 > +#define SR_IM3 0x00000800 > +#define SR_IM2 0x00000400 > +#define SR_IM1 0x00000200 > +#define SR_IM0 0x00000100 > + > +#define SR_KX 0x00000080 /* 64-bit kernel mode */ > +#define SR_KX_SHIFT 7 > +#define SR_SX 0x00000040 /* 64-bit supervisor mode */ > +#define SR_SX_SHIFT 6 > +#define SR_UX 0x00000020 /* 64-bit user mode */ > +#define SR_UX_SHIFT 5 > + > +#define SR_UM 0x00000010 /* user mode */ > +#define SR_KSU_MASK 0x00000018 /* ksu mode mask */ > +#define SR_KSU_SHIFT 3 > +#define SR_KSU_BITS 2 > +#define SR_KSU_USER 0x00000010 /* user mode */ > +#define SR_KSU_SPVS 0x00000008 /* supervisor mode */ > +#define SR_KSU_KERN 0x00000000 /* kernel mode */ > + > +#define SR_ERL 0x00000004 /* error level */ > +#define SR_ERL_SHIFT 2 > +#define SR_EXL 0x00000002 /* exception level */ > +#define SR_EXL_SHIFT 1 > +#define SR_IE 0x00000001 /* interrupt enable */ > +#define SR_IE_SHIFT 0 > + > +/* > + * MIPS32r6 VPControl (CP0 Register 0, Select 4) > + */ > +#define VPCONTROL_DIS 0x00000001 > +#define VPCONTROL_SHIFT 0 > + > +/* > + * MIPS32r2 HWREna Register (CP0 Register 7, Select 0) > + */ > +#define HWRENA_ULR 0x20000000 > +#define HWRENA_XNP 0x00000020 > +#define HWRENA_PERFCNT 0x00000010 > +#define HWRENA_CCRES 0x00000008 > +#define HWRENA_CC 0x00000004 > +#define HWRENA_SYNCSTEP 0x00000002 > +#define HWRENA_CPUNUM 0x00000001 > + > +/* > + * MIPS32r2 IntCtl Register (CP0 Register 12, Select 1) > + */ > +#define INTCTL_IPTI 0xe0000000 /* timer i/u pending bit */ > +#define INTCTL_IPTI_SHIFT 29 > +#define INTCTL_IPTI_BITS 3 > +#define INTCTL_IPPCI 0x1c000000 /* perfctr i/u pending bit */ > +#define INTCTL_IPPCI_SHIFT 26 > +#define INTCTL_IPPCI_BITS 3 > +#define INTCTL_IPFDC 0x03800000 /* fast debug chan i/u pending bit > */ > +#define INTCTL_IPFDC_SHIFT 23 > +#define INTCTL_IPFDC_BITS 3 > +#define INTCTL_VS 0x000003e0 /* vector spacing */ > +#define INTCTL_VS_SHIFT 5 > +#define INTCTL_VS_BITS 5 > +#define INTCTL_VS_0 (0x00 << INTCTL_VS_SHIFT) > +#define INTCTL_VS_32 (0x01 << INTCTL_VS_SHIFT) > +#define INTCTL_VS_64 (0x02 << INTCTL_VS_SHIFT) > +#define INTCTL_VS_128 (0x04 << INTCTL_VS_SHIFT) > +#define INTCTL_VS_256 (0x08 << INTCTL_VS_SHIFT) > +#define INTCTL_VS_512 (0x10 << INTCTL_VS_SHIFT) > + > +/* > + * MIPS32r2 SRSCtl Register (CP0 Register 12, Select 2) > + */ > +#define SRSCTL_HSS 0x3c000000 /* highest shadow set */ > +#define SRSCTL_HSS_SHIFT 26 > +#define SRSCTL_EICSS 0x003c0000 /* EIC shadow set */ > +#define SRSCTL_EICSS_SHIFT 18 > +#define SRSCTL_ESS 0x0000f000 /* exception shadow set */ > +#define SRSCTL_ESS_SHIFT 12 > +#define SRSCTL_PSS 0x000003c0 /* previous shadow set */ > +#define SRSCTL_PSS_SHIFT 6 > +#define SRSCTL_CSS 0x0000000f /* current shadow set */ > +#define SRSCTL_CSS_SHIFT 0 > + > +/* > + * MIPS32 BEVVA Register (CP0 Register 15, Select 4) > + */ > +#define BEVVA_BASE_MASK 0xfffff000 > +#define BEVVA_BASE_SHIFT 12 > +#define BEVVA_MASK_MASK 0x00000fff > +#define BEVVA_MASK_SHIFT 0 > + > +/* > + * MIPS32 Config0 Register (CP0 Register 16, Select 0) > + */ > +#define CFG0_M 0x80000000 /* Config1 implemented */ > +#define CFG0_M_SHIFT 31 > +#define CFG0_K23_MASK 0x70000000 /* Fixed MMU kseg2/3 CCA */ > +#define CFG0_K23_SHIFT 28 > +#define CFG0_KU_MASK 0x0e000000 /* Fixed MMU kuseg CCA */ > +#define CFG0_KU_SHIFT 25 > +#define CFG0_BE 0x00008000 /* Big Endian */ > +#define CFG0_BE_SHIFT 15 > +#define CFG0_AT_MASK 0x00006000 /* Architecture type: */ > +#define CFG0_ATMASK 0x00006000 > +#define CFG0_AT_SHIFT 13 > +#define CFG0_AT_BITS 2 > +#define CFG0_AT_M32 (0 << CFG0_AT_SHIFT) /* MIPS32 */ > +#define CFG0_AT_M64_A32 (1 << CFG0_AT_SHIFT) /* MIPS64, 32-bit addresses > */ > +#define CFG0_AT_M64_A64 (2 << CFG0_AT_SHIFT) /* MIPS64, 64-bit addresses > */ > +#define CFG0_AT_RES (3 << CFG0_AT_SHIFT) > +#define CFG0_AR_MASK 0x00001c00 > +#define CFG0_ARMASK 0x00001c00 > +#define CFG0_AR_SHIFT 10 > +#define CFG0_ARSHIFT 10 > +#define CFG0_AR_BITS 3 > +#define CFG0_AR_R1 (0 << CFG0_AR_SHIFT) /* Release 1 */ > +#define CFG0_AR_R2 (1 << CFG0_AR_SHIFT) /* Release 2,3,5 */ > +#define CFG0_AR_R6 (2 << CFG0_AR_SHIFT) /* Release 6 */ > +#define CFG0_MT_MASK 0x00000380 /* MMU Type: */ > +#define CFG0_MTMASK 0x00000380 > +#define CFG0_MT_SHIFT 7 > +#define CFG0_MT_BITS 3 > +#define CFG0_MT_NONE (0 << CFG0_MT_SHIFT) /* No MMU */ > +#define CFG0_MT_TLB (1 << CFG0_MT_SHIFT) /* Standard TLB */ > +#define CFG0_MT_BAT (2 << CFG0_MT_SHIFT) /* BAT */ > +#define CFG0_MT_FIXED (3 << CFG0_MT_SHIFT) /* Fixed mapping */ > +#define CFG0_MT_NONSTD (3 << CFG0_MT_SHIFT) /* Legacy */ > +#define CFG0_MT_DUAL (4 << CFG0_MT_SHIFT) /* Dual VTLB and FTLB */ > +#define CFG0_VI 0x00000008 /* Icache is virtual */ > +#define CFG0_VI_SHIFT 3 > +#define CFG0_K0_MASK 0x00000007 /* KSEG0 coherency algorithm */ > +#define CFG0_K0MASK 0x00000007 > +#define CFG0_K0_SHIFT 0 > +#define CFG0_K0_BITS 3 > + > +/* > + * MIPS32 Config1 Register (CP0 Register 16, Select 1) > + */ > +#define CFG1_M 0x80000000 /* Config2 implemented */ > +#define CFG1_M_SHIFT 31 > +#define CFG1_MMUS_MASK 0x7e000000 /* mmu size - 1 */ > +#define CFG1_MMUSMASK 0x7e000000 > +#define CFG1_MMUS_SHIFT 25 > +#define CFG1_MMUSSHIFT 25 > +#define CFG1_MMUS_BITS 6 > +#define CFG1_IS_MASK 0x01c00000 /* icache lines 64<<n */ > +#define CFG1_ISMASK 0x01c00000 > +#define CFG1_IS_SHIFT 22 /* Unless n==7, then 32 */ > +#define CFG1_ISSHIFT 22 > +#define CFG1_IS_BITS 3 > +#define CFG1_IL_MASK 0x00380000 /* icache line size 2<<n */ > +#define CFG1_ILMASK 0x00380000 > +#define CFG1_IL_SHIFT 19 > +#define CFG1_ILSHIFT 19 > +#define CFG1_IL_BITS 3 > +#define CFG1_IA_MASK 0x00070000 /* icache ways - 1 */ > +#define CFG1_IAMASK 0x00070000 > +#define CFG1_IA_SHIFT 16 > +#define CFG1_IASHIFT 16 > +#define CFG1_IA_BITS 3 > +#define CFG1_DS_MASK 0x0000e000 /* dcache lines 64<<n */ > +#define CFG1_DSMASK 0x0000e000 > +#define CFG1_DS_SHIFT 13 > +#define CFG1_DSSHIFT 13 > +#define CFG1_DS_BITS 3 > +#define CFG1_DL_MASK 0x00001c00 /* dcache line size 2<<n */ > +#define CFG1_DLMASK 0x00001c00 > +#define CFG1_DL_SHIFT 10 > +#define CFG1_DLSHIFT 10 > +#define CFG1_DL_BITS 3 > +#define CFG1_DA_MASK 0x00000380 /* dcache ways - 1 */ > +#define CFG1_DAMASK 0x00000380 > +#define CFG1_DA_SHIFT 7 > +#define CFG1_DASHIFT 7 > +#define CFG1_DA_BITS 3 > +#define CFG1_C2 0x00000040 /* Coprocessor 2 present */ > +#define CFG1_C2_SHIFT 6 > +#define CFG1_MD 0x00000020 /* MDMX implemented */ > +#define CFG1_MD_SHIFT 5 > +#define CFG1_PC 0x00000010 /* performance counters > implemented */ > +#define CFG1_PC_SHIFT 4 > +#define CFG1_WR 0x00000008 /* watch registers > implemented */ > +#define CFG1_WR_SHIFT 3 > +#define CFG1_CA 0x00000004 /* compression (mips16) > implemented */ > +#define CFG1_CA_SHIFT 2 > +#define CFG1_EP 0x00000002 /* ejtag implemented */ > +#define CFG1_EP_SHIFT 1 > +#define CFG1_FP 0x00000001 /* fpu implemented */ > +#define CFG1_FP_SHIFT 0 > + > + > +/* > + * MIPS32r2 Config2 Register (CP0 Register 16, Select 2) > + */ > +#define CFG2_M 0x80000000 /* Config3 implemented */ > +#define CFG1_M_SHIFT 31 > +#define CFG2_TU_MASK 0x70000000 /* tertiary cache control */ > +#define CFG2_TUMASK 0x70000000 > +#define CFG2_TU_SHIFT 28 > +#define CFG2_TUSHIFT 28 > +#define CFG2_TU_BITS 3 > +#define CFG2_TS_MASK 0x0f000000 /* tcache sets per wway 64<<n */ > +#define CFG2_TSMASK 0x0f000000 > +#define CFG2_TS_SHIFT 24 > +#define CFG2_TSSHIFT 24 > +#define CFG2_TS_BITS 4 > +#define CFG2_TL_MASK 0x00f00000 /* tcache line size 2<<n */ > +#define CFG2_TLMASK 0x00f00000 > +#define CFG2_TL_SHIFT 20 > +#define CFG2_TLSHIFT 20 > +#define CFG2_TL_BITS 4 > +#define CFG2_TA_MASK 0x000f0000 /* tcache ways - 1 */ > +#define CFG2_TAMASK 0x000f0000 > +#define CFG2_TA_SHIFT 16 > +#define CFG2_TASHIFT 16 > +#define CFG2_TA_BITS 4 > +#define CFG2_SU_MASK 0x0000f000 /* secondary cache control */ > +#define CFG2_SUMASK 0x0000f000 > +#define CFG2_SU_SHIFT 12 > +#define CFG2_SUSHIFT 12 > +#define CFG2_SU_BITS 4 > +#define CFG2_SS_MASK 0x00000f00 /* scache sets per wway 64<<n */ > +#define CFG2_SSMASK 0x00000f00 > +#define CFG2_SS_SHIFT 8 > +#define CFG2_SSSHIFT 8 > +#define CFG2_SS_BITS 4 > +#define CFG2_SL_MASK 0x000000f0 /* scache line size 2<<n */ > +#define CFG2_SLMASK 0x000000f0 > +#define CFG2_SL_SHIFT 4 > +#define CFG2_SLSHIFT 4 > +#define CFG2_SL_BITS 4 > +#define CFG2_SA_MASK 0x0000000f /* scache ways - 1 */ > +#define CFG2_SAMASK 0x0000000f > +#define CFG2_SA_SHIFT 0 > +#define CFG2_SASHIFT 0 > +#define CFG2_SA_BITS 4 > + > +/* > + * MIPS32r2 Config3 Register (CP0 Register 16, Select 3) > + */ > +#define CFG3_M 0x80000000 /* Config4 implemented */ > +#define CFG3_M_SHIFT 31 > +#define CFG3_BPG 0x40000000 /* Big pages implemented */ > +#define CFG3_BPG_SHIFT 30 > +#define CFG3_CMGCR 0x20000000 /* Coherency manager implemented */ > +#define CFG3_CMGCR_SHIFT 29 > +#define CFG3_MSAP 0x10000000 /* MSA implemented */ > +#define CFG3_MSAP_SHIFT 28 > +#define CFG3_BP 0x08000000 /* BadInstrP implemented */ > +#define CFG3_BP_SHIFT 27 > +#define CFG3_BI 0x04000000 /* BadInstr implemented */ > +#define CFG3_BI_SHIFT 26 > +#define CFG3_SC 0x02000000 /* Segment control > implemented */ > +#define CFG3_SC_SHIFT 25 > +#define CFG3_PW 0x01000000 /* HW page table walk > implemented */ > +#define CFG3_PW_SHIFT 24 > +#define CFG3_VZ 0x00800000 /* Virtualization module > implemented */ > +#define CFG3_VZ_SHIFT 23 > +#define CFG3_IPLW_MASK 0x00600000 /* IPL field width */ > +#define CFG3_IPLW_SHIFT 21 > +#define CFG3_IPLW_BITS 2 > +#define CFG3_IPLW_6BIT (0 << CFG3_IPLW_SHIFT) /* IPL/RIPL are > 6-bits wide */ > +#define CFG3_IPLW_8BIT (1 << CFG3_IPLW_SHIFT) /* IPL/RIPL are > 8-bits wide */ > +#define CFG3_MMAR_MASK 0x001c0000 /* MicroMIPS64 architecture > revision */ > +#define CFG3_MMAR_SHIFT 18 > +#define CFG3_MMAR_BITS 3 > +#define CFG3_MMAR_R3 (0 << CFG3_MMAR_SHIFT) /* MicroMIPS64 Release 3 */ > +#define CFG3_MCU 0x00020000 /* MCU ASE is implemented */ > +#define CFG3_MCU_SHIFT 17 > +#define CFG3_IOE 0x00010000 /* MicroMIPS exception entry > points */ > +#define CFG3_IOE_SHIFT 16 > +#define CFG3_ISA_MASK 0x0000c000 /* ISA availability */ > +#define CFG3_ISA_SHIFT 14 > +#define CFG3_ISA_BITS 2 > +#define CFG3_ISA_MIPS (0 << CFG3_ISA_SHIFT) /* MIPS only */ > +#define CFG3_ISA_UMIPS (1 << CFG3_ISA_SHIFT) /* MicroMIPS only */ > +#define CFG3_ISA_BOTH (2 << CFG3_ISA_SHIFT) /* MIPS (boot) and > MicroMIPS */ > +#define CFG3_ISA_UBOTH (3 << CFG3_ISA_SHIFT) /* MIPS and > MicroMIPS (boot) */ > +#define CFG3_ULRI 0x00002000 /* UserLocal register is available > */ > +#define CFG3_ULRI_SHIFT 13 > +#define CFG3_RXI 0x00001000 /* RIE and XIE exist in pagegrain > */ > +#define CFG3_RXI_SHIFT 12 > +#define CFG3_DSP2P 0x00000800 /* DSPR2 ASE present */ > +#define CFG3_DSP2P_SHIFT 11 > +#define CFG3_DSPP 0x00000400 /* DSP ASE present */ > +#define CFG3_DSPP_SHIFT 10 > +#define CFG3_CTXTC 0x00000200 /* Context Config regs are present > */ > +#define CFG3_CTXTC_SHIFT 9 > +#define CFG3_ITL 0x00000100 /* IFlowtrace mechanism > implemented */ > +#define CFG3_ITL_SHIFT 8 > +#define CFG3_LPA 0x00000080 /* Large physical addresses */ > +#define CFG3_LPA_SHIFT 7 > +#define CFG3_VEIC 0x00000040 /* Vectored external i/u > controller */ > +#define CFG3_VEIC_SHIFT 6 > +#define CFG3_VI 0x00000020 /* Vectored i/us */ > +#define CFG3_VI_SHIFT 5 > +#define CFG3_SP 0x00000010 /* Small page support */ > +#define CFG3_SP_SHIFT 4 > +#define CFG3_CDMM 0x00000008 /* Common Device Memory Map > support */ > +#define CFG3_CDMM_SHIFT 3 > +#define CFG3_MT 0x00000004 /* MT ASE present */ > +#define CFG3_MT_SHIFT 2 > +#define CFG3_SM 0x00000002 /* SmartMIPS ASE */ > +#define CFG3_SM_SHIFT 1 > +#define CFG3_TL 0x00000001 /* Trace Logic */ > +#define CFG3_TL_SHIFT 0 > + > +/* > + * MIPS32r2 Config4 Register (CP0 Register 16, Select 4) > + */ > +#define CFG4_M 0x80000000 /* Config5 implemented */ > +#define CFG4_M_SHIFT 31 > +#define CFG4_IE_MASK 0x60000000 /* TLB invalidate insn support */ > +#define CFG4_IE_SHIFT 29 > +#define CFG4_IE_BITS 2 > +#define CFG4_IE_NONE (0 << CFG4_IE_SHIFT) /* TLB invalidate not > available */ > +#define CFG4_IE_EHINV (1 << CFG4_IE_SHIFT) /* TLB invalidate with EHINV > */ > +#define CFG4_IE_INV (2 << CFG4_IE_SHIFT) /* TLB invalidate per entry */ > +#define CFG4_IE_INVALL (3 << CFG4_IE_SHIFT) /* TLB invalidate > entire MMU */ > +#define CFG4_AE 0x10000000 /* EntryHI.ASID is 10-bits > */ > +#define CFG4_AE_SHIFT 28 > +#define CFG4_VTLBSEXT_MASK 0x0f000000 /* VTLB size extension > field */ > +#define CFG4_VTLBSEXT_SHIFT 24 > +#define CFG4_VTLBSEXT_BITS 4 > +#define CFG4_KSCREXIST_MASK 0x00ff0000 /* Indicates presence of > KScratch */ > +#define CFG4_KSCREXIST_SHIFT 16 > +#define CFG4_KSCREXIST_BITS 8 > +#define CFG4_MMUED 0x0000c000 /* MMU Extension definition */ > +#define CFG4_MMUED_SHIFT 14 > +#define CFG4_MMUED_BITS 2 > +#define CFG4_MMUED_SIZEEXT (1 << CFG4_MMUED_SHIFT) /* MMUSizeExt */ > +#define CFG4_MMUED_FTLB (2 << CFG4_MMUED_SHIFT) /* FTLB fields */ > +#define CFG4_MMUED_FTLBVEXT (3 << CFG4_MMUED_SHIFT) /* FTLB and Vext */ > +#define CFG4_FTLBPS_MASK 0x00001f00 /* FTLB Page Size */ > +#define CFG4_FTLBPS_SHIFT 8 > +#define CFG4_FTLBPS_BITS 5 > +#define CFG4_FTLBW_MASK 0x000000f0 /* FTLB Ways mask */ > +#define CFG4_FTLBW_SHIFT 4 > +#define CFG4_FTLBW_BITS 4 > +#define CFG4_FTLBS_MASK 0x0000000f /* FTLB Sets mask */ > +#define CFG4_FTLBS_SHIFT 0 > +#define CFG4_FTLBS_BITS 4 > +#define CFG4_MMUSE_MASK 0x000000ff /* MMU size extension */ > +#define CFG4_MMUSE_SHIFT 0 > +#define CFG4_MMUSE_BITS 8 > + > +/* > + * MIPS32r2 Config5 Register (CP0 Register 16, Select 5) > + */ > +#define CFG5_M 0x80000000 /* Undefined extension */ > +#define CFG5_M_SHIFT 31 > +#define CFG5_K 0x40000000 /* Disable CCA control */ > +#define CFG5_K_SHIFT 30 > +#define CFG5_CV 0x20000000 /* Disable CacheException > in KSEG1 */ > +#define CFG5_CV_SHIFT 29 > +#define CFG5_EVA 0x10000000 /* EVA is implemented */ > +#define CFG5_EVA_SHIFT 28 > +#define CFG5_MSAEN 0x08000000 /* Enable MSA ASE */ > +#define CFG5_MSAEN_SHIFT 27 > +#define CFG_XNP 0x00002000 > +#define CFG_XNP_SHIFT 13 > +#define CFG5_CES 0x00001000 /* Current endian state */ > +#define CFG5_CES_SHIFT 12 > +#define CFG5_DEC 0x00000800 /* Dual endian control */ > +#define CFG5_DEC_SHIFT 11 > +#define CFG5_L2C 0x00000400 /* Config 2 is memory mapped */ > +#define CFG5_L2C_SHIFT 10 > +#define CFG5_UFE 0x00000200 /* Usermode FRE control */ > +#define CFG5_LUFE_SHIFT 9 > +#define CFG5_FRE 0x00000100 /* Emulation support for FR=0 */ > +#define CFG5_FRE_SHIFT 8 > +#define CFG5_VP 0x00000080 /* Multiple virtual > processors */ > +#define CFG5_VP_SHIFT 7 > +#define CFG5_SBRI 0x00000040 /* Force RI on SDBBP */ > +#define CFG5_SBRI_SHIFT 6 > +#define CFG5_MVH 0x00000020 /* XPA instruction support */ > +#define CFG5_MVH_SHIFT 5 > +#define CFG5_LLB 0x00000010 /* Load-Linked Bit present */ > +#define CFG5_LLB_SHIFT 4 > +#define CFG5_MRP 0x00000008 /* MAAR and MAARI are present */ > +#define CFG5_MRP_SHIFT 3 > +#define CFG5_UFR 0x00000004 /* Usermode FR control */ > +#define CFG5_UFR_SHIFT 2 > +#define CFG5_NF 0x00000001 /* Nested fault support */ > +#define CFG5_NF_SHIFT 0 > + > +/* > + * Primary cache mode > + */ > +#define CFG_CBITS 3 > +#define CFG_C_UNCACHED 2 > +#define CFG_C_WBACK 3 > +#define CFG_C_NONCOHERENT 3 > + > +#if 0 > +/* These cache modes are CPU specific */ > +#define CFG_C_WTHRU_NOALLOC 0 > +#define CFG_C_WTHRU_ALLOC 1 > +#define CFG_C_COHERENTXCL 4 > +#define CFG_C_COHERENTXCLW 5 > +#define CFG_C_COHERENTUPD 6 > +#define CFG_C_UNCACHED_ACCEL 7 > +#endif > + > + > +/* > + * Primary Cache TagLo (CP0 Register 28, Select 0/2) > + */ > +#define TAG_PTAG_MASK 0xffffff00 /* Primary Tag */ > +#define TAG_PTAG_SHIFT 8 > +#define TAG_PSTATE_MASK 0x000000c0 /* Primary Cache State */ > +#define TAG_PSTATE_SHIFT 6 > +#define TAG_PSTATE_LOCK 0x00000020 > +#define TAG_PARITY_MASK 0x00000001 /* Primary Tag Parity */ > +#define TAG_PARITY_SHIFT 0 > + > +/* primary cache state (XXX actually implementation specific) */ > +#define PSTATE_INVAL 0 > +#define PSTATE_SHARED 1 > +#define PSTATE_CLEAN_EXCL 2 > +#define PSTATE_DIRTY_EXCL 3 > + > + > +/* > + * Cache operations > + */ > +#define Index_Invalidate_I 0x00 /* 0 0 */ > +#define Index_Writeback_Inv_D 0x01 /* 0 1 */ > +#define Index_Writeback_Inv_T 0x02 /* 0 2 */ > +#define Index_Writeback_Inv_S 0x03 /* 0 3 */ > +#define Index_Load_Tag_I 0x04 /* 1 0 */ > +#define Index_Load_Tag_D 0x05 /* 1 1 */ > +#define Index_Load_Tag_T 0x06 /* 1 2 */ > +#define Index_Load_Tag_S 0x07 /* 1 3 */ > +#define Index_Store_Tag_I 0x08 /* 2 0 */ > +#define Index_Store_Tag_D 0x09 /* 2 1 */ > +#define Index_Store_Tag_T 0x0A /* 2 2 */ > +#define Index_Store_Tag_S 0x0B /* 2 3 */ > +#define Hit_Invalidate_I 0x10 /* 4 0 */ > +#define Hit_Invalidate_D 0x11 /* 4 1 */ > +#define Hit_Invalidate_T 0x12 /* 4 2 */ > +#define Hit_Invalidate_S 0x13 /* 4 3 */ > +#define Fill_I 0x14 /* 5 0 */ > +#define Hit_Writeback_Inv_D 0x15 /* 5 1 */ > +#define Hit_Writeback_Inv_T 0x16 /* 5 2 */ > +#define Hit_Writeback_Inv_S 0x17 /* 5 3 */ > +#define Hit_Writeback_D 0x19 /* 6 1 */ > +#define Hit_Writeback_T 0x1A /* 6 2 */ > +#define Hit_Writeback_S 0x1B /* 6 3 */ > +#define Fetch_Lock_I 0x1C /* 7 0 */ > +#define Fetch_Lock_D 0x1D /* 7 1 */ > +#define Fetch_Lock_S 0x1F /* 7 3 */ > + > +/* MIPS32 WatchLo Register (CP0 Register 18) */ > +#define WATCHLO_VA 0xfffffff8 > +#define WATCHLO_I 0x00000004 > +#define WATCHLO_R 0x00000002 > +#define WATCHLO_W 0x00000001 > + > +/* MIPS32 WatchHi Register (CP0 Register 19) */ > +#define WATCHHI_M 0x80000000 > +#define WATCHHI_M_SHIFT 31 > +#define WATCHHI_G 0x40000000 > +#define WATCHHI_G_SHIFT 30 > +#define WATCHHI_ASID_MASK 0x00ff0000 > +#define WATCHHI_ASIDMASK 0x00ff0000 > +#define WATCHHI_ASID_SHIFT 16 > +#define WATCHHI_ASIDSHIFT 16 > +#define WATCHHI_ASID_BITS 8 > +#define WATCHHI_MASK 0x00000ffc > +#define WATCHHI_I 0x00000004 > +#define WATCHHI_R 0x00000002 > +#define WATCHHI_W 0x00000001 > + > +/* MIPS32 PerfCnt Register (CP0 Register 25) */ > +#define PERFCNT_M 0x80000000 > +#define PERFCNT_EVENT_MASK 0x000007e0 > +#define PERFCNT_EVENTMASK 0x000007e0 > +#define PERFCNT_EVENT_SHIFT 5 > +#define PERFCNT_EVENTSHIFT 5 > +#define PERFCNT_EVENT_BITS 6 > +#define PERFCNT_IE 0x00000010 > +#define PERFCNT_U 0x00000008 > +#define PERFCNT_S 0x00000004 > +#define PERFCNT_K 0x00000002 > +#define PERFCNT_EXL 0x00000001 > + > +/* MIPS32r2 PageGrain Register (CP0 Register 5, Select 1) */ > +#define PAGEGRAIN_ELPA 0x20000000 /* Enable large physical addresses > */ > +#define PAGEGRAIN_ELPA_SHIFT 29 > +#define PAGEGRAIN_ELPA_BITS 1 > + > +#define PAGEGRAIN_ESP 0x10000000 /* Enable small (1KB) page support > */ > + > +/* MIPS32r2 EBase Register (CP0 Register 15, Select 1) */ > +#define EBASE_BASE 0xfffff000 /* Exception base */ > +#define EBASE_WG 0x00000800 /* Write Gate */ > +#define EBASE_WG_SHIFT 11 > +#define EBASE_CPU 0x000003ff /* CPU number */ > +#define EBASE_CPU_SHIFT 0 > +#define EBASE_CPU_BITS 10 > + > +/* MIPS32r2 EntryHi register (CP0 Register 10, Select 0) */ > +#define C0_ENTRYHI64_R_MASK 0xC000000000000000 > +#define C0_ENTRYHI64_R_BITS 2 > +#define C0_ENTRYHI64_R_SHIFT 61 > +#define C0_ENTRYHI64_VPN2_MASK 0xFFFFFFE000 > +#define C0_ENTRYHI64_VPN2_BITS 27 > +#define C0_ENTRYHI64_VPN2_SHIFT 13 > +#define C0_ENTRYHI_VPN2_MASK 0xFFFFE000 > +#define C0_ENTRYHI_VPN2_BITS 19 > +#define C0_ENTRYHI_VPN2_SHIFT 13 > +#define C0_ENTRYHI_VPN2X_MASK 0x3 > +#define C0_ENTRYHI_VPN2X_BITS 2 > +#define C0_ENTRYHI_VPN2X_SHIFT 11 > +#define C0_ENTRYHI_EHINV_MASK 0x400 > +#define C0_ENTRYHI_EHINV_BITS 1 > +#define C0_ENTRYHI_EHINV_SHIFT 10 > +#define C0_ENTRYHI_ASIDX_MASK 0x300 > +#define C0_ENTRYHI_ASIDX_BITS 2 > +#define C0_ENTRYHI_ASIDX_SHIFT 8 > +#define C0_ENTRYHI_ASID_MASK 0xFF > +#define C0_ENTRYHI_ASID_BITS 8 > +#define C0_ENTRYHI_ASID_SHIFT 0 > + > +/* MIPS32 EntryLo0 register (CP0 Register 2, select 0) */ > +#define ENTRYLO064_RI_MASK 0x8000000000000000 > +#define ENTRYLO064_RI_BITS 1 > +#define ENTRYLO064_RI_SHIFT 63 > +#define ENTRYLO064_XI_MASK 0x4000000000000000 > +#define ENTRYLO064_XI_BITS 1 > +#define ENTRYLO064_XI_SHIFT 62 > +#define ENTRYLO064_PFN_MASK 0x3FFFFFFFFFFFFFE0 > +#define ENTRYLO064_PFN_BITS 56 > +#define ENTRYLO064_PFN_SHIFT 6 > +#define ENTRYLO064_RI_SHIFT 63 > +#define ENTRYLO064_RI_BITS 1 > +#define ENTRYLO064_RI_SHIFT 63 > +#define ENTRYLO0_PFNX_MASK 0x7FFFFF > +#define ENTRYLO0_PFNX_BITS 23 > +#define ENTRYLO0_PFNX_SHIFT 0 > +#define ENTRYLO0_RI_MASK 0x80000000 > +#define ENTRYLO0_RI_BITS 1 > +#define ENTRYLO0_RI_SHIFT 31 > +#define ENTRYLO0_XI_MASK 0x40000000 > +#define ENTRYLO0_XI_BITS 1 > +#define ENTRYLO0_XI_SHIFT 30 > +#define ENTRYLO0_PFN_MASK 0x3FFFFFE0 > +#define ENTRYLO0_PFN_BITS 23 > +#define ENTRYLO0_PFN_SHIFT 6 > +#define ENTRYLO0_C_MASK 0x38 > +#define ENTRYLO0_C_BITS 3 > +#define ENTRYLO0_C_SHIFT 3 > +#define ENTRYLO0_D_MASK 0x4 > +#define ENTRYLO0_D_BITS 1 > +#define ENTRYLO0_D_SHIFT 2 > +#define ENTRYLO0_V_MASK 0x2 > +#define ENTRYLO0_V_BITS 1 > +#define ENTRYLO0_V_SHIFT 1 > +#define ENTRYLO0_G_MASK 0x1 > +#define ENTRYLO0_G_BITS 1 > +#define ENTRYLO0_G_SHIFT 0 > + > +/* MIPS32 EntryLo1 register (CP0 Register 3, select 0) */ > +#define ENTRYLO164_RI_MASK ENTRYLO064_RI_MASK > +#define ENTRYLO164_RI_BITS ENTRYLO064_RI_BITS > +#define ENTRYLO164_RI_SHIFT ENTRYLO064_RI_SHIFT > +#define ENTRYLO164_XI_MASK ENTRYLO064_XI_MASK > +#define ENTRYLO164_XI_BITS ENTRYLO064_XI_BITS > +#define ENTRYLO164_XI_SHIFT ENTRYLO064_XI_SHIFT > +#define ENTRYLO164_PFN_MASK ENTRYLO064_PFN_MASK > +#define ENTRYLO164_PFN_BITS ENTRYLO064_PFN_BITS > +#define ENTRYLO164_PFN_SHIFT ENTRYLO064_PFN_SHIFT > +#define ENTRYLO164_RI_SHIFT ENTRYLO064_RI_SHIFT > +#define ENTRYLO164_RI_BITS ENTRYLO064_RI_BITS > +#define ENTRYLO164_RI_SHIFT ENTRYLO064_RI_SHIFT > +#define ENTRYLO1_PFNX_MASK ENTRYLO0_PFNX_MASK > +#define ENTRYLO1_PFNX_BITS ENTRYLO0_PFNX_BITS > +#define ENTRYLO1_PFNX_SHIFT ENTRYLO0_PFNX_SHIFT > +#define ENTRYLO1_RI_MASK ENTRYLO0_RI_MASK > +#define ENTRYLO1_RI_BITS ENTRYLO0_RI_BITS > +#define ENTRYLO1_RI_SHIFT ENTRYLO0_RI_SHIFT > +#define ENTRYLO1_XI_MASK ENTRYLO0_XI_MASK > +#define ENTRYLO1_XI_BITS ENTRYLO0_XI_BITS > +#define ENTRYLO1_XI_SHIFT ENTRYLO0_XI_SHIFT > +#define ENTRYLO1_PFN_MASK ENTRYLO0_PFN_MASK > +#define ENTRYLO1_PFN_BITS ENTRYLO0_PFN_BITS > +#define ENTRYLO1_PFN_SHIFT ENTRYLO0_PFN_SHIFT > +#define ENTRYLO1_C_MASK ENTRYLO0_C_MASK > +#define ENTRYLO1_C_BITS ENTRYLO0_C_BITS > +#define ENTRYLO1_C_SHIFT ENTRYLO0_C_SHIFT > +#define ENTRYLO1_D_MASK ENTRYLO0_D_MASK > +#define ENTRYLO1_D_BITS ENTRYLO0_D_BITS > +#define ENTRYLO1_D_SHIFT ENTRYLO0_D_SHIFT > +#define ENTRYLO1_V_MASK ENTRYLO0_V_MASK > +#define ENTRYLO1_V_BITS ENTRYLO0_V_BITS > +#define ENTRYLO1_V_SHIFT ENTRYLO0_V_SHIFT > +#define ENTRYLO1_G_MASK ENTRYLO0_G_MASK > +#define ENTRYLO1_G_BITS ENTRYLO0_G_BITS > +#define ENTRYLO1_G_SHIFT ENTRYLO0_G_SHIFT > + > +/* MIPS32 TraceControl register (CP0 Register 23, select 1) */ > +#define TRACECONTROL_TS_MASK 0x80000000 > +#define TRACECONTROL_TS_SHIFT 31 > +#define TRACECONTROL_TB_MASK 0x08000000 > +#define TRACECONTROL_TB_SHIFT 27 > +#define TRACECONTROL_IO_MASK 0x04000000 > +#define TRACECONTROL_IO_SHIFT 26 > +#define TRACECONTROL_D_MASK 0x02000000 > +#define TRACECONTROL_D_SHIFT 25 > +#define TRACECONTROL_E_MASK 0x01000000 > +#define TRACECONTROL_E_SHIFT 24 > +#define TRACECONTROL_K_MASK 0x00800000 > +#define TRACECONTROL_K_SHIFT 23 > +#define TRACECONTROL_S_MASK 0x00400000 > +#define TRACECONTROL_S_SHIFT 22 > +#define TRACECONTROL_U_MASK 0x00200000 > +#define TRACECONTROL_U_SHIFT 21 > +#define TRACECONTROL_ASID_M_MASK 0x001fe000 > +#define TRACECONTROL_ASID_M_SHIFT 13 > +#define TRACECONTROL_ASID_M_BITS 8 > +#define TRACECONTROL_ASID_MASK 0x00001fe0 > +#define TRACECONTROL_ASID_SHIFT 5 > +#define TRACECONTROL_ASID_BITS 8 > +#define TRACECONTROL_G_MASK 0x00000010 > +#define TRACECONTROL_G_SHIFT 4 > +#define TRACECONTROL_TFCR_MASK 0x00000008 > +#define TRACECONTROL_TFCR_SHIFT 3 > +#define TRACECONTROL_TLSM_MASK 0x00000004 > +#define TRACECONTROL_TLSM_SHIFT 2 > +#define TRACECONTROL_TIM_MASK 0x00000002 > +#define TRACECONTROL_TIM_SHIFT 1 > +#define TRACECONTROL_ON_MASK 0x00000001 > +#define TRACECONTROL_ON_SHIFT 0 > + > +/* MIPS32 TraceControl2 register (CP0 Register 23, select 2) */ > +#define TRACECONTROL2_SYPEXT_MASK 0xc0000000 > +#define TRACECONTROL2_SYPEXT_SHIFT 30 > +#define TRACECONTROL2_SYPEXT_BITS 2 > +#define TRACECONTROL2_CPUIDV_MASK 0x20000000 > +#define TRACECONTROL2_CPUIDV_SHIFT 29 > +#define TRACECONTROL2_CPUID_MASK 0x1fe00000 > +#define TRACECONTROL2_CPUID_SHIFT 21 > +#define TRACECONTROL2_CPUID_BITS 8 > +#define TRACECONTROL2_TCV_MASK 0x00100000 > +#define TRACECONTROL2_TCV_SHIFT 20 > +#define TRACECONTROL2_TCNUM_MASK 0x000ff000 > +#define TRACECONTROL2_TCNUM_SHIFT 12 > +#define TRACECONTROL2_TCNUM_BITS 8 > +#define TRACECONTROL2_MODE_MASK 0x00000f80 > +#define TRACECONTROL2_MODE_SHIFT 7 > +#define TRACECONTROL2_MODE_BITS 5 > +#define TRACECONTROL2_VMODE_MASK 0x00000060 > +#define TRACECONTROL2_VMODE_SHIFT 5 > +#define TRACECONTROL2_VMODE_BITS 2 > +#define TRACECONTROL2_VMODE_PC (0x0 << > TRACECONTROL2_VMODE_SHIFT) > +#define TRACECONTROL2_VMODE_PCLSA (0x1 << TRACECONTROL2_VMODE_SHIFT) > +#define TRACECONTROL2_VMODE_PCLSAD (0x2 << TRACECONTROL2_VMODE_SHIFT) > +#define TRACECONTROL2_TBI_MASK 0x00000010 > +#define TRACECONTROL2_TBI_SHIFT 4 > +#define TRACECONTROL2_TBU_MASK 0x00000008 > +#define TRACECONTROL2_TBU_SHIFT 3 > +#define TRACECONTROL2_SYP_MASK 0x00000007 > +#define TRACECONTROL2_SYP_SHIFT 0 > +#define TRACECONTROL2_SYP_BITS 3 > + > +/* MIPS32 TraceControl3 register (CP0 Register 24, select 2) */ > +#define TRACECONTROL3_TNUD_MASK 0x20000000 > +#define TRACECONTROL3_TNUD_SHIFT 29 > +#define TRACECONTROL3_MSA_EN_MASK 0x10000000 > +#define TRACECONTROL3_MSA_EN_SHIFT 28 > +#define TRACECONTROL3_MSA_MASK 0x08000000 > +#define TRACECONTROL3_MSA_SHIFT 27 > +#define TRACECONTROL3_EASID_M_MASK 0x06000000 > +#define TRACECONTROL3_EASID_M_SHIFT 25 > +#define TRACECONTROL3_EASID_M_BITS 2 > +#define TRACECONTROL3_EASID_MASK 0x01800000 > +#define TRACECONTROL3_EASID_SHIFT 23 > +#define TRACECONTROL3_EASID_BITS 2 > +#define TRACECONTROL3_GV_MASK 0x00400000 > +#define TRACECONTROL3_GV_SHIFT 22 > +#define TRACECONTROL3_GUESTID_MASK 0x003fc000 > +#define TRACECONTROL3_GUESTID_SHIFT 14 > +#define TRACECONTROL3_GUESTID_BITS 8 > +#define TRACECONTROL3_PECOVF_MASK 0x00000200 > +#define TRACECONTROL3_PECOVF_SHIFT 13 > +#define TRACECONTROL3_PECFCR_MASK 0x00000100 > +#define TRACECONTROL3_PECFCR_SHIFT 12 > +#define TRACECONTROL3_PECBP_MASK 0x00000080 > +#define TRACECONTROL3_PECBP_SHIFT 11 > +#define TRACECONTROL3_PECSYNC_MASK 0x00000040 > +#define TRACECONTROL3_PECSYNC_SHIFT 10 > +#define TRACECONTROL3_PECE_MASK 0x00000020 > +#define TRACECONTROL3_PECE_SHIFT 9 > +#define TRACECONTROL3_PEC_MASK 0x00000010 > +#define TRACECONTROL3_PEC_SHIFT 8 > +#define TRACECONTROL3_TRIDLE_MASK 0x00000004 > +#define TRACECONTROL3_TRIDLE_SHIFT 2 > +#define TRACECONTROL3_TRPAD_MASK 0x00000002 > +#define TRACECONTROL3_TRPAD_SHIFT 1 > +#define TRACECONTROL3_FDT_MASK 0x00000001 > +#define TRACECONTROL3_FDT_SHIFT 0 > + > +#ifdef __ASSEMBLER__ > + > +/* > + * MIPS32 Coprocessor 0 register numbers > + */ > +#define C0_INDEX $0 > +#define C0_INX $0 > +#define C0_RANDOM $1 > +#define C0_RAND $1 > +#define C0_ENTRYLO0 $2 > +#define C0_TLBLO0 $2 > +#define C0_ENTRYLO1 $3 > +#define C0_TLBLO1 $3 > +#define C0_GLOBAL $3,1 > +#define C0_CONTEXT $4 > +#define C0_CTXT $4 > +#define C0_CONTEXTCONF $4,1 > +#define C0_USERLOCAL $4,2 > +#define C0_XCONTEXTCONF $4,3 > +#define C0_DEBUGCTXTID $4,4 > +#define C0_PAGEMASK $5 > +#define C0_PAGEGRAIN $5,1 > +#define C0_SEGCTL0 $5,2 > +#define C0_SEGCTL1 $5,3 > +#define C0_SEGCTL2 $5,4 > +#define C0_PWBASE $5,5 > +#define C0_PWFIELD $5,6 > +#define C0_PWSIZE $5,7 > +#define C0_WIRED $6 > +#define C0_PWCTL $6,6 > +#define C0_HWRENA $7 > +#define C0_BADVADDR $8 > +#define C0_VADDR $8 > +#define C0_BADINSTR $8,1 > +#define C0_BADPINSTR $8,2 > +#define C0_COUNT $9 > +#define C0_ENTRYHI $10 > +#define C0_TLBHI $10 > +#define C0_COMPARE $11 > +#define C0_STATUS $12 > +#define C0_SR $12 > +#define C0_INTCTL $12,1 > +#define C0_SRSCTL $12,2 > +#define C0_SRSMAP $12,3 > +#define C0_CAUSE $13 > +#define C0_CR $13 > +#define C0_NESTEDEXC $13,5 > +#define C0_EPC $14 > +#define C0_NEPC $14,2 > +#define C0_PRID $15 > +#define C0_EBASE $15,1 > +#define C0_CDMMBASE $15,2 > +#define C0_CMGCRBASE $15,3 > +#define C0_BEVVA $15,4 > +#define C0_CONFIG $16 > +#define C0_CONFIG0 $16,0 > +#define C0_CONFIG1 $16,1 > +#define C0_CONFIG2 $16,2 > +#define C0_CONFIG3 $16,3 > +#define C0_CONFIG4 $16,4 > +#define C0_CONFIG5 $16,5 > +#define C0_LLADDR $17 > +#define C0_MAAR $17,1 > +#define C0_MAARI $17,2 > +#define C0_WATCHLO $18 > +#define C0_WATCHHI $19 > +#define C0_XCONTEXT $20 > +#define C0_DEBUG $23 > +#define C0_TRACECONTROL $23,1 > +#define C0_TRACECONTROL2 $23,2 > +#define C0_USERTRACEDATA1 $23,3 > +#define C0_TRACEIBPC $23,4 > +#define C0_TRACEDBPC $23,5 > +#define C0_DEBUG2 $23,6 > +#define C0_DEPC $24 > +#define C0_TRACECONTROL3 $24,2 > +#define C0_USERTRACEDATA2 $24,3 > +#define C0_PERFCNT $25 > +#define C0_ERRCTL $26 > +#define C0_CACHEERR $27 > +#define C0_TAGLO $28 > +#define C0_ITAGLO $28 > +#define C0_DTAGLO $28,2 > +#define C0_TAGLO2 $28,4 > +#define C0_DATALO $28,1 > +#define C0_IDATALO $28,1 > +#define C0_DDATALO $28,3 > +#define C0_DATALO2 $28,5 > +#define C0_TAGHI $29 > +#define C0_ITAGHI $29 > +#define C0_DTAGHI $29,2 > +#define C0_DATAHI $29,1 > +#define C0_IDATAHI $29,1 > +#define C0_DDATAHI $29,3 > +#define C0_ERRPC $30 > +#define C0_DESAVE $31 > +#define C0_KSCRATCH1 $31,2 > +#define C0_KSCRATCH2 $31,3 > +#define C0_KSCRATCH3 $31,4 > +#define C0_KSCRATCH4 $31,5 > +#define C0_KSCRATCH5 $31,6 > +#define C0_KSCRATCH6 $31,7 > + > +$index = $0 > +$random = $1 > +$entrylo0 = $2 > +$entrylo1 = $3 > +$context = $4 > +$pagemask = $5 > +$wired = $6 > +$hwrena = $7 > +$vaddr = $8 > +$badvaddr = $8 > +$count = $9 > +$entryhi = $10 > +$compare = $11 > +$sr = $12 > +$cr = $13 > +$epc = $14 > +$prid = $15 > +$config = $16 > +$lladdr = $17 > +$watchlo = $18 > +$watchhi = $19 > +$debug = $23 > +$depc = $24 > +$perfcnt = $25 > +$errctl = $26 > +$cacheerr = $27 > +$taglo = $28 > +$taghi = $29 > +$errpc = $30 > +$desave = $31 > + > + > +#else /* !__ASSEMBLER__ */ > + > +/* > + * Standard types > + */ > +typedef unsigned int reg32_t; /* a 32-bit register */ > +typedef unsigned long long reg64_t; /* a 64-bit register */ > +#if _MIPS_SIM==_ABIO32 > +typedef unsigned int reg_t; > +typedef signed int sreg_t; > +#else > +typedef unsigned long long reg_t; > +typedef signed long long sreg_t; > +#endif > + > +/* > + * MIPS32 Coprocessor 0 register encodings for C use. > + * These encodings are implementation specific. > + */ > +#define C0_INDEX 0 > +#define C0_INX 0 > +#define C0_RANDOM 1 > +#define C0_RAND 1 > +#define C0_ENTRYLO0 2 > +#define C0_TLBLO0 2 > +#define C0_ENTRYLO1 3 > +#define C0_TLBLO1 3 > +#define C0_GLOBAL 0x103 > +#define C0_CONTEXT 4 > +#define C0_CTXT 4 > +#define C0_CONTEXTCONF 0x104 > +#define C0_USERLOCAL 0x204 > +#define C0_XCONTEXTCONF 0x304 > +#define C0_DEBUGCTXTID 0x404 > +#define C0_PAGEMASK 5 > +#define C0_PAGEGRAIN 0x105 > +#define C0_SEGCTL0 0x205 > +#define C0_SEGCTL1 0x305 > +#define C0_SEGCTL2 0x405 > +#define C0_PWBASE 0x505 > +#define C0_PWFIELD 0x605 > +#define C0_PWSIZE 0x705 > +#define C0_WIRED 6 > +#define C0_PWCTL 0x606 > +#define C0_HWRENA 7 > +#define C0_BADVADDR 8 > +#define C0_VADDR 8 > +#define C0_BADINSTR 0x108 > +#define C0_BADINSTRP 0x208 > +#define C0_COUNT 9 > +#define C0_ENTRYHI 10 > +#define C0_TLBHI 10 > +#define C0_COMPARE 11 > +#define C0_STATUS 12 > +#define C0_SR 12 > +#define C0_INTCTL 0x10C > +#define C0_SRSCTL 0x20C > +#define C0_SRSMAP 0x30C > +#define C0_CAUSE 13 > +#define C0_CR 13 > +#define C0_NESTEDEXC 0x50D > +#define C0_EPC 14 > +#define C0_NEPC 0x20E > +#define C0_PRID 15 > +#define C0_EBASE 0x10F > +#define C0_CDMMBASE 0x20F > +#define C0_CMGCRBASE 0x30F > +#define C0_BEVVA 0x40F > +#define C0_CONFIG 16 > +#define C0_CONFIG0 16 > +#define C0_CONFIG1 0x110 > +#define C0_CONFIG2 0x210 > +#define C0_CONFIG3 0x310 > +#define C0_CONFIG4 0x410 > +#define C0_CONFIG5 0x510 > +#define C0_LLADDR 17 > +#define C0_MAAR 0x111 > +#define C0_MAARI 0x111 > +#define C0_WATCHLO 18 > +#define C0_WATCHHI 19 > +#define C0_XCONTEXT 20 > +#define C0_DEBUG 23 > +#define C0_TRACECONTROL 0x117 > +#define C0_TRACECONTROL2 0x217 > +#define C0_USERTRACEDATA1 0x317 > +#define C0_TRACEIBPC 0x417 > +#define C0_TRACEDBPC 0x517 > +#define C0_DEBUG2 0x617 > +#define C0_DEPC 24 > +#define C0_TRACECONTROL3 0x218 > +#define C0_USERTRACEDATA2 0x318 > +#define C0_PERFCNT 25 > +#define C0_ERRCTL 26 > +#define C0_CACHEERR 27 > +#define C0_TAGLO 28 > +#define C0_ITAGLO 28 > +#define C0_DTAGLO 0x21C > +#define C0_TAGLO2 0x41C > +#define C0_DATALO 0x11C > +#define C0_IDATALO 0x11C > +#define C0_DDATALO 0x31C > +#define C0_DATALO2 0x51C > +#define C0_TAGHI 29 > +#define C0_ITAGHI 29 > +#define C0_DTAGHI 0x21D > +#define C0_DATAHI 0x11D > +#define C0_IDATAHI 0x11D > +#define C0_DDATAHI 0x31D > +#define C0_ERRPC 30 > +#define C0_DESAVE 31 > +#define C0_KSCRATCH1 0x21F > +#define C0_KSCRATCH2 0x31F > +#define C0_KSCRATCH3 0x41F > +#define C0_KSCRATCH4 0x51F > +#define C0_KSCRATCH5 0x61F > +#define C0_KSCRATCH6 0x71F > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#define _mips_sync() __asm__ __volatile__ ("sync" : : : "memory") > + > +/* wait for unmasked interrupt */ > +#define _mips_wait() \ > + __asm__ __volatile ("wait") > + > +/* > + * Define macros for accessing the MIPS32 coprocessor 0 registers. Most > apart > + * from "set" return the original register value. These macros take an > encoded > + * (register, select) combination, so they can use the textual names > above. > + */ > + > +#define MIPS_C0_REGNAME(regno, sel) ((sel << 8) + regno) > + > +#define mips32_get_c0(selreg) \ > +__extension__ ({ \ > + register unsigned long __r; \ > + __asm__ __volatile ("mfc0 %0,$%1,%2" \ > + : "=d" (__r) \ > + : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \ > + __r; \ > +}) > + > +#undef EHB > +#if defined (__MIPS_NO_IMPLICIT_EHB) > +#define EHB "" > +#else > +#define EHB "ehb\n" > +#endif > + > +#define mips32_set_c0(selreg, val) \ > +do { \ > + __asm__ __volatile (".set push \n"\ > + ".set noreorder\n"\ > + "mtc0 %z0,$%1,%2\n"\ > + EHB \ > + ".set pop" \ > + : \ > + : "dJ" ((reg32_t)(val)), "JK" (selreg & 0x1F),\ > + "JK" (selreg >> 8) \ > + : "memory"); \ > +} while (0) > + > +#define mips32_xch_c0(selreg, val) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = mips32_get_c0 (selreg); \ > + mips32_set_c0 (selreg, val); \ > + __o; \ > +}) > + > +#define mips32_bc_c0(selreg, clr) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = mips32_get_c0 (selreg); \ > + mips32_set_c0 (selreg, __o & ~(clr)); \ > + __o; \ > +}) > + > +#define mips32_bs_c0(selreg, set) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = mips32_get_c0 (selreg); \ > + mips32_set_c0 (selreg, __o | (set)); \ > + __o; \ > +}) > + > +#define mips32_bcs_c0(selreg, clr, set) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = mips32_get_c0 (selreg); \ > + mips32_set_c0 (selreg, (__o & ~(clr)) | (set)); \ > + __o; \ > +}) > + > +/* MIPS instructions */ > +#define mips_sync() \ > + ({__asm__ volatile ("\t sync \n");}) > + > +#define mips_synci(ADDR) \ > + ({__asm__ volatile ("\t synci 0(%0) \n" :: "r" (ADDR));}) > + > +#define mips_synci_step() \ > +({ \ > + int _step; \ > + __asm__ volatile ( \ > + "\t rdhwr %0,$1 \n" : "=r" (_step)); \ > + _step; \ > +}) > + > +#define mips_ehb() \ > + ({__asm__ volatile ("\t ehb \n");}) > + > +#define mips_tlbwi() \ > + ({__asm__ volatile ("\t tlbwi \n");}) > + > +#define mips_tlbwr() \ > + ({__asm__ volatile ("\t tlbwr \n");}) > + > +#define mips_tlbp() \ > + ({__asm__ volatile ("\t tlbp \n");}) > + > +#define mips_tlbr() \ > + ({__asm__ volatile ("\t tlbr \n");}) > + > +#define mips_eva_tlbinvf() \ > +({__asm__ volatile ( \ > + "\t .set push \n" \ > + "\t .set eva \n" \ > + "\t tlbinvf \n" \ > + "\t .set pop \n" \ > + ); \ > +}) > + > +/* Set upper half of EntryHI */ > +#define mips32_sethientryhi(VAL) \ > +({__asm__ volatile ( \ > + "\t .set push \n" \ > + "\t .set xpa \n" \ > + "\t mthc0 %0,$10,0 \n" \ > + "\t .set pop \n" \ > + : :"r" (VAL) \ > + ); \ > +}) > + > +#define mips_cache(OP,ADDR) \ > + ({__asm__ volatile ("\t cache %0,0(%1) \n" :: "JK" (OP), "r" (ADDR));}) > + > +/* generic equivalents for mips/cpu.h */ > +#define _mips_mfc0(r) mips32_get_c0(r) > +#define _mips_mtc0(r,v) mips32_set_c0(r,v) > + > +/* MIPS32 Entry*, Index, PageMask registers */ > +#define mips32_getentryhi() mips32_get_c0(C0_ENTRYHI) > +#define mips32_setentryhi(v) mips32_set_c0(C0_ENTRYHI,v) > +#define mips32_getentrylo0() mips32_get_c0(C0_ENTRYLO0) > +#define mips32_setentrylo0(v) mips32_set_c0(C0_ENTRYLO0,v) > +#define mips32_getentrylo1() mips32_get_c0(C0_ENTRYLO1) > +#define mips32_setentrylo1(v) mips32_set_c0(C0_ENTRYLO1,v) > +#define mips32_getpagemask() mips32_get_c0(C0_PAGEMASK) > +#define mips32_setpagemask(v) mips32_set_c0(C0_PAGEMASK,v) > +#define mips32_getindex() mips32_get_c0(C0_INDEX) > +#define mips32_setindex(v) mips32_set_c0(C0_INDEX,v) > + > +/* MIPS32 Config0 register */ > +#define mips32_getconfig0() mips32_get_c0(C0_CONFIG0) > +#define mips32_setconfig0(v) mips32_set_c0(C0_CONFIG0,v) > +#define mips32_xchconfig0(v) mips32_xch_c0(C0_CONFIG0,v) > +#define mips32_bicconfig0(clr) mips32_bc_c0(C0_CONFIG0,clr) > +#define mips32_bisconfig0(set) mips32_bs_c0(C0_CONFIG0,set) > +#define mips32_bcsconfig0(c,s) mips32_bcs_c0(C0_CONFIG0,c,s) > + > +/* MIPS32 Config1, 2, 3, 4, 5 register */ > +#define mips32_getconfig1() mips32_get_c0(C0_CONFIG1) > +#define mips32_setconfig1(v) mips32_set_c0(C0_CONFIG1,v) > +#define mips32_xchconfig1(v) mips32_xch_c0(C0_CONFIG1,v) > +#define mips32_bicconfig1(clr) mips32_bc_c0(C0_CONFIG1,clr) > +#define mips32_bisconfig1(set) mips32_bs_c0(C0_CONFIG1,set) > +#define mips32_bcsconfig1(c,s) mips32_bcs_c0(C0_CONFIG1,c,s) > + > +#define mips32_getconfig2() mips32_get_c0(C0_CONFIG2) > +#define mips32_setconfig2(v) mips32_set_c0(C0_CONFIG2,v) > +#define mips32_xchconfig2(v) mips32_xch_c0(C0_CONFIG2,v) > +#define mips32_bicconfig2(clr) mips32_bc_c0(C0_CONFIG2,clr) > +#define mips32_bisconfig2(set) mips32_bs_c0(C0_CONFIG2,set) > +#define mips32_bcsconfig2(c,s) mips32_bcs_c0(C0_CONFIG2,c,s) > + > +#define mips32_getconfig3() mips32_get_c0(C0_CONFIG3) > +#define mips32_setconfig3(v) mips32_set_c0(C0_CONFIG3,v) > +#define mips32_xchconfig3(v) mips32_xch_c0(C0_CONFIG3,v) > +#define mips32_bicconfig3(clr) mips32_bc_c0(C0_CONFIG3,clr) > +#define mips32_bisconfig3(set) mips32_bs_c0(C0_CONFIG3,set) > +#define mips32_bcsconfig3(c,s) mips32_bcs_c0(C0_CONFIG3,c,s) > + > +#define mips32_getconfig4() mips32_get_c0(C0_CONFIG4) > +#define mips32_setconfig4(v) mips32_set_c0(C0_CONFIG4,v) > +#define mips32_xchconfig4(v) mips32_xch_c0(C0_CONFIG4,v) > +#define mips32_bicconfig4(clr) mips32_bc_c0(C0_CONFIG4,clr) > +#define mips32_bisconfig4(set) mips32_bs_c0(C0_CONFIG4,set) > +#define mips32_bcsconfig4(c,s) mips32_bcs_c0(C0_CONFIG4,c,s) > + > +#define mips32_getconfig5() mips32_get_c0(C0_CONFIG5) > +#define mips32_setconfig5(v) mips32_set_c0(C0_CONFIG5,v) > +#define mips32_xchconfig5(v) mips32_xch_c0(C0_CONFIG5,v) > +#define mips32_bicconfig5(clr) mips32_bc_c0(C0_CONFIG5,clr) > +#define mips32_bisconfig5(set) mips32_bs_c0(C0_CONFIG5,set) > +#define mips32_bcsconfig5(c,s) mips32_bcs_c0(C0_CONFIG5,c,s) > + > +/* MIPS32 Debug register */ > +#define mips32_getdebug() mips32_get_c0(C0_DEBUG) > +#define mips32_setdebug(v) mips32_set_c0(C0_DEBUG,v) > +#define mips32_xchdebug(v) mips32_xch_c0(C0_DEBUG,v) > +#define mips32_bicdebug(clr) mips32_bc_c0(C0_DEBUG,clr) > +#define mips32_bisdebug(set) mips32_bs_c0(C0_DEBUG,set) > +#define mips32_bcsdebug(c,s) mips32_bcs_c0(C0_DEBUG,c,s) > + > +/* MIPS32 ErrCtl register */ > +#define mips32_geterrctl() mips32_get_c0(C0_ERRCTL) > +#define mips32_seterrctl(x) mips32_set_c0(C0_ERRCTL,x) > +#define mips32_xcherrctl(x) mips32_xch_c0(C0_ERRCTL,x) > +#define mips32_bicerrctl(clr) mips32_bc_c0(C0_ERRCTL,clr) > +#define mips32_biserrctl(set) mips32_bs_c0(C0_ERRCTL,set) > +#define mips32_bcserrctl(c,s) mips32_bcs_c0(C0_ERRCTL,c,s) > + > +/* MIPS32 TagLo register */ > +#define mips32_getitaglo() mips32_get_c0(C0_TAGLO) /* alias > define */ > +#define mips32_setitaglo(x) mips32_set_c0(C0_TAGLO,x) /* alias > define */ > +#define mips32_xchitaglo(x) mips32_xch_c0(C0_TAGLO,x) /* alias > define */ > +#define mips32_getdtaglo() mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 2)) > +#define mips32_setdtaglo(x) mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 2),x) > +#define mips32_xchdtaglo(x) mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 2),x) > +#define mips32_gettaglo2() mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 4)) > +#define mips32_settaglo2(x) mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 4),x) > +#define mips32_xchtaglo2(x) mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 4),x) > + > +/* MIPS32 DataLo register */ > +#define mips32_getdatalo() mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 1)) > +#define mips32_setdatalo(x) mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 1),x) > +#define mips32_xchdatalo(x) mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 1),x) > +#define mips32_getidatalo() mips32_getdatalo() /* alias define */ > +#define mips32_setidatalo(x) mips32_setdatalo(x) /* alias define */ > +#define mips32_xchidatalo(x) mips32_xchdatalo(x) /* alias define */ > +#define mips32_getddatalo() mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 3)) > +#define mips32_setddatalo(x) mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 3),x) > +#define mips32_xchddatalo(x) mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 3),x) > +#define mips32_getdatalo2() mips32_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 5)) > +#define mips32_setdatalo2(x) mips32_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 5),x) > +#define mips32_xchdatalo2(x) mips32_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 5),x) > + > +/* MIPS32r2 IntCtl register */ > +#define mips32_getintctl() mips32_get_c0(C0_INTCTL) > +#define mips32_setintctl(x) mips32_set_c0(C0_INTCTL,x) > +#define mips32_xchintctl(x) mips32_xch_c0(C0_INTCTL,x) > + > +/* MIPS32r2 SRSCtl register */ > +#define mips32_getsrsctl() mips32_get_c0(C0_SRSCTL) > +#define mips32_setsrsctl(x) mips32_set_c0(C0_SRSCTL,x) > +#define mips32_xchsrsctl(x) mips32_xch_c0(C0_SRSCTL,x) > + > +/* MIPS32r2 SRSMap register */ > +#define mips32_getsrsmapl() mips32_get_c0(C0_SRSMAP) > +#define mips32_setsrsmap(x) mips32_set_c0(C0_SRSMAP,x) > +#define mips32_xchsrsmap(x) mips32_xch_c0(C0_SRSMAP,x) > + > +/* MIPS32r2/SmartMIPS PageGrain register */ > +#define mips32_getpagegrain() mips32_get_c0(C0_PAGEGRAIN) > +#define mips32_setpagegrain(x) mips32_set_c0(C0_PAGEGRAIN,x) > +#define mips32_xchpagegrain(x) mips32_xch_c0(C0_PAGEGRAIN,x) > + > +/* MIPS32r2 HWREna register */ > +#define mips32_gethwrena() mips32_get_c0(C0_HWRENA) > +#define mips32_sethwrena(v) mips32_set_c0(C0_HWRENA,v) > +#define mips32_xchhwrena(v) mips32_xch_c0(C0_HWRENA,v) > +#define mips32_bichwrena(clr) mips32_bc_c0(C0_HWRENA,clr) > +#define mips32_bishwrena(set) mips32_bs_c0(C0_HWRENA,set) > +#define mips32_bcshwrena(c,s) mips32_bcs_c0(C0_HWRENA,c,s) > + > +/* MIPS32r2 EBase register */ > +#define mips32_getebase() mips32_get_c0(C0_EBASE) > +#define mips32_setebase(x) mips32_set_c0(C0_EBASE,x) > +#define mips32_xchebase(x) mips32_xch_c0(C0_EBASE,x) > + > +/* CP0 Status register (NOTE: not atomic operations) */ > +#define mips32_getsr() mips32_get_c0(C0_SR) > +#define mips32_setsr(v) mips32_set_c0(C0_SR,v) > +#define mips32_xchsr(v) mips32_xch_c0(C0_SR,v) > +#define mips32_bicsr(clr) mips32_bc_c0(C0_SR,clr) > +#define mips32_bissr(set) mips32_bs_c0(C0_SR,set) > +#define mips32_bcssr(c,s) mips32_bcs_c0(C0_SR,c,s) > + > +/* CP0 Cause register (NOTE: not atomic operations) */ > +#define mips32_getcr() mips32_get_c0(C0_CR) > +#define mips32_setcr(v) mips32_set_c0(C0_CR,v) > +#define mips32_xchcr(v) mips32_xch_c0(C0_CR,v) > +#define mips32_biccr(clr) mips32_bc_c0(C0_CR,clr) > +#define mips32_biscr(set) mips32_bs_c0(C0_CR,set) > +#define mips32_bcscr(c,s) mips32_bcs_c0(C0_CR,c,s) > + > +/* CP0 PrID register */ > +#define mips32_getprid() mips32_get_c0(C0_PRID) > + > +#ifdef C0_COUNT > +/* CP0 Count register */ > +#define mips32_getcount() mips32_get_c0(C0_COUNT) > +#define mips32_setcount(v) mips32_set_c0(C0_COUNT,v) > +#define mips32_xchcount(v) mips32_xch_c0(C0_COUNT,v) > +#endif > + > +#ifdef C0_COMPARE > +/* CP0 Compare register*/ > +#define mips32_getcompare() mips32_get_c0(C0_COMPARE) > +#define mips32_setcompare(v) mips32_set_c0(C0_COMPARE,v) > +#define mips32_xchcompare(v) mips32_xch_c0(C0_COMPARE,v) > +#endif > + > +#ifdef C0_CONFIG > +/* CP0 Config register */ > +#define mips32_getconfig() mips32_get_c0(C0_CONFIG) > +#define mips32_setconfig(v) mips32_set_c0(C0_CONFIG,v) > +#define mips32_xchconfig(v) mips32_xch_c0(C0_CONFIG,v) > +#define mips32_bicconfig(c) mips32_bc_c0(C0_CONFIG,c) > +#define mips32_bisconfig(s) mips32_bs_c0(C0_CONFIG,s) > +#define mips32_bcsconfig(c,s) mips32_bcs_c0(C0_CONFIG,c,s) > +#endif > + > +#ifdef C0_ECC > +/* CP0 ECC register */ > +#define mips32_getecc() mips32_get_c0(C0_ECC) > +#define mips32_setecc(x) mips32_set_c0(C0_ECC, x) > +#define mips32_xchecc(x) mips32_xch_c0(C0_ECC, x) > +#endif > + > +#ifdef C0_TAGHI > +/* CP0 TagHi register */ > +#define mips32_gettaghi() mips32_get_c0(C0_TAGHI) > +#define mips32_settaghi(x) mips32_set_c0(C0_TAGHI, x) > +#define mips32_xchtaghi(x) mips32_xch_c0(C0_TAGHI, x) > +#endif > + > +#ifdef C0_WATCHLO > +/* CP0 WatchLo register */ > +#define mips32_getwatchlo() mips32_get_c0(C0_WATCHLO) > +#define mips32_setwatchlo(x) mips32_set_c0(C0_WATCHLO, x) > +#define mips32_xchwatchlo(x) mips32_xch_c0(C0_WATCHLO, x) > +#endif > + > +#ifdef C0_WATCHHI > +/* CP0 WatchHi register */ > +#define mips32_getwatchhi() mips32_get_c0(C0_WATCHHI) > +#define mips32_setwatchhi(x) mips32_set_c0(C0_WATCHHI, x) > +#define mips32_xchwatchhi(x) mips32_xch_c0(C0_WATCHHI, x) > +#endif > + > +#ifdef C0_USERTRACE1 > +/* PDTRACE usertrace registers */ > +#define mips32_usertrace1(x) mips32_set_c0(C0_USERTRACE1, x) > +#define mips32_usertrace2(x) mips32_set_c0(C0_USERTRACE2, x) > +#endif > + > +/* > + * Define macros for accessing the MIPS32 coprocessor 0 registers. Most > + * apart from "set" return the original register value. These particular > + * macros take (reg, sel) as separate paramters, so they can't be used > with > + * the coprocessor 0 register names above. > + */ > +#define _m32c0_mfc0(reg, sel) \ > +__extension__ ({ \ > + register unsigned long __r; \ > + __asm__ __volatile ("mfc0 %0,$%1,%2" \ > + : "=d" (__r) \ > + : "JK" (reg), "JK" (sel)); \ > + __r; \ > +}) > + > +#define _m32c0_mtc0(reg, sel, val) \ > +do { \ > + __asm__ __volatile (".set push \n"\ > + ".set noreorder\n"\ > + "mtc0 %z0,$%1,%2\n"\ > + "ehb\n" \ > + ".set pop" \ > + : \ > + : "dJ" ((reg32_t)(val)), "JK" (reg), "JK" (sel) \ > + : "memory"); \ > +} while (0) > + > +#define _m32c0_mxc0(reg, sel, val) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _m32c0_mfc0 (reg, sel); \ > + _m32c0_mtc0 (reg, sel, val); \ > + __o; \ > +}) > + > +#define _m32c0_bcc0(reg, sel, clr) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _m32c0_mfc0 (reg, sel); \ > + _m32c0_mtc0 (reg, sel, __o & ~(clr)); \ > + __o; \ > +}) > + > +#define _m32c0_bsc0(reg, sel, set) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _m32c0_mfc0 (reg, sel); \ > + _m32c0_mtc0 (reg, sel, __o | (set)); \ > + __o; \ > +}) > + > +#define _m32c0_bcsc0(reg, sel, clr, set) \ > +__extension__ ({ \ > + register reg32_t __o; \ > + __o = _m32c0_mfc0 (reg, sel); \ > + _m32c0_mtc0 (reg, sel, (__o & ~(clr)) | (set)); \ > + __o; \ > +}) > + > +#ifdef __cplusplus > +} > +#endif > + > +/* Define MIPS32 user-level intrinsics */ > +#include <mips/mips32.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* CP0 intrinsics */ > + > +/* MIPS32r2 atomic interrupt disable */ > +#define _mips_intdisable() __extension__({ \ > + unsigned int __v; \ > + __asm__ __volatile__ ("di %0; ehb" : "=d" (__v)); \ > + __v; \ > +}) > + > +/* MIPS32r2 atomic interrupt disable */ > +#define _mips_intenable() __extension__({ \ > + unsigned int __v; \ > + __asm__ __volatile__ ("ei %0; ehb" : "=d" (__v)); \ > + __v; \ > +}) > + > +/* MIPS32r2 atomic interrupt restore */ > +#define _mips_intrestore(x) \ > + mips_setsr (x) > + > +/* MIPS32r2 set SRSCtl.PSS (previous shadow set), returning old value */ > +extern unsigned int _mips32r2_xchsrspss (unsigned int); > + > +/* MIPS32r2 write previous gpr */ > +#define _mips32r2_wrpgpr(regno, val) \ > +do { \ > + __asm __volatile ("wrpgpr $%0,%z1" \ > + : /* no outputs */ \ > + : "JK" (regno), "dJ" (val)); \ > +} while (0) > + > +/* MIPS32r2 read previous gpr */ > +#define _mips32r2_rdpgpr(regno) \ > +__extension__({ \ > + reg_t __val; \ > + __asm __volatile ("rdpgpr %0,$%1" \ > + : "=d" (__val) \ > + : "JK" (regno)); \ > + __val; \ > +}) > + > +#endif /* __ASSEMBLER__ */ > + > +/* MIPS32 PREF instruction hint codes */ > +#define PREF_LOAD 0 > +#define PREF_STORE 1 > +#define PREF_LOAD_STREAMED 4 > +#define PREF_STORE_STREAMED 5 > +#define PREF_LOAD_RETAINED 6 > +#define PREF_STORE_RETAINED 7 > +#define PREF_WRITEBACK_INVAL 25 > +#define PREF_PREPAREFORSTORE 30 > + > +#ifdef __cplusplus > +} > +#endif > +#endif /* _M32C0_H_ */ > diff --git a/libgloss/mips/include/mips/m32c1.h > b/libgloss/mips/include/mips/m32c1.h > new file mode 100644 > index 000000000..e33837c2b > --- /dev/null > +++ b/libgloss/mips/include/mips/m32c1.h > @@ -0,0 +1,276 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _M32C1_H_ > +#define _M32C1_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifndef __ASSEMBLER__ > + > +unsigned fpa_getrid(void); /* get fpa revision id */ > +unsigned fpa_getsr(void); /* get fpa status register */ > +void fpa_setsr(unsigned); > +unsigned fpa_xchsr(unsigned); > +unsigned fpa_bicsr(unsigned); > +unsigned fpa_bissr(unsigned); > + > +unsigned msa_getmir(void); /* get msa revision id */ > +unsigned msa_getsr(void); /* get msa status register */ > +void msa_setsr(unsigned); > +unsigned msa_xchsr(unsigned); > +unsigned msa_bicsr(unsigned); > +unsigned msa_bissr(unsigned); > + > +/* > + * Define macros to accessing the Coprocessor 1 control registers. > + * Most apart from "set" return the original register value. > + */ > + > +#define fpa_getrid() \ > +__extension__({ \ > + register unsigned __r; \ > + __asm__ __volatile ("cfc1 %0,$0" : "=d" (__r)); \ > + __r; \ > +}) > + > +#define fpa_getfir() fpa_getrid() > + > +#define fpa_getsr() \ > +__extension__({ \ > + register unsigned __r; \ > + __asm__ __volatile ("cfc1 %0,$31" : "=d" (__r)); \ > + __r; \ > +}) > + > +#define fpa_setsr(val) \ > +__extension__({ \ > + register unsigned __r = (val); \ > + __asm__ __volatile ("ctc1 %0,$31" : : "d" (__r)); \ > + __r; \ > +}) > + > +#define fpa_xchsr(val) \ > +__extension__({ \ > + register unsigned __o, __n = (val); \ > + __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \ > + __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \ > + __o; \ > +}) > + > +#define fpa_bissr(val) \ > +__extension__({ \ > + register unsigned __o, __n; \ > + __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \ > + __n = __o | (val); \ > + __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \ > + __o; \ > +}) > + > +#define fpa_bicsr(val) \ > +__extension__({ \ > + register unsigned __o, __n; \ > + __asm__ __volatile ("cfc1 %0,$31" : "=d" (__o)); \ > + __n = __o &~ (val); \ > + __asm__ __volatile ("ctc1 %0,$31" : : "d" (__n)); \ > + __o; \ > +}) > + > + > +#define msa_getmir() \ > +__extension__({ \ > + register unsigned __r; \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "cfcmsa %0,$0\n" \ > + ".set pop": "=d" (__r)); \ > + __r; \ > +}) > + > +#define msa_getsr() \ > +__extension__({ \ > + register unsigned __r; \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "cfcmsa %0,$1\n" \ > + ".set pop": "=d" (__r)); \ > + __r; \ > +}) > + > +#define msa_setsr(val) \ > +__extension__({ \ > + register unsigned __r = (val); \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "ctcmsa $1,%0\n" \ > + ".set pop": : "d" (__r)); \ > + __r; \ > +}) > + > +#define msa_xchsr(val) \ > +__extension__({ \ > + register unsigned __o, __n = (val); \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "cfcmsa %0,$1\n" \ > + ".set pop": "=d" (__o)); \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "ctcmsa $1,%0\n" \ > + ".set pop": : "d" (__n)); \ > + __o; \ > +}) > + > +#define msa_bissr(val) \ > +__extension__({ \ > + register unsigned __o, __n; \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "cfcmsa %0,$1\n" \ > + ".set pop": "=d" (__o)); \ > + __n = __o | (val); \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "ctcmsa $1,%0\n" \ > + ".set pop": : "d" (__n)); \ > + __o; \ > +}) > + > +#define msa_bicsr(val) \ > +__extension__({ \ > + register unsigned __o, __n; \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "cfcmsa %0,$1\n" \ > + ".set pop": "=d" (__o)); \ > + __n = __o &~ (val); \ > + __asm__ __volatile (".set push\n" \ > + ".set fp=64\n" \ > + ".set msa\n" \ > + "ctcmsa $1,%0\n" \ > + ".set pop": : "d" (__n)); \ > + __o; \ > +}) > + > +#endif /* !ASSEMBLER */ > + > +#ifdef __cplusplus > +} > +#endif > + > +/* > + * FCSR - FPU Control & Status Register > + */ > +#define FPA_CSR_MD0 0x00200000 /* machine dependent */ > +#define FPA_CSR_MD1 0x00400000 /* machine dependent */ > +#define FPA_CSR_COND 0x00800000 /* $fcc0 */ > +#define FPA_CSR_COND0 0x00800000 /* $fcc0 */ > +#define FPA_CSR_FLUSH 0x01000000 /* flush to 0 */ > +#define FPA_CSR_FS 0x01000000 /* flush to 0 */ > +#define FPA_CSR_COND1 0x02000000 /* $fcc1 */ > +#define FPA_CSR_COND2 0x04000000 /* $fcc2 */ > +#define FPA_CSR_COND3 0x08000000 /* $fcc3 */ > +#define FPA_CSR_COND4 0x10000000 /* $fcc4 */ > +#define FPA_CSR_COND5 0x20000000 /* $fcc5 */ > +#define FPA_CSR_COND6 0x40000000 /* $fcc6 */ > +#define FPA_CSR_COND7 0x80000000 /* $fcc7 */ > + > +/* > + * X the exception cause indicator > + * E the exception enable > + * S the sticky/flag bit > +*/ > +#define FPA_CSR_ALL_X 0x0003f000 > +#define FPA_CSR_UNI_X 0x00020000 > +#define FPA_CSR_INV_X 0x00010000 > +#define FPA_CSR_DIV_X 0x00008000 > +#define FPA_CSR_OVF_X 0x00004000 > +#define FPA_CSR_UDF_X 0x00002000 > +#define FPA_CSR_INE_X 0x00001000 > + > +#define FPA_CSR_ALL_E 0x00000f80 > +#define FPA_CSR_INV_E 0x00000800 > +#define FPA_CSR_DIV_E 0x00000400 > +#define FPA_CSR_OVF_E 0x00000200 > +#define FPA_CSR_UDF_E 0x00000100 > +#define FPA_CSR_INE_E 0x00000080 > + > +#define FPA_CSR_ALL_S 0x0000007c > +#define FPA_CSR_INV_S 0x00000040 > +#define FPA_CSR_DIV_S 0x00000020 > +#define FPA_CSR_OVF_S 0x00000010 > +#define FPA_CSR_UDF_S 0x00000008 > +#define FPA_CSR_INE_S 0x00000004 > + > +/* rounding mode */ > +#define FPA_CSR_RN 0x0 /* nearest */ > +#define FPA_CSR_RZ 0x1 /* towards zero */ > +#define FPA_CSR_RU 0x2 /* towards +Infinity */ > +#define FPA_CSR_RD 0x3 /* towards -Infinity */ > + > +/* FPU Implementation Register */ > +#define FPA_FIR_F64 0x00400000 /* implements 64-bits registers */ > +#define FPA_FIR_L 0x00200000 /* implements long fixed point */ > +#define FPA_FIR_W 0x00100000 /* implements word fixed point */ > +#define FPA_FIR_3D 0x00080000 /* implements MIPS-3D ASE */ > +#define FPA_FIR_PS 0x00040000 /* implements paired-single format > */ > +#define FPA_FIR_D 0x00020000 /* implements double format */ > +#define FPA_FIR_S 0x00010000 /* implements single format */ > +#define FPA_FIR_PRID 0x0000ff00 /* ProcessorID */ > +#define FPA_FIR_REV 0x000000ff /* Revision */ > + > +#ifdef __ASSEMBLER__ > + > + .previous > + > +/* control regs */ > + $fir = $0 > + $fccr = $25 > + $fexr = $26 > + $fenr = $28 > + $fcsr = $31 > + > +/* backwards compat */ > + $fpa_rid = $0 > + $fpa_sr = $31 > +#endif > + > + > +#endif /*_M32C1_H_*/ > diff --git a/libgloss/mips/include/mips/m32tlb.h > b/libgloss/mips/include/mips/m32tlb.h > new file mode 100644 > index 000000000..0abd99dde > --- /dev/null > +++ b/libgloss/mips/include/mips/m32tlb.h > @@ -0,0 +1,103 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > + /* > + * m32tlb.h: MIPS32 TLB support functions > + */ > + > +#ifndef _M32TLB_H_ > +#define _M32TLB_H_ > + > +#if __mips != 32 && __mips != 64 > +#error use -mips32 or -mips64 option with this file > +#endif > + > +#include <mips/notlb.h> > +#ifndef __ASSEMBLER__ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifdef __mips16 > +# define _MIPS_M32TLB_NOMIPS16 __attribute__((nomips16)) > +#else > +# define _MIPS_M32TLB_NOMIPS16 > +#endif > + > +typedef unsigned int tlbhi_t; > +typedef unsigned int tlblo_t; > + > +// Returns the size of the TLB. > +_MIPS_M32TLB_NOMIPS16 > +int mips_tlb_size (void); > + // Probes the TLB for an entry matching hi, and if present invalidates > it. > +_MIPS_M32TLB_NOMIPS16 > +void mips_tlbinval (tlbhi_t hi); > + > +// Invalidate the whole TLB. > +_MIPS_M32TLB_NOMIPS16 > +void mips_tlbinvalall (void); > + > +// Reads the TLB entry with specified by index, and returns the EntryHi, > +// EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmsk > +// respectively. > +_MIPS_M32TLB_NOMIPS16 > +void mips_tlbri2 (tlbhi_t *phi, tlblo_t *plo0, tlblo_t *plo1, unsigned > *pmsk, > + int index); > + > +// Writes hi, lo0, lo1 and msk into the TLB entry specified by index. > +_MIPS_M32TLB_NOMIPS16 > +void mips_tlbwi2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk, > + int index); > + > +// Writes hi, lo0, lo1 and msk into the TLB entry specified by the > +// Random register. > +_MIPS_M32TLB_NOMIPS16 > +void mips_tlbwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk); > + > +// Probes the TLB for an entry matching hi and returns its index, or -1 if > +// not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of > the > +// entry are also returned in *plo0, *plo1 and *pmsk respectively > +_MIPS_M32TLB_NOMIPS16 > +int mips_tlbprobe2 (tlbhi_t hi, tlblo_t *plo0, tlblo_t *plo1, unsigned > *pmsk); > + > +// Probes the TLB for an entry matching hi and if present rewrites that > entry, > +// otherwise updates a random entry. A safe way to update the TLB. > +_MIPS_M32TLB_NOMIPS16 > +int mips_tlbrwr2 (tlbhi_t hi, tlblo_t lo0, tlblo_t lo1, unsigned msk); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __ASSEMBLER__ */ > + > +#endif /* _M32TLB_H_ */ > diff --git a/libgloss/mips/include/mips/m64c0.h > b/libgloss/mips/include/mips/m64c0.h > new file mode 100644 > index 000000000..2fc0203ea > --- /dev/null > +++ b/libgloss/mips/include/mips/m64c0.h > @@ -0,0 +1,268 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _M64C0_H_ > +#define _M64C0_H_ > + > +/* Superset of MIPS32 */ > +#include <mips/m32c0.h> > + > +#ifndef __ASSEMBLER__ > +typedef union { > + unsigned long long ll; > + struct { > +#if defined(_MIPSEB) || defined(MIPSEB) > + unsigned int hi; > + unsigned int lo; > +#else > + unsigned int lo; > + unsigned int hi; > +#endif > + } s; > +} __ll_shape_type; > +#endif > + > +/* > + * Define macros for accessing the MIPS coprocessor 0 registers which are > + * 64 bits wide. > + * Most apart from "set" return the original register value. > + */ > + > +#if (_MIPS_SIM == _ABIO32) > +#define mips64_get_c0(selreg) \ > +__extension__ ({ \ > + __ll_shape_type __r; \ > + __asm__ __volatile ("mfc0 %0,$%2,%3\n" \ > + ".set push\n"\ > + ".set xpa\n"\ > + "mfhc0 %1,$%2,%3\n" \ > + ".set pop\n" \ > + : "=r" (__r.s.lo), \ > + "=r" (__r.s.hi) \ > + : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \ > + __r.ll; \ > +}) > +#else /* _MIPS_SIM==N32 || _MIPS_SIM==N64 */ > +#define mips64_get_c0(selreg) \ > +__extension__ ({ \ > + register unsigned long __r; \ > + __asm__ __volatile ("dmfc0 %0,$%1,%2" \ > + : "=d" (__r) \ > + : "JK" (selreg & 0x1F), "JK" (selreg >> 8)); \ > + __r; \ > +}) > +#endif > + > +#undef EHB > +#if defined (__MIPS_NO_IMPLICIT_EHB) > +#define EHB "" > +#else > +#define EHB "ehb\n" > +#endif > + > +#if (_MIPS_SIM == _ABIO32) > +#define mips64_set_c0(selreg, val) \ > +do { \ > + __ll_shape_type __ll; \ > + __ll.ll = (val); \ > + __asm__ __volatile (".set push \n"\ > + ".set noreorder\n"\ > + "mtc0 %z0,$%2,%3\n"\ > + ".set xpa\n"\ > + "mthc0 %z1,$%2,%3\n"\ > + EHB \ > + ".set pop" \ > + : \ > + : "dJ" ((reg32_t)(__ll.s.lo)),\ > + "dJ" ((reg32_t)(__ll.s.hi)),\ > + "JK" (selreg & 0x1F),\ > + "JK" (selreg >> 8)\ > + : "memory"); \ > +} while (0) > +#else /* _MIPS_SIM==N32 || _MIPS_SIM==N64 */ > +#define mips64_set_c0(selreg, val) \ > +do { \ > + __asm__ __volatile (".set push \n"\ > + ".set noreorder\n"\ > + "dmtc0 %z0,$%1,%2\n"\ > + EHB \ > + ".set pop" \ > + : \ > + : "dJ" ((reg64_t)(val)), "JK" (selreg & 0x1F),\ > + "JK" (selreg >> 8) \ > + : "memory"); \ > +} while (0) > +#endif > + > +#define mips64_xch_c0(selreg, val) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = mips64_get_c0 (selreg); \ > + mips64_set_c0 (selreg, val); \ > + __o; \ > +}) > + > +#define mips64_bc_c0(selreg, clr) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = mips64_get_c0 (selreg); \ > + mips64_set_c0 (selreg, __o & ~(clr)); \ > + __o; \ > +}) > + > +#define mips64_bs_c0(selreg, set) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = mips64_get_c0 (selreg); \ > + mips64_set_c0 (selreg, __o | (set)); \ > + __o; \ > +}) > + > +#define mips64_bcs_c0(selreg, clr, set) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = mips64_get_c0 (selreg); \ > + mips64_set_c0 (selreg, (__o & ~(clr)) | (set)); \ > + __o; \ > +}) > + > +/* MIPS64 Entry*, Index, PageMask registers */ > +#define mips64_setentryhi(x) mips64_set_c0(C0_ENTRYHI,x) > +#define mips64_getentryhi() mips64_get_c0(C0_ENTRYHI) > +#define mips64_setentrylo0(x) mips64_set_c0(C0_ENTRYLO0,x) > +#define mips64_getentrylo0() mips64_get_c0(C0_ENTRYLO0) > +#define mips64_setentrylo1(x) mips64_set_c0(C0_ENTRYLO1,x) > +#define mips64_getentrylo1() mips64_get_c0(C0_ENTRYLO1) > +#define mips64_setpagemask(x) mips64_set_c0(C0_PAGEMASK,x) > +#define mips64_getpagemask() mips64_get_c0(C0_PAGEMASK) > +#define mips64_setindex(x) mips32_set_c0(C0_INDEX,x) > +#define mips64_getindex(x) mips32_get_c0(C0_INDEX) > + > +/* MIPS64 Config3 and Config4 registers */ > +#define mips64_getconfig3() mips32_get_c0(C0_CONFIG3) > +#define mips64_setconfig3(x) mips32_set_c0(C0_CONFIG3,x) > +#define mips64_getconfig4() mips32_get_c0(C0_CONFIG4) > +#define mips64_setconfig4(x) mips32_set_c0(C0_CONFIG4,x) > + > +/* MIPS64 TagLo register */ > +#define mips64_getitaglo() mips64_get_c0(C0_TAGLO) /* alias > define */ > +#define mips64_setitaglo(x) mips64_set_c0(C0_TAGLO,x) /* alias > define */ > +#define mips64_xchitaglo(x) mips64_xch_c0(C0_TAGLO,x) /* alias > define */ > +#define mips64_getdtaglo() mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 2)) > +#define mips64_setdtaglo(x) mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 2),x) > +#define mips64_xchdtaglo(x) mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 2),x) > +#define mips64_gettaglo2() mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 4)) > +#define mips64_settaglo2(x) mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 4),x) > +#define mips64_xchtaglo2(x) mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 4),x) > + > +/* MIPS64 DataLo register */ > +#define mips64_getdatalo() mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 1)) > +#define mips64_setdatalo(x) mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 1),x) > +#define mips64_xchdatalo(x) mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 1),x) > +#define mips64_getidatalo() mips64_getdatalo() /* alias define */ > +#define mips64_setidatalo(x) mips64_setdatalo(x) /* alias define */ > +#define mips64_xchidatalo(x) mips64_xchdatalo(x) /* alias define */ > +#define mips64_getddatalo() mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 3)) > +#define mips64_setddatalo(x) mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 3),x) > +#define mips64_xchddatalo(x) mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 3),x) > +#define mips64_getdatalo2() mips64_get_c0(MIPS_C0_REGNAME(C0_TAGLO, 5)) > +#define mips64_setdatalo2(x) mips64_set_c0(MIPS_C0_REGNAME(C0_TAGLO, > 5),x) > +#define mips64_xchdatalo2(x) mips64_xch_c0(MIPS_C0_REGNAME(C0_TAGLO, > 5),x) > + > +/* CP0 TagHi register */ > +#define mips64_gettaghi() mips64_get_c0(C0_TAGHI) > +#define mips64_settaghi(x) mips64_set_c0(C0_TAGHI, x) > +#define mips64_xchtaghi(x) mips64_xch_c0(C0_TAGHI, x) > + > +/* CP0 WatchLo register */ > +#define mips64_getwatchlo() mips64_get_c0(C0_WATCHLO) > +#define mips64_setwatchlo(x) mips64_set_c0(C0_WATCHLO, x) > +#define mips64_xchwatchlo(x) mips64_xch_c0(C0_WATCHLO, x) > + > +#define _m64c0_mfc0(reg, sel) \ > +__extension__ ({ \ > + register unsigned long __r; \ > + __asm__ __volatile ("dmfc0 %0,$%1,%2" \ > + : "=d" (__r) \ > + : "JK" (reg), "JK" (sel)); \ > + __r; \ > +}) > + > +#define _m64c0_mtc0(reg, sel, val) \ > +do { \ > + __asm__ __volatile (".set push \n"\ > + ".set noreorder\n"\ > + "dmtc0 %z0,$%1,%2\n"\ > + "ehb\n" \ > + ".set pop" \ > + : \ > + : "dJ" ((reg64_t)(val)), "JK" (reg), "JK" (sel) \ > + : "memory"); \ > +} while (0) > + > +#define _m64c0_mxc0(reg, sel, val) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = _m64c0_mfc0 (reg, sel); \ > + _m64c0_mtc0 (reg, sel, val); \ > + __o; \ > +}) > + > +#define _m64c0_bcc0(reg, sel, clr) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = _m64c0_mfc0 (reg, sel); \ > + _m64c0_mtc0 (reg, sel, __o & ~(clr)); \ > + __o; \ > +}) > + > +#define _m64c0_bsc0(reg, sel, set) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = _m64c0_mfc0 (reg, sel); \ > + _m64c0_mtc0 (reg, sel, __o | (set)); \ > + __o; \ > +}) > + > +#define _m64c0_bcsc0(reg, sel, clr, set) \ > +__extension__ ({ \ > + register reg64_t __o; \ > + __o = _m64c0_mfc0 (reg, sel); \ > + _m64c0_mtc0 (reg, sel, (__o & ~(clr)) | (set)); \ > + __o; \ > +}) > + > +/* Define MIPS64 user-level intrinsics */ > +#include <mips/mips64.h> > + > +/* MIPS64-specific MMU interface */ > +#include <mips/m64tlb.h> > + > +#endif /* _M64C0_H_ */ > diff --git a/libgloss/mips/include/mips/m64tlb.h > b/libgloss/mips/include/mips/m64tlb.h > new file mode 100644 > index 000000000..86b0e58aa > --- /dev/null > +++ b/libgloss/mips/include/mips/m64tlb.h > @@ -0,0 +1,106 @@ > +/* > + * Copyright 2015-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +/* > + * m64tlb.h: MIPS64 / XPA TLB support functions > +*/ > +#ifndef _M64TLB_H_ > +#define _M64TLB_H_ > + > +#if __mips != 32 && __mips != 64 > +#error use -mips32 or -mips64 option with this file > +#endif > + > +#include <mips/notlb.h> > + > +#ifndef __ASSEMBLER__ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifdef __mips16 > +# define _MIPS_M64TLB_NOMIPS16 __attribute__((nomips16)) > +#else > +# define _MIPS_M64TLB_NOMIPS16 > +#endif > + > +typedef unsigned long long tlbhi64_t; > +typedef unsigned long long tlblo64_t; > +// Returns the size of the TLB. > +_MIPS_M64TLB_NOMIPS16 > +int m64_tlb_size (void); > + > +// Probes the TLB for an entry matching hi, and if present invalidates it. > +_MIPS_M64TLB_NOMIPS16 > +void m64_tlbinval (tlbhi64_t hi); > + > +// Invalidate the whole TLB. > +_MIPS_M64TLB_NOMIPS16 > +void m64_tlbinvalall (void); > + > +// Reads the TLB entry with specified by index, and returns the EntryHi, > +// EntryLo0, EntryLo1 and PageMask parts in *phi, *plo0, *plo1 and *pmsk > +// respectively. > +_MIPS_M64TLB_NOMIPS16 > +void m64_tlbri2 (tlbhi64_t *phi, tlblo64_t *plo0, tlblo64_t *plo1, > + unsigned long long *pmsk, int index); > + > +// Writes hi, lo0, lo1 and msk into the TLB entry specified by index. > +_MIPS_M64TLB_NOMIPS16 > +void m64_tlbwi2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1, > + unsigned long long msk, int index); > + > +// Writes hi, lo0, lo1 and msk into the TLB entry specified by the > +// Random register. > +_MIPS_M64TLB_NOMIPS16 > +void m64_tlbwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1, > + unsigned long long msk); > + > +// Probes the TLB for an entry matching hi and returns its index, or -1 if > +// not found. If found, then the EntryLo0, EntryLo1 and PageMask parts of > the > +// entry are also returned in *plo0, *plo1 and *pmsk respectively > +_MIPS_M64TLB_NOMIPS16 > +int m64_tlbprobe2 (tlbhi64_t hi, tlblo64_t *plo0, tlblo64_t *plo1, > + unsigned long long *pmsk); > + > +// Probes the TLB for an entry matching hi and if present rewrites that > entry, > +// otherwise updates a random entry. A safe way to update the TLB. > +_MIPS_M64TLB_NOMIPS16 > +int m64_tlbrwr2 (tlbhi64_t hi, tlblo64_t lo0, tlblo64_t lo1, > + unsigned long long msk); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __ASSEMBLER__ */ > + > +#endif /* _M64TLB_H_ */ > diff --git a/libgloss/mips/include/mips/mips32.h > b/libgloss/mips/include/mips/mips32.h > new file mode 100644 > index 000000000..20e31a2e7 > --- /dev/null > +++ b/libgloss/mips/include/mips/mips32.h > @@ -0,0 +1,177 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS32_H_ > +#define _MIPS32_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifndef __ASSEMBLER__ > + > +#if ! __mips16 > + > +/* C interface to clz/clo instructions */ > + > +/* count leading zeros */ > +# define mips_clz(x) __builtin_clz (x) > + > +/* count trailing zeros */ > +# define mips_ctz(x) __builtin_ctz (x) > + > +#define mips_clo(x) __extension__({ \ > + unsigned int __x = (x); \ > + unsigned int __v; \ > + __asm__ ("clo %0,%1" : "=d" (__v) : "d" (__x)); \ > + __v; \ > +}) > + > +#ifndef __mips64 > + > +/* Simulate 64-bit count leading zeroes */ > +#if !defined(mips_dclz) > +#define mips_dclz(x) __extension__({ \ > + unsigned long long __x = (x); \ > + unsigned int __hx = (__x >> 32); \ > + __hx ? mips_clz(__hx) : 32 + mips_clz(__x); \ > +}) > +#endif > + > +/* Simulate 64-bit count leading ones */ > +#if !defined(mips_dclo) > +#define mips_dclo(x) __extension__({ \ > + unsigned long long __x = (x); \ > + unsigned int __hx = (__x >> 32); \ > + (~__hx) ? mips_clo(__hx) : 32 + mips_clo(__x); \ > +}) > +#endif > + > +/* Simulate 64-bit count trailing zeroes */ > +#if !defined(mips_dctz) > +#define mips_dctz(x) __extension__({ \ > + unsigned long long __dx = (x); \ > + unsigned int __ldx = __dx; \ > + unsigned int __hdx = __dx >> 32; \ > + __ldx ? mips_ctz(__ldx) : (63 ^ mips_clz(__hdx & -__hdx)); \ > + }) > +#endif > + > +#endif > + > +/* MIPS32r2 wsbh opcode */ > +#define _mips32r2_wsbh(x) __extension__({ \ > + unsigned int __x = (x), __v; \ > + __asm__ ("wsbh %0,%1" \ > + : "=d" (__v) \ > + : "d" (__x)); \ > + __v; \ > +}) > + > +/* MIPS32r2 byte-swap word */ > +#define _mips32r2_bswapw(x) __extension__({ \ > + unsigned int __x = (x), __v; \ > + __asm__ ("wsbh %0,%1; rotr %0,16" \ > + : "=d" (__v) \ > + : "d" (__x)); \ > + __v; \ > +}) > + > +/* MIPS32r2 insert bits */ > +#define _mips32r2_ins(tgt,val,pos,sz) __extension__({ \ > + unsigned int __t = (tgt), __v = (val); \ > + __asm__ ("ins %0,%z1,%2,%3" \ > + : "+d" (__t) \ > + : "dJ" (__v), "I" (pos), "I" (sz)); \ > + __t; \ > +}) > + > +/* MIPS32r2 extract bits */ > +#define _mips32r2_ext(x,pos,sz) __extension__({ \ > + unsigned int __x = (x), __v; \ > + __asm__ ("ext %0,%z1,%2,%3" \ > + : "=d" (__v) \ > + : "dJ" (__x), "I" (pos), "I" (sz)); \ > + __v; \ > +}) > + > +#if __mips_isa_rev < 6 > + > +/* MIPS32r2 jr.hb */ > +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 > +#define mips32_jr_hb() __asm__ __volatile__( \ > + "bltzal $0,0f\n" \ > +"0: addiu $31,1f-0b\n" \ > +" jr.hb $31\n" \ > +"1:" \ > + : : : "$31") > +#elif _MIPS_SIM == _ABI64 > +#define mips32_jr_hb() __asm__ __volatile__( \ > + "bltzal $0,0f\n" \ > +"0: daddiu $31,1f-0b\n" \ > +" jr.hb $31\n" \ > +"1:" \ > + : : : "$31") > +#else > +#error Unknown ABI > +#endif > + > +#else /* __mips_isa_rev < 6 */ > + > +/* MIP32r6 jr.hb */ > +#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32 > +#define mips32_jr_hb() __asm__ __volatile__( \ > + "auipc $24,%pcrel_hi(1f)\n" \ > + "addiu $24,%pcrel_lo(1f + 4)\n" \ > + "jr.hb $24\n" \ > +"1:" \ > + : : : "$24") > +#elif _MIPS_SIM == _ABI64 > +#define mips32_jr_hb() __asm__ __volatile__( \ > + "auipc $24,%pcrel_hi(1f)\n" \ > + "daddiu $24,%pcrel_lo(1f + 4)\n" \ > + "jr.hb $24\n" \ > +"1:" \ > + : : : "$24") > +#else > +#error Unknown ABI > +#endif > + > +#endif /* __mips_isa_rev < 6 */ > + > +#endif /* ! __mips16 */ > + > +#endif /* __ASSEMBLER__ */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _MIPS32_H_ */ > diff --git a/libgloss/mips/include/mips/mips64.h > b/libgloss/mips/include/mips/mips64.h > new file mode 100644 > index 000000000..03b608e2e > --- /dev/null > +++ b/libgloss/mips/include/mips/mips64.h > @@ -0,0 +1,116 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS64_H_ > +#define _MIPS64_H_ > + > +#include <mips/mips32.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifndef __ASSEMBLER__ > + > +#if __mips == 64 && ! __mips16 > + > +/* 64-bit count leading zeroes */ > +#if !defined(mips_dclz) > +# define mips_dclz(x) __builtin_clzll (x) > +#endif > + > +/* 64-bit count trailing zeroes */ > +#if !defined(mips_dctz) > +# define mips_dctz(x) __builtin_ctzll (x) > +#endif > + > +#if !defined(mips_dclo) > +#define mips_dclo(x) __extension__({ \ > + unsigned long long __x = (x); \ > + unsigned int __v; \ > + __asm__ ("dclo %0,%1" : "=d" (__v) : "d" (__x)); \ > + __v; \ > +}) > +#endif > + > +/* MIPS64r2 dshd opcode */ > +#define _mips64r2_dshd(x) __extension__({ \ > + unsigned long long __x = (x), __v; \ > + __asm__ ("dshd %0,%1" \ > + : "=d" (__v) \ > + : "d" (__x)); \ > + __v; \ > +}) > + > +/* MIPS64r2 dsbh opcode */ > +#define _mips64r2_dsbh(x) __extension__({ \ > + unsigned long long __x = (x), __v; \ > + __asm__ ("dsbh %0,%1" \ > + : "=d" (__v) \ > + : "d" (__x)); \ > + __v; \ > +}) > + > +/* MIPS64r2 byte-swap doubleword */ > +#define _mips64r2_bswapd(x) __extension__({ \ > + unsigned long long __x = (x), __v; \ > + __asm__ ("dsbh %0,%1; dshd %0,%0" \ > + : "=d" (__v) \ > + : "d" (__x)); \ > + __v; \ > +}) > + > +/* MIPS64r2 insert bits */ > +#define _mips64r2_dins(tgt,val,pos,sz) __extension__({ \ > + unsigned long long __t = (tgt), __v = (val); \ > + __asm__ ("dins %0,%z1,%2,%3" \ > + : "+d" (__t) \ > + : "dJ" (__v), "I" (pos), "I" (sz)); \ > + __t; \ > +}) > + > +/* MIPS64r2 extract bits */ > +#define _mips64r2_dext(x,pos,sz) __extension__({ \ > + unsigned long long __x = (x), __v; \ > + __asm__ ("dext %0,%z1,%2,%3" \ > + : "=d" (__v) \ > + : "dJ" (__x), "I" (pos), "I" (sz)); \ > + __v; \ > +}) > + > +#endif /* __mips == 64 && ! __mips16 */ > + > +#endif /* !__ASSEMBLER__ */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _MIPS64_H_ */ > diff --git a/libgloss/mips/include/mips/mt.h > b/libgloss/mips/include/mips/mt.h > new file mode 100644 > index 000000000..91a75f28c > --- /dev/null > +++ b/libgloss/mips/include/mips/mt.h > @@ -0,0 +1,521 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_MT_H_ > +#define _MIPS_MT_H_ > + > +#include <mips/m32c0.h> > +#include <mips/mips32.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* > + * MIPS32 MVPControl Register (CP0 Register 0, Select 1) > + */ > +#define MVPCONTROL_EVP 0x00000001 /* Enable Virtual Processors */ > +#define MVPCONTROL_VPC 0x00000002 /* VPE Configuration State */ > +#define MVPCONTROL_STLB 0x00000004 /* Share TLBS */ > +#define MVPCONTROL_CPA 0x00000008 /* Cache Partitioning Active */ > + > +/* > + * MIPS32 MVPConf0 Register (CP0 Register 0, Select 2) > + */ > +#define MVPCONF0_PTC 0x000000ff > +#define MVPCONF0_PTC_SHIFT 0 > +#define MVPCONF0_PVPE 0x00003c00 > +#define MVPCONF0_PVPE_SHIFT 10 > +#define MVPCONF0_TCA 0x00008000 > +#define MVPCONF0_PTLBE 0x03ff0000 > +#define MVPCONF0_PTLBE_SHIFT 16 > +#define MVPCONF0_TLBS 0x20000000 > +#define MVPCONF0_M 0x80000000 > + > +/* > + * MIPS32 MVPConf1 Register (CP0 Register 0, Select 3) > + */ > +#define MVPCONF1_PCP1 0x000000ff > +#define MVPCONF1_PCP1_SHIFT 0 > +#define MVPCONF1_PCP2 0x0003fc00 > +#define MVPCONF1_PCP2_SHIFT 10 > +#define MVPCONF1_PCX 0x0ff00000 > +#define MVPCONF1_PCX_SHIFT 20 > +#define MVPCONF1_C1F 0x40000000 > +#define MVPCONF1_C1M 0x80000000 > + > +/* > + * MIPS32 VPEControl Register (CP0 Register 1, Select 1) > + */ > +#define VPECONTROL_TARGTC 0x000000ff > +#define VPECONTROL_TARGTC_SHIFT 0 > +#define VPECONTROL_TARGVPE 0x00003c00 > +#define VPECONTROL_TARGVPE_SHIFT 10 > +#define VPECONTROL_TE 0x00008000 > +#define VPECONTROL_EXCPT 0x00070000 > +#define VPECONTROL_EXCPT_SHIFT 16 > +#define VPECONTROL_GSI 0x00100000 > +#define VPECONTROL_YSI 0x00200000 > + > +/* > + * MIPS32 VPEConf0 Register (CP0 Register 1, Select 2) > + */ > +#define VPECONF0_VPA 0x00000001 > +#define VPECONF0_MVP 0x00000002 > +#define VPECONF0_XTC 0x1fe00000 > +#define VPECONF0_XTC_SHIFT 21 > +#define VPECONF0_M 0x80000000 > + > +/* > + * MIPS32 VPEConf1 Register (CP0 Register 1, Select 3) > + */ > +#define VPECONF1_NCP1 0x000000ff > +#define VPECONF1_NCP1_SHIFT 0 > +#define VPECONF1_NCP2 0x0003fc00 > +#define VPECONF1_NCP2_SHIFT 10 > +#define VPECONF1_NCX 0x0ff00000 > +#define VPECONF1_NCX_SHIFT 20 > + > +/* > + * MIPS32 YQMask Register (CP0 Register 1, Select 4) > + */ > +#define YQMASK_MASK 0x7fffffff > +#define YQMASK_MASK_SHIFT 0 > + > +/* > + * MIPS32 VPEOpt Register (CP0 Register 1, Select 7) > + */ > +#define VPEOPT_DWX0 0x00000001 > +#define VPEOPT_DWX1 0x00000002 > +#define VPEOPT_DWX2 0x00000004 > +#define VPEOPT_DWX3 0x00000008 > +#define VPEOPT_DWX4 0x00000010 > +#define VPEOPT_DWX5 0x00000020 > +#define VPEOPT_DWX6 0x00000040 > +#define VPEOPT_DWX7 0x00000080 > +#define VPEOPT_DWX 0x000000ff > +#define VPEOPT_DWX_SHIFT 0 > +#define VPEOPT_IWX0 0x00000100 > +#define VPEOPT_IWX1 0x00000200 > +#define VPEOPT_IWX2 0x00000400 > +#define VPEOPT_IWX3 0x00000800 > +#define VPEOPT_IWX4 0x00001000 > +#define VPEOPT_IWX5 0x00002000 > +#define VPEOPT_IWX6 0x00004000 > +#define VPEOPT_IWX7 0x00008000 > +#define VPEOPT_IWX 0x0000ff00 > +#define VPEOPT_IWX_SHIFT 8 > + > +/* > + * MIPS32 TCStatus Register (CP0 Register 2, Select 1) > + */ > +#define TCSTATUS_TASID 0x000000ff > +#define TCSTATUS_TASID_SHIFT 0 > +#define TCSTATUS_IXMT 0x00000400 > +#define TCSTATUS_TKSU 0x00001800 > +#define TCSTATUS_TKSU_SHIFT 11 > +#define TCSTATUS_A 0x00002000 > +#define TCSTATUS_DA 0x00008000 > +#define TCSTATUS_IMPL 0x000f0000 > +#define TCSTATUS_IMPL_SHIFT 16 > +#define TCSTATUS_DT 0x00100000 > +#define TCSTATUS_TDS 0x00200000 > +#define TCSTATUS_TSST 0x00400000 > +#define TCSTATUS_RNST 0x01800000 > +#define TCSTATUS_RNST_SHIFT 23 > +#define TCSTATUS_TCU0 0x10000000 > +#define TCSTATUS_TCU1 0x20000000 > +#define TCSTATUS_TCU2 0x40000000 > +#define TCSTATUS_TCU3 0x80000000 > + > +/* > + * MIPS32 TCBind Register (CP0 Register 2, Select 2) > + */ > +#define TCBIND_CURVPE 0x0000000f > +#define TCBIND_CURVPE_SHIFT 0 > +#define TCBIND_CURTC 0x1fe00000 > +#define TCBIND_CURTC_SHIFT 21 > + > +/* > + * MIPS32 TCHalt Register (CP0 Register 2, Select 4) > + */ > +#define TCHALT_H 0x00000001 > + > +/* > + * MIPS32 SRSConf0 Register (CP0 Register 6, Select 1) > + */ > +#define SRSCONF0_SRS1 0x000003ff > +#define SRSCONF0_SRS1_SHIFT 0 > +#define SRSCONF0_SRS2 0x000ffc00 > +#define SRSCONF0_SRS2_SHIFT 10 > +#define SRSCONF0_SRS3 0x3ff00000 > +#define SRSCONF0_SRS3_SHIFT 20 > +#define SRSCONF0_M 0x80000000 > + > +/* > + * MIPS32 SRSConf1 Register (CP0 Register 6, Select 2) > + */ > +#define SRSCONF1_SRS4 0x000003ff > +#define SRSCONF1_SRS4_SHIFT 0 > +#define SRSCONF1_SRS5 0x000ffc00 > +#define SRSCONF1_SRS5_SHIFT 10 > +#define SRSCONF1_SRS6 0x3ff00000 > +#define SRSCONF1_SRS6_SHIFT 20 > +#define SRSCONF1_M 0x80000000 > + > +/* > + * MIPS32 SRSConf2 Register (CP0 Register 6, Select 3) > + */ > +#define SRSCONF2_SRS7 0x000003ff > +#define SRSCONF2_SRS7_SHIFT 0 > +#define SRSCONF2_SRS8 0x000ffc00 > +#define SRSCONF2_SRS8_SHIFT 10 > +#define SRSCONF2_SRS9 0x3ff00000 > +#define SRSCONF2_SRS9_SHIFT 20 > +#define SRSCONF2_M 0x80000000 > + > +/* > + * MIPS32 SRSConf3 Register (CP0 Register 6, Select 4) > + */ > +#define SRSCONF3_SRS10 0x000003ff > +#define SRSCONF3_SRS10_SHIFT 0 > +#define SRSCONF3_SRS11 0x000ffc00 > +#define SRSCONF3_SRS11_SHIFT 10 > +#define SRSCONF3_SRS12 0x3ff00000 > +#define SRSCONF3_SRS12_SHIFT 20 > +#define SRSCONF3_M 0x80000000 > + > +/* > + * MIPS32 SRSConf4 Register (CP0 Register 6, Select 5) > + */ > +#define SRSCONF4_SRS13 0x000003ff > +#define SRSCONF4_SRS13_SHIFT 0 > +#define SRSCONF4_SRS14 0x000ffc00 > +#define SRSCONF4_SRS14_SHIFT 10 > +#define SRSCONF4_SRS15 0x3ff00000 > +#define SRSCONF4_SRS15_SHIFT 20 > + > +/* > + * MIPS32 Config3 Register (CP0 Register 16, Select 3) > + * New fields for MT > + */ > +#define CFG3_MT 0x00000004 > + > +#ifdef __ASSEMBLER__ > + > +/* > + * MT Coprocessor 0 register numbers > + */ > +#define C0_MVPCONTROL $0,1 > +#define C0_MVPCONF0 $0,2 > +#define C0_MVPCONF1 $0,3 > +#define C0_VPECONTROL $1,1 > +#define C0_VPECONF0 $1,2 > +#define C0_VPECONF1 $1,3 > +#define C0_YQMASK $1,4 > +#define C0_VPESCHEDULE $1,5 > +#define C0_VPESCHEFBACK $1,6 > +#define C0_VPEOPT $1,7 > +#define C0_TCSTATUS $2,1 > +#define C0_TCBIND $2,2 > +#define C0_TCRESTART $2,3 > +#define C0_TCHALT $2,4 > +#define C0_TCCONTEXT $2,5 > +#define C0_TCSCHEDULE $2,6 > +#define C0_TCSCHEFBACK $2,7 > +#define C0_SRSCONF0 $6,1 > +#define C0_SRSCONF1 $6,2 > +#define C0_SRSCONF2 $6,3 > +#define C0_SRSCONF3 $6,4 > +#define C0_SRSCONF4 $6,5 > + > +#else > + > +#define mips32_getmvpcontrol() _m32c0_mfc0(0,1) > +#define mips32_setmvpcontrol(x) _m32c0_mtc0(0,1,x) > +#define mips32_xchmvpcontrol(x) _m32c0_mxc0(0,1,x) > + > +#define mips32_getmvpconf0() _m32c0_mfc0(0,2) > +#define mips32_setmvpconf0(x) _m32c0_mtc0(0,2,x) > +#define mips32_xchmvpconf0(x) _m32c0_mxc0(0,2,x) > + > +#define mips32_getmvpconf1() _m32c0_mfc0(0,3) > +#define mips32_setmvpconf1(x) _m32c0_mtc0(0,3,x) > +#define mips32_xchmvpconf1(x) _m32c0_mxc0(0,3,x) > + > +#define mips32_getvpecontrol() _m32c0_mfc0(1,1) > +#define mips32_setvpecontrol(x) _m32c0_mtc0(1,1,x) > +#define mips32_xchvpecontrol(x) _m32c0_mxc0(1,1,x) > + > +#define mips32_getvpeconf0() _m32c0_mfc0(1,2) > +#define mips32_setvpeconf0(x) _m32c0_mtc0(1,2,x) > +#define mips32_xchvpeconf0(x) _m32c0_mxc0(1,2,x) > + > +#define mips32_getvpeconf1() _m32c0_mfc0(1,3) > +#define mips32_setvpeconf1(x) _m32c0_mtc0(1,3,x) > +#define mips32_xchvpeconf1(x) _m32c0_mxc0(1,3,x) > + > +#define mips32_getyqmask() _m32c0_mfc0(1,4) > +#define mips32_setyqmask(x) _m32c0_mtc0(1,4,x) > +#define mips32_xchyqmask(x) _m32c0_mxc0(1,4,x) > + > +#define mips32_getvpeschedule() _m32c0_mfc0(1,5) > +#define mips32_setvpeschedule(x) _m32c0_mtc0(1,5,x) > +#define mips32_xchvpeschedule(x) _m32c0_mxc0(1,5,x) > + > +#define mips32_getvpeschefback() _m32c0_mfc0(1,6) > +#define mips32_setvpeschefback(x) _m32c0_mtc0(1,6,x) > +#define mips32_xchvpeschefback(x) _m32c0_mxc0(1,6,x) > + > +#define mips32_getvpeopt() _m32c0_mfc0(1,7) > +#define mips32_setvpeopt(x) _m32c0_mtc0(1,7,x) > +#define mips32_xchvpeopt(x) _m32c0_mxc0(1,7,x) > + > +#define mips32_gettcstatus() _m32c0_mfc0(2,1) > +#define mips32_settcstatus(x) _m32c0_mtc0(2,1,x) > +#define mips32_xchtcstatus(x) _m32c0_mxc0(2,1,x) > + > +#define mips32_gettcbind() _m32c0_mfc0(2,2) > +#define mips32_settcbind(x) _m32c0_mtc0(2,2,x) > +#define mips32_xchtcbind(x) _m32c0_mxc0(2,2,x) > + > +#define mips32_gettcrestart() _m32c0_mfc0(2,3) > +#define mips32_settcrestart(x) _m32c0_mtc0(2,3,x) > +#define mips32_xchtcrestart(x) _m32c0_mxc0(2,3,x) > + > +#define mips32_gettchalt() _m32c0_mfc0(2,4) > +#define mips32_settchalt(x) _m32c0_mtc0(2,4,x) > +#define mips32_xchtchalt(x) _m32c0_mxc0(2,4,x) > + > +#define mips32_gettccontext() _m32c0_mfc0(2,5) > +#define mips32_settccontext(x) _m32c0_mtc0(2,5,x) > +#define mips32_xchtccontext(x) _m32c0_mxc0(2,5,x) > + > +#define mips32_gettcschedule() _m32c0_mfc0(2,6) > +#define mips32_settcschedule(x) _m32c0_mtc0(2,6,x) > +#define mips32_xchtcschedule(x) _m32c0_mxc0(2,6,x) > + > +#define mips32_gettcschefback() _m32c0_mfc0(2,7) > +#define mips32_settcschefback(x) _m32c0_mtc0(2,7,x) > +#define mips32_xchtcschefback(x) _m32c0_mxc0(2,7,x) > + > +#define mips32_getsrsconf0() _m32c0_mfc0(6,1) > +#define mips32_setsrsconf0(x) _m32c0_mtc0(6,1,x) > +#define mips32_xchsrsconf0(x) _m32c0_mxc0(6,1,x) > + > +#define mips32_getsrsconf1() _m32c0_mfc0(6,2) > +#define mips32_setsrsconf1(x) _m32c0_mtc0(6,2,x) > +#define mips32_xchsrsconf1(x) _m32c0_mxc0(6,2,x) > + > +#define mips32_getsrsconf2() _m32c0_mfc0(6,3) > +#define mips32_setsrsconf2(x) _m32c0_mtc0(6,3,x) > +#define mips32_xchsrsconf2(x) _m32c0_mxc0(6,3,x) > + > +#define mips32_getsrsconf3() _m32c0_mfc0(6,4) > +#define mips32_setsrsconf3(x) _m32c0_mtc0(6,4,x) > +#define mips32_xchsrsconf3(x) _m32c0_mxc0(6,4,x) > + > +#define mips32_getsrsconf4() _m32c0_mfc0(6,5) > +#define mips32_setsrsconf4(x) _m32c0_mtc0(6,5,x) > +#define mips32_xchsrsconf4(x) _m32c0_mxc0(6,5,x) > + > +#if !__mips16 > +/* Access to other VPE/TC registers */ > + > +/* move from gpr */ > +#define _m32c0_mftgpr(rt) \ > +__extension__ ({ \ > + unsigned long __res; \ > + __asm__ __volatile__( \ > + ".set push\n" \ > + ".set noat\n" \ > + "mftgpr\t%0,$" #rt "\n" \ > + ".set pop\n" \ > + : "=d" (__res)); \ > + __res; \ > +}) > + > +/* move to gpr */ > +#define _m32c0_mttgpr(rd,v) \ > +do { \ > + __asm__ __volatile__( \ > + ".set push\n" \ > + ".set noat\n" \ > + "mttgpr\t%z0,$" #rd "\n" \ > + ".set pop\n" \ > + : : "dJ" (v)); \ > +} while (0) > + > +/* move from cp0 */ > +#define _m32c0_mftc0(rt,sel) \ > +__extension__ ({ \ > + unsigned long __res; \ > + __asm__ __volatile__( \ > + "mftc0\t%0,$" #rt "," #sel \ > + : "=d" (__res)); \ > + __res; \ > +}) > + > +/* move to cp0 */ > +#define _m32c0_mttc0(rd,sel,v) \ > +do { \ > + __asm__ __volatile__( \ > + "%(mttc0\t %z0,$" #rd "," #sel "; ehb%)" \ > + : : "dJ" (v)); \ > +} while (0) > +#endif /* ! __mips16 */ > + > +/* > + * targeted VPE register macros > + */ > +#define mips32_mt_settarget(tc) \ > + mips32_setvpecontrol ( \ > + (mips32_getvpecontrol () & ~(VPECONTROL_TARGTC)) \ > + | ((tc) << VPECONTROL_TARGTC_SHIFT)) > + > +#define mips32_mt_gettarget() \ > + ((mips32_getvpecontrol () & (VPECONTROL_TARGTC)) \ > + >> VPECONTROL_TARGTC_SHIFT) > + > +/* > + * Before using any mips32_mt_ macros you should ensure the > + * destination VPE and TC are set with a call to mips32_mt_settarget() > + */ > + > +/* > + * Non-MT CP0 registers > + */ > +#define mips32_mt_getc0status() _m32c0_mftc0(12, 0) > +#define mips32_mt_setc0status(val) _m32c0_mttc0(12, 0, val) > +#define mips32_mt_getc0cause() _m32c0_mftc0(13, 0) > +#define mips32_mt_setc0cause(val) _m32c0_mttc0(13, 0, val) > +#define mips32_mt_getc0config() _m32c0_mftc0(16, 0) > +#define mips32_mt_setc0config(val) _m32c0_mttc0(16, 0, val) > +#define mips32_mt_getc0config1() _m32c0_mftc0(16, 1) > +#define mips32_mt_setc0config1(val) _m32c0_mttc0(16, 1, val) > +#define mips32_mt_getc0ebase() _m32c0_mftc0(15, 1) > +#define mips32_mt_setc0ebase(val) _m32c0_mttc0(15, 1, val) > + > +/* > + * Non-MT GPR registers > + */ > +#define mips32_mt_getsp() _m32c0_mftgpr(29) > +#define mips32_mt_setsp(val) _m32c0_mttgpr(29, val) > +#define mips32_mt_getgp() _m32c0_mftgpr(28) > +#define mips32_mt_setgp(val) _m32c0_mttgpr(28, val) > + > +/* > + * VPE > + */ > +#define mips32_mt_getvpecontrol() _m32c0_mftc0(1, 1) > +#define mips32_mt_setvpecontrol(val) _m32c0_mttc0(1, 1, val) > +#define mips32_mt_getvpeconf0() _m32c0_mftc0(1, 2) > +#define mips32_mt_setvpeconf0(val) _m32c0_mttc0(1, 2, val) > + > +/* > + * TC > + */ > +#define mips32_mt_gettcstatus() _m32c0_mftc0(2, 1) > +#define mips32_mt_settcstatus(val) _m32c0_mttc0(2, 1, val) > +#define mips32_mt_gettcbind() _m32c0_mftc0(2, 2) > +#define mips32_mt_settcbind(val) _m32c0_mttc0(2, 2, val) > +#define mips32_mt_gettcrestart() _m32c0_mftc0(2, 3) > +#define mips32_mt_settcrestart(val) _m32c0_mttc0(2, 3, val) > +#define mips32_mt_gettchalt() _m32c0_mftc0(2, 4) > +#define mips32_mt_settchalt(val) _m32c0_mttc0(2, 4, val) > +#define mips32_mt_gettccontext() _m32c0_mftc0(2, 5) > +#define mips32_mt_settccontext(val) _m32c0_mttc0(2, 5, val) > + > + > +/* > + * MT Intrinsics > + */ > +#define mips_mt_fork(a, pv, cv) \ > +__extension__ ({ \ > + void * __a = (a); \ > + unsigned int __cv = (cv); \ > + unsigned int __res = (pv); \ > + __asm__ __volatile (".set push; .set mt; fork %0,%1,%z2; .set pop" \ > + : "+d" (__res) \ > + : "d" (__a), "dJ" (__cv)); \ > + __res; \ > +}) > + > +#define mips_mt_yield(yq) \ > +__extension__ ({ \ > + unsigned int __yq = (yq); \ > + unsigned int __res; \ > + __asm__ __volatile (".set push; .set mt; yield %0,%z1; .set pop" \ > + : "=d" (__res) \ > + : "dJ" (__yq)); \ > + __res; \ > +}) > + > +#define mips_mt_dmt() \ > +__extension__ ({ \ > + unsigned int __res; \ > + __asm__ __volatile (".set push; .set mt; dmt %0; .set pop" \ > + : "=d" (__res)); \ > + mips32_jr_hb(); \ > + __res & VPECONTROL_TE; \ > +}) > + > +#define mips_mt_emt() \ > +__extension__ ({ \ > + unsigned int __res; \ > + __asm__ __volatile (".set push; .set mt; emt %0; ehb; .set pop" \ > + : "=d" (__res)); \ > + __res & VPECONTROL_TE; \ > +}) > + > +#define mips_mt_dvpe() \ > +__extension__ ({ \ > + unsigned int __res; \ > + __asm__ __volatile (".set push; .set mt; dvpe %0; .set pop" \ > + : "=d" (__res)); \ > + mips32_jr_hb(); \ > + __res & MVPCONTROL_EVP; \ > +}) > + > +#define mips_mt_evpe() \ > +__extension__ ({ \ > + unsigned int __res; \ > + __asm__ __volatile (".set push; .set mt; evpe %0; ehb; .set pop" \ > + : "=d" (__res)); \ > + __res & MVPCONTROL_EVP; \ > +}) > + > +#endif /* __ASSEMBLER__ */ > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _MIPS_MT_H_ */ > diff --git a/libgloss/mips/include/mips/notlb.h > b/libgloss/mips/include/mips/notlb.h > new file mode 100644 > index 000000000..2a6c1b439 > --- /dev/null > +++ b/libgloss/mips/include/mips/notlb.h > @@ -0,0 +1,115 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _NOTLB_H_ > +#define _NOTLB_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#ifndef ROM_BASE > +#define ROM_BASE 0xbfc00000 /* standard ROM base address */ > +#endif > + > +#ifdef __ASSEMBLER__ > + > +/* > + * Stub 32-bit memory regions > + */ > +#define KSEG0_BASE 0x80000000 > +#define KSEG1_BASE 0xa0000000 > +#define KSEG0_SIZE 0x20000000 > +#define KSEG1_SIZE 0x20000000 > +#define RVEC_BASE ROM_BASE > + > +/* > + * Translate a kernel address in KSEG0 or KSEG1 to a real > + * physical address and back. > + */ > +#define KVA_TO_PA(v) ((v) & 0x1fffffff) > +#define PA_TO_KVA0(pa) ((pa) | 0x80000000) > +#define PA_TO_KVA1(pa) ((pa) | 0xa0000000) > + > +/* translate between KSEG0 and KSEG1 addresses */ > +#define KVA0_TO_KVA1(v) ((v) | 0x20000000) > +#define KVA1_TO_KVA0(v) ((v) & ~0x20000000) > + > +#else /* __ASSEMBLER__ */ > +/* > + * Standard address types > + */ > +#ifndef _PADDR_T_DEFINED_ > +typedef unsigned long paddr_t; /* a physical address */ > +#define _PADDR_T_DEFINED_ > +#endif > +#ifndef _VADDR_T_DEFINED_ > +typedef unsigned long vaddr_t; /* a virtual address */ > +#define _VADDR_T_DEFINED_ > +#endif > + > +/* > + * Stub 32-bit memory regions > + */ > +#define KSEG0_BASE ((void *)0x80000000) > +#define KSEG1_BASE ((void *)0xa0000000) > +#define KSEG0_SIZE 0x20000000u > +#define KSEG1_SIZE 0x20000000u > + > +#define RVEC_BASE ((void *)ROM_BASE) /* reset vector base */ > + > +/* > + * Translate a kernel virtual address in KSEG0 or KSEG1 to a real > + * physical address and back. > + */ > +#define KVA_TO_PA(v) ((paddr_t)(v) & 0x1fffffff) > +#define PA_TO_KVA0(pa) ((void *) ((pa) | 0x80000000)) > +#define PA_TO_KVA1(pa) ((void *) ((pa) | 0xa0000000)) > + > +/* translate between KSEG0 and KSEG1 virtual addresses */ > +#define KVA0_TO_KVA1(v) ((void *) ((unsigned)(v) | 0x20000000)) > +#define KVA1_TO_KVA0(v) ((void *) ((unsigned)(v) & ~0x20000000)) > + > +/* Test for KSEGS */ > +#define IS_KVA(v) ((int)(v) < 0) > +#define IS_KVA0(v) (((unsigned)(v) >> 29) == 0x4) > +#define IS_KVA1(v) (((unsigned)(v) >> 29) == 0x5) > +#define IS_KVA01(v) (((unsigned)(v) >> 30) == 0x2) > + > +/* convert register type to address and back */ > +#define VA_TO_REG(v) ((long)(v)) /* sign-extend 32->64 */ > +#define REG_TO_VA(v) ((void *)(long)(v)) /* truncate 64->32 */ > + > +#endif /* __ASSEMBLER__ */ > + > +#ifdef __cplusplus > +} > +#endif > +#endif /* _NOTLB_H_*/ > diff --git a/libgloss/mips/include/mips/prid.h > b/libgloss/mips/include/mips/prid.h > new file mode 100644 > index 000000000..2bf017cf1 > --- /dev/null > +++ b/libgloss/mips/include/mips/prid.h > @@ -0,0 +1,130 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_PRID_H_ > +#define _MIPS_PRID_H_ > + > +/* > + * MIPS CPU types > + */ > +#define PRID_R2000 0x01 /* MIPS R2000 CPU > ISA I */ > +#define PRID_R3000 0x02 /* MIPS R3000 CPU > ISA I */ > +#define PRID_R6000 0x03 /* MIPS R6000 CPU > ISA II */ > +#define PRID_R4000 0x04 /* MIPS R4000/4400 CPU > ISA III */ > +#define PRID_LR33K 0x05 /* LSI Logic R3000 derivate ISA I */ > +#define PRID_R6000A 0x06 /* MIPS R6000A CPU > ISA II */ > +#define PRID_R3IDT 0x07 /* IDT R3000 derivates > ISA I */ > +#define PRID_R3IDT_R3041 0x07 /* R3041 (cp_rev field) */ > +#define PRID_R3IDT_R36100 0x10 /* R36100 (cp_rev field) */ > +#define PRID_R10000 0x09 /* MIPS R10000/T5 CPU > ISA IV */ > +#define PRID_R4200 0x0a /* MIPS R4200 CPU (ICE) > ISA III */ > +#define PRID_R4300 0x0b /* NEC VR4300 CPU ISA III */ > +#define PRID_R4100 0x0c /* NEC VR4100 CPU ISA III */ > +#define PRID_R8000 0x10 /* MIPS R8000 Blackbird/TFP > ISA IV */ > +#define PRID_RC6457X 0x15 /* IDT RC6457X CPU > ISA IV */ > +#define PRID_RC3233X 0x18 /* IDT RC3233X CPU > ISA MIPS32 */ > +#define PRID_R4600 0x20 /* QED R4600 Orion > ISA III */ > +#define PRID_R4700 0x21 /* QED R4700 Orion > ISA III */ > +#define PRID_R3900 0x22 /* Toshiba/Philips R3900 CPU > ISA I */ > +#define PRID_R4650 0x22 /* QED R4650/R4640 CPU > ISA III */ > +#define PRID_R5000 0x23 /* MIPS R5000 CPU > ISA IV */ > +#define PRID_RC3236X 0x26 /* IDT RC3236X CPU > ISA MIPS32 */ > +#define PRID_RM7000 0x27 /* QED RM7000 CPU > ISA IV */ > +#define PRID_RM52XX 0x28 /* QED RM52XX CPU > ISA IV */ > +#define PRID_RC6447X 0x30 /* IDT RC6447X CPU > ISA III */ > +#define PRID_R5400 0x54 /* NEC Vr5400 CPU > ISA IV */ > +#define PRID_R5500 0x55 /* NEC Vr5500 CPU > ISA IV */ > +#define PRID_JADE 0x80 /* MIPS Jade (obsolete name) ISA MIPS32 > */ > +#define PRID_4KC 0x80 /* MIPS 4Kc (TLB) ISA MIPS32 > */ > +#define PRID_5KC 0x81 /* MIPS 5Kc ISA MIPS64 > */ > +#define PRID_20KC 0x82 /* MIPS 20Kc ISA MIPS64 > */ > +#define PRID_4KMP 0x83 /* MIPS 4Kp/4Km (FM) ISA MIPS32 > */ > +#define PRID_4KEC 0x84 /* MIPS 4KEc (TLB) ISA MIPS32 > */ > +#define PRID_4KEMP 0x85 /* MIPS 4KEm/4KEp (FM) ISA MIPS32 > */ > +#define PRID_4KSC 0x86 /* MIPS 4KSc ISA MIPS32 > */ > +#define PRID_M4K 0x87 /* MIPS M4K ISA > MIPS32r2 */ > +#define PRID_25KF 0x88 /* MIPS 25Kf ISA MIPS64 > */ > +#define PRID_5KE 0x89 /* MIPS 5KE ISA > MIPS64r2 */ > +#define PRID_4KEC_R2 0x90 /* MIPS 4KEc (TLB) ISA > MIPS32r2 */ > +#define PRID_4KEMP_R2 0x91 /* MIPS 4KEm/4KEp (FM) ISA > MIPS32r2 */ > +#define PRID_4KSD 0x92 /* MIPS 4KSd ISA > MIPS32r2 */ > +#define PRID_24K 0x93 /* MIPS 24K ISA > MIPS32r2 */ > +#define PRID_34K 0x95 /* MIPS 34K ISA > MIPS32r2 */ > +#define PRID_24KE 0x96 /* MIPS 24KE ISA > MIPS32r2 */ > +#define PRID_74K 0x97 /* MIPS 74K ISA > MIPS32r2 */ > +#define PRID_1004K 0x99 /* MIPS 1004K ISA > MIPS32r2 */ > +#define PRID_1074K 0x9A /* MIPS 1074K ISA > MIPS32r2 */ > +#define PRID_M14K 0x9B /* MIPS M14K ISA > MIPS32r2 */ > +#define PRID_M14KC 0x9C /* MIPS M14KC ISA > MIPS32r2 */ > +#define PRID_M14KE 0x9D /* MIPS M14KE ISA > MIPS32r2 */ > +#define PRID_M14KEC 0x9E /* MIPS M14KEC ISA > MIPS32r2 */ > +#define PRID_INTERAPTIV_UP 0xA0 /* MIPS INTERAPTIV UP ISA > MIPS32r2 */ > +#define PRID_INTERAPTIV_MP 0xA1 /* MIPS INTERAPTIV MP ISA > MIPS32r2 */ > +#define PRID_PROAPTIV_UP 0xA2 /* MIPS PROAPTIV UP ISA > MIPS32r2 */ > +#define PRID_PROAPTIV_MP 0xA3 /* MIPS PROAPTIV MP ISA > MIPS32r2 */ > +#define PRID_M5100 0xA6 /* MIPS WARRIOR M5100 ISA > MIPS32r2 */ > +#define PRID_M5150 0xA7 /* MIPS WARRIOR M5150 ISA > MIPS32r2 */ > +#define PRID_P5600 0xA8 /* MIPS WARRIOR P5600 ISA > MIPS32r2 */ > +#define PRID_I6400 0xA9 /* MIPS I6400 ISA > MIPS64r6 */ > + > +/* > + * MIPS FPU types > + */ > +#define PRID_SOFT 0x00 /* Software emulation > ISA I */ > +#define PRID_R2360 0x01 /* MIPS R2360 FPC > ISA I */ > +#define PRID_R2010 0x02 /* MIPS R2010 FPC > ISA I */ > +#define PRID_R3010 0x03 /* MIPS R3010 FPC > ISA I */ > +#define PRID_R6010 0x04 /* MIPS R6010 FPC > ISA II */ > +#define PRID_R4010 0x05 /* MIPS R4000/R4400 FPC > ISA II */ > +#define PRID_LR33010 0x06 /* LSI Logic derivate ISA I */ > +#define PRID_R10010 0x09 /* MIPS R10000/T5 FPU > ISA IV */ > +#define PRID_R4210 0x0a /* MIPS R4200 FPC (ICE) > ISA III */ > +#define PRID_UNKF1 0x0b /* unnanounced product cpu ISA III */ > +#define PRID_R8010 0x10 /* MIPS R8000 Blackbird/TFP > ISA IV */ > +#define PRID_RC6457XF 0x15 /* IDT RC6457X FPU > ISA IV */ > +#define PRID_R4610 0x20 /* QED R4600 Orion > ISA III */ > +#define PRID_R3SONY 0x21 /* Sony R3000 based FPU > ISA I */ > +#define PRID_R3910 0x22 /* Toshiba/Philips R3900 FPU > ISA I */ > +#define PRID_R5010 0x23 /* MIPS R5000 FPU > ISA IV */ > +#define PRID_RM7000F 0x27 /* QED RM7000 FPU > ISA IV */ > +#define PRID_RM52XXF 0x28 /* QED RM52X FPU > ISA IV */ > +#define PRID_RC6447XF 0x30 /* IDT RC6447X FPU > ISA III */ > +#define PRID_R5400F 0x54 /* NEC Vr5400 FPU > ISA IV */ > +#define PRID_R5500F 0x55 /* NEC Vr5500 FPU > ISA IV */ > +#define PRID_20KCF 0x82 /* MIPS 20Kc FPU ISA MIPS64 > */ > +#define PRID_5KF 0x81 /* MIPS 5Kf FPU ISA MIPS64 > */ > +#define PRID_25KFF 0x88 /* MIPS 25Kf FPU ISA MIPS64 > */ > +#define PRID_5KEF 0x89 /* MIPS 5KEf FPU ISA > MIPS64r2 */ > +#define PRID_24KF 0x93 /* MIPS 24Kf FPU ISA > MIPS32r2 */ > +#define PRID_34KF 0x95 /* MIPS 34K FPU ISA > MIPS32r2 */ > +#define PRID_24KEF 0x96 /* MIPS 24KE FPU ISA > MIPS32r2 */ > +#define PRID_74KF 0x97 /* MIPS 74K FPU ISA > MIPS32r2 */ > + > +#endif /* _MIPS_PRID_H_ */ > diff --git a/libgloss/mips/include/mips/regdef.h > b/libgloss/mips/include/mips/regdef.h > new file mode 100644 > index 000000000..f901c3043 > --- /dev/null > +++ b/libgloss/mips/include/mips/regdef.h > @@ -0,0 +1,133 @@ > +/* > + * Copyright 2014-2017, Imagination Technologies Limited and/or its > + * affiliated group companies. > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * 1. Redistributions of source code must retain the above copyright > notice, > + * this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS > BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > THE > + * POSSIBILITY OF SUCH DAMAGE. > +*/ > + > +#ifndef _MIPS_REGDEF_H_ > +#define _MIPS_REGDEF_H_ > + > +#define zero $0 > + > +#define AT $1 > + > +#define v0 $2 > +#define v1 $3 > +#define va0 $2 > +#define va1 $3 > + > +#define vt0 $2 > +#define vt1 $3 > + > +#define a0 $4 > +#define a1 $5 > +#define a2 $6 > +#define a3 $7 > + > +#if _MIPS_SIM==_ABIN32 || _MIPS_SIM==_ABI64 || _MIPS_SIM==_ABIEABI > +#define a4 $8 > +#define a5 $9 > +#define a6 $10 > +#define a7 $11 > +#define t0 $12 > +#define t1 $13 > +#define t2 $14 > +#define t3 $15 > +#define ta0 $8 /* alias for $a4 */ > +#define ta1 $9 /* alias for $a5 */ > +#define ta2 $10 /* alias for $a6 */ > +#define ta3 $11 /* alias for $a7 */ > +#else > +#define t0 $8 > +#define t1 $9 > +#define t2 $10 > +#define t3 $11 > +#define t4 $12 > +#define t5 $13 > +#define t6 $14 > +#define t7 $15 > +#define ta0 $12 /* alias for $t4 */ > +#define ta1 $13 /* alias for $t5 */ > +#define ta2 $14 /* alias for $t6 */ > +#define ta3 $15 /* alias for $t7 */ > +#endif > + > +#define s0 $16 > +#define s1 $17 > +#define s2 $18 > +#define s3 $19 > +#define s4 $20 > +#define s5 $21 > +#define s6 $22 > +#define s7 $23 > +#define s8 $30 /* == fp */ > + > +#define t8 $24 > +#define t9 $25 > +#define k0 $26 > +#define k1 $27 > + > +#define gp $28 > + > +#define sp $29 > +#define fp $30 > +#define ra $31 > + > +#define r0 $0 > +#define r1 $1 > +#define r2 $2 > +#define r3 $3 > +#define r4 $4 > +#define r5 $5 > +#define r6 $6 > +#define r7 $7 > +#define r8 $8 > +#define r9 $9 > +#define r10 $10 > +#define r11 $11 > +#define r12 $12 > +#define r13 $13 > +#define r14 $14 > +#define r15 $15 > +#define r16 $16 > +#define r17 $17 > +#define r18 $18 > +#define r19 $19 > +#define r20 $20 > +#define r21 $21 > +#define r22 $22 > +#define r23 $23 > +#define r24 $24 > +#define r25 $25 > +#define r26 $26 > +#define r27 $27 > +#define r28 $28 > +#define r29 $29 > +#define r30 $30 > +#define r31 $31 > + > +#endif /*_MIPS_REGDEF_H_*/ > diff --git a/libgloss/mips/include/mips/version.h > b/libgloss/mips/include/mips/version.h > new file mode 100644 > index 000000000..d2ca5679d > --- /dev/null > +++ b/libgloss/mips/include/mips/version.h > @@ -0,0 +1,4 @@ > +/* This file just defines the current version number of MIPS HAL > library. */ > + > +#define __MIPS_HAL_VERSION__ "3.0.0" > + > diff --git a/libgloss/mips/malta32-yamon.ld > b/libgloss/mips/malta32-yamon.ld > new file mode 100644 > index 000000000..5175071c2 > --- /dev/null > +++ b/libgloss/mips/malta32-yamon.ld > @@ -0,0 +1,318 @@ > +/* > + * A malta based target independent link script to produce UHI > + * compliant binaries with varying levels of system initialization > + * support. > + */ > + > +__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start; > +ENTRY(__entry) > +OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", > "elf32-tradlittlemips") > +GROUP(-lc -lyamon -luhi -lgcc -lhal) > +SEARCH_DIR(.) > + > +/* Define where the yamon entry point table is */ > +__yamon_functions = 0x9fc00500; > + > +__DYNAMIC = 0; > +STARTUP(crt0.o) > +/* Force the exception handler to be registered */ > +EXTERN(__register_excpt_handler) > +/* Force the exception handler to be included in the link */ > +EXTERN(__exception_entry) > +/* > + * Require verbose exceptions. This can be changed to pull in > + * __exception_handle_quiet to reduce code size but be less > + * informative > + */ > +EXTERN(__exception_handle_verbose) > +/* Force the interrupt handlers to be included in the link */ > +EXTERN(__isr_vec) > +/* Force ISRs 0-7 to be included in the link */ > +EXTERN(_isr_vec_7) > +/* Require the UHI getargs support */ > +EXTERN(__getargs) > +/* Include the breakpoint exception handler. */ > +EXTERN (__uhi_break); > + > +/* > + * Set the location of the top of the stack. A value of 0 means > + * that it will be automatically placed at the highest address > + * available as described by the __memory_* setttings > + */ > +PROVIDE (__stack = 0); > + > +/* Size of the memory returned by _get_ram_range */ > +PROVIDE (__memory_size = 3M); > + > +/* Base of the memory returned by _get_ram_range */ > +PROVIDE (__memory_base = 0x80000000); > + > +/* Stride length for tlb software invalidate for tlbinvf > + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways > + * differently in the index register. Either sets LSB or ways LSB. > + * > + * By setting this to 1 we presume that sets come first. The default boot > + * code will decrement this value from the Number of TLB entries. > + */ > +PROVIDE (__tlb_stride_length = 1); > + > +/* By default, XPA is not used even if available. To enable XPA, > + * __enable_xpa should be 1. > + */ > +PROVIDE (__enable_xpa = 0); > + > +/* > + * 0 = Do not use exception handler present in boot for UHI > + * 1 = Use exception handler present in boot for UHI if BEV is 0 at > + * startup > + * 2 = Always use exception handler present in boot for UHI > + */ > +PROVIDE (__use_excpt_boot = 0); > +/* > + * Include the code to be able to return to boot context. This is > + * necessary if __use_excpt_boot != 0. > + */ > +EXTERN (__register_excpt_boot); > + > +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0, > + "Registration for boot context is required for UHI chaining") > + > +/* Control if subnormal floating-point values are flushed to zero in > + hardware. This applies to both FPU and MSA operations. */ > +PROVIDE (__flush_to_zero = 1); > + > +/* Set up the public symbols depending on whether the user has chosen > + quiet or verbose exception handling above */ > +EXTERN (__exception_handle); > +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet) > + ? __exception_handle_quiet > + : __exception_handle_verbose)); > +PROVIDE(_mips_handle_exception = __exception_handle); > + > +/* > + * Initalize some symbols to be zero so we can reference them in the > + * crt0 without core dumping. These functions are all optional, but > + * we do this so we can have our crt0 always use them if they exist. > + * This is so BSPs work better when using the crt0 installed with gcc. > + * We have to initalize them twice, so we multiple object file > + * formats, as some prepend an underscore. > + */ > +PROVIDE (hardware_exit_hook = 0); > +PROVIDE (hardware_hazard_hook = 0); > +PROVIDE (hardware_init_hook = 0); > +PROVIDE (software_init_hook = 0); > + > +/* The default base address for application code is 0x80200000 which > + leaves 2M of space at the start of KSEG0 for a bootloader. */ > +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000); > +/* Set default vector spacing to 32 bytes. */ > +PROVIDE (__isr_vec_space = 32); > +/* Leave space for 9 vector entries by default. 8 entry points and one > + fallback handler. */ > +PROVIDE (__isr_vec_count = 9); > +/* > + * The start of flash must be set if including boot code. By default > + * the use of boot code will mean that application code is copied > + * from flash to RAM at runtime before being executed. > + */ > +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 : > __app_start); > + > +SECTIONS > +{ > + /* Start of bootrom */ > + .bootrom 0x9fc00000 : /* Runs uncached (from 0x9fc00000) until I$ is > + initialized. */ > + AT (__flash_start) > + { > + *(.reset) /* Reset entry point. */ > + *(.boot) /* Boot code. */ > + . = ALIGN(8); > + } = 0 > + > + PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start); > + > + /* Start of the application */ > + .exception_vector ALIGN(__app_start, 0x1000) : > + AT (__flash_app_start) > + { > + __excpt_ebase = ABSOLUTE(.); > + __base = .; > + KEEP(* (.text.__exception_entry)) > + . = __base + 0x200; > + KEEP(* (SORT(.text.__isr_vec*))) > + /* Leave space for all the vector entries */ > + . = __base + 0x200 + (__isr_vec_space * __isr_vec_count); > + ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1) > + ? __isr_vec_sw1 - __isr_vec_sw0 > + : __isr_vec_space), > + "Actual ISR vector spacing does not match __isr_vec_space"); > + ASSERT(__base + 0x200 == (DEFINED(__isr_vec_sw0) > + ? __isr_vec_sw0 & 0xfffffffe : __base + > 0x200), > + "__isr_vec_sw0 is not placed at EBASE + 0x200"); > + . = ALIGN(8); > + } = 0 > + > + .text : { > + _ftext = . ; > + PROVIDE (eprol = .); > + *(.text) > + *(.text.*) > + *(.gnu.linkonce.t.*) > + *(.mips16.fn.*) > + *(.mips16.call.*) > + } > + .init : { > + KEEP (*(.init)) > + } > + .fini : { > + KEEP (*(.fini)) > + } > + .rel.sdata : { > + PROVIDE (__runtime_reloc_start = .); > + *(.rel.sdata) > + PROVIDE (__runtime_reloc_stop = .); > + } > + PROVIDE (etext = .); > + _etext = .; > + > + .eh_frame_hdr : { *(.eh_frame_hdr) } > + .eh_frame : { KEEP (*(.eh_frame)) } > + .gcc_except_table : { *(.gcc_except_table) } > + .jcr : { KEEP (*(.jcr)) } > + .ctors : > + { > + /* gcc uses crtbegin.o to find the start of > + the constructors, so we make sure it is > + first. Because this is a wildcard, it > + doesn't matter if the user does not > + actually link against crtbegin.o; the > + linker won't look for a file to match a > + wildcard. The wildcard also means that it > + doesn't matter which directory crtbegin.o > + is in. */ > + > + KEEP (*crtbegin.o(.ctors)) > + > + /* We don't want to include the .ctor section from > + from the crtend.o file until after the sorted ctors. > + The .ctor section from the crtend file contains the > + end of ctors marker and it must be last */ > + > + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) > + KEEP (*(SORT(.ctors.*))) > + KEEP (*(.ctors)) > + } > + > + .dtors : > + { > + KEEP (*crtbegin.o(.dtors)) > + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) > + KEEP (*(SORT(.dtors.*))) > + KEEP (*(.dtors)) > + } > + > + . = .; > + .MIPS.abiflags : { > + __MIPS_abiflags_start = .; > + *(.MIPS.abiflags) > + __MIPS_abiflags_end = .; > + } > + .rodata : { > + *(.rdata) > + *(.rodata) > + *(.rodata.*) > + *(.gnu.linkonce.r.*) > + } > + . = ALIGN(16); > + _fdata = .; > + .data : { > + *(.data) > + *(.data.*) > + *(.gnu.linkonce.d.*) > + } > + . = ALIGN(8); > + MIPS_REVISION = DEFINED (__mips_isa_rev) ? ABSOLUTE(__mips_isa_rev) : 0; > + GP_OFFSET = (MIPS_REVISION < 7) ? 0x8000 : 0; > + _gp = . + GP_OFFSET; > + __global = _gp; > + .lit8 : { > + *(.lit8) > + } > + .lit4 : { > + *(.lit4) > + } > + .sdata : { > + *(.sdata) > + *(.sdata.*) > + *(.gnu.linkonce.s.*) > + } > + . = ALIGN(4); > + PROVIDE (edata = .); > + _edata = .; > + _fbss = .; > + .sbss : { > + *(.sbss) > + *(.sbss.*) > + *(.gnu.linkonce.sb.*) > + *(.scommon) > + } > + .bss : { > + _bss_start = . ; > + *(.bss) > + *(.bss.*) > + *(.gnu.linkonce.b.*) > + *(COMMON) > + } > + > + . = ALIGN(4); > + PROVIDE (end = .); > + _end = .; > + /* Now place the data that is only needed within start.S and can be > + overwritten by the heap. */ > + .startdata : { > + *(.startdata) > + } > + > + /* DWARF debug sections. > + Symbols in the DWARF debugging sections are relative to > + the beginning of the section so we begin them at 0. */ > + > + /* DWARF 1 */ > + .debug 0 : { *(.debug) } > + .line 0 : { *(.line) } > + > + /* GNU DWARF 1 extensions */ > + .debug_srcinfo 0 : { *(.debug_srcinfo) } > + .debug_sfnames 0 : { *(.debug_sfnames) } > + > + /* DWARF 1.1 and DWARF 2 */ > + .debug_aranges 0 : { *(.debug_aranges) } > + .debug_pubnames 0 : { *(.debug_pubnames) } > + > + /* DWARF 2 */ > + .debug_info 0 : { *(.debug_info) } > + .debug_abbrev 0 : { *(.debug_abbrev) } > + .debug_line 0 : { *(.debug_line) } > + .debug_frame 0 : { *(.debug_frame) } > + .debug_str 0 : { *(.debug_str) } > + .debug_loc 0 : { *(.debug_loc) } > + .debug_macinfo 0 : { *(.debug_macinfo) } > + .debug_ranges 0 : { *(.debug_ranges) } > + > + /* SGI/MIPS DWARF 2 extensions */ > + .debug_weaknames 0 : { *(.debug_weaknames) } > + .debug_funcnames 0 : { *(.debug_funcnames) } > + .debug_typenames 0 : { *(.debug_typenames) } > + .debug_varnames 0 : { *(.debug_varnames) } > + > + /* Special sections generated by gcc */ > + /* Newer GNU linkers strip by default */ > + .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) } > + .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) } > + .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) } > + .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) } > + .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) } > + .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) } > + .gcc_compiled_long32 0 : { KEEP(*(.gcc_compiled_long32)) } > + .gcc_compiled_long64 0 : { KEEP(*(.gcc_compiled_long64)) } > +} > diff --git a/libgloss/mips/regs.S b/libgloss/mips/regs.S > index e4b134307..ac2935465 100644 > --- a/libgloss/mips/regs.S > +++ b/libgloss/mips/regs.S > @@ -98,7 +98,10 @@ > #define SR_SX 0x00000040 /* Supervisor extended addressing > enabled */ > #define SR_UX 0x00000020 /* User extended addressing > enabled */ > > -#define SR_MSA 0x08000000 /* MSA ASE */ > +#define SR_IE 0x00000001 /* Interrupt enable */ > + > +#define SR_MX 0x01000000 /* MDMX or DSP ASE */ > +#define CFG5_MSAEN 0x08000000 /* MSA ASE */ > > /* Standard (R4000) cache operations. Taken from "MIPS R4000 > Microprocessor User's Manual" 2nd edition: */ > diff --git a/libgloss/mips/syscalls.c b/libgloss/mips/syscalls.c > deleted file mode 100644 > index 3ab543674..000000000 > --- a/libgloss/mips/syscalls.c > +++ /dev/null > @@ -1,45 +0,0 @@ > -#include <_ansi.h> > -#include <sys/types.h> > -#include <sys/stat.h> > - > -#include "regs.S" > - > -extern char _end[]; > - > -/* FIXME: This is not ideal, since we do a get_mem_info() call for > - every sbrk() call. */ > -char * > -sbrk (nbytes) > - int nbytes; > -{ > - static char *heap_ptr = _end; > - static char *heap_start = _end; > - char *base; > - struct s_mem { > - unsigned int size; > - unsigned int icsize; > - unsigned int dcsize; > - } mem; > - unsigned int avail = 0; > - > - /* The sizeof (s_mem.size) must be 4 bytes. The compiler should be > - able to eliminate this check */ > - if (sizeof (unsigned int) != 4) > - return (char *)-1; > - > - get_mem_info(&mem); > - /* NOTE: The value returned from the get_mem_info call is the amount > - of memory, and not the address of the (last byte + 1) */ > - > - if (((size_t)heap_ptr >= heap_start) && ((size_t)heap_ptr < (heap_start > + mem.size))) { > - avail = (heap_start + mem.size) - (size_t)heap_ptr; > - base = heap_ptr; > - } /* else will fail since "nbytes" will be greater than zeroed "avail" > value */ > - > - if ((nbytes > avail) || (heap_ptr + nbytes < _end)) > - base = (char *)-1; > - else > - heap_ptr += nbytes; > - > - return base; > -} > diff --git a/libgloss/mips/uhi32.ld b/libgloss/mips/uhi32.ld > new file mode 100644 > index 000000000..d9df8e5e0 > --- /dev/null > +++ b/libgloss/mips/uhi32.ld > @@ -0,0 +1,322 @@ > +/* > + * A platform and target independent link script to produce UHI > + * compliant binaries with varying levels of system initialization > + * support. > + */ > + > +__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start; > +ENTRY(__entry) > +OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips", > "elf32-tradlittlemips") > +GROUP(-lc -luhi -lgcc -lhal) > +SEARCH_DIR(.) > +__DYNAMIC = 0; > +STARTUP(crt0.o) > +/* Force the exception handler to be registered */ > +EXTERN(__register_excpt_handler) > +/* Force the exception handler to be included in the link */ > +EXTERN(__exception_entry) > +/* > + * Require verbose exceptions. This can be changed to pull in > + * __exception_handle_quiet to reduce code size but be less > + * informative > + */ > +EXTERN(__exception_handle_verbose) > +/* Force ISRs 0-7 to be included in the link */ > +EXTERN(__isr_vec_007) > +/* Require the UHI getargs support */ > +EXTERN(__getargs) > +/* Include the breakpoint exception handler. */ > +EXTERN (__uhi_break); > + > +/* > + * Set the location of the top of the stack. A value of 0 means > + * that it will be automatically placed at the highest address > + * available as described by the __memory_* setttings > + */ > +PROVIDE (__stack = 0); > + > +/* Size of the memory returned by _get_ram_range */ > +PROVIDE (__memory_size = 3M); > + > +/* Base of the memory returned by _get_ram_range */ > +PROVIDE (__memory_base = 0x80000000); > + > +/* Stride length for tlb software invalidate for tlbinvf > + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways > + * differently in the index register. Either sets LSB or ways LSB. > + * > + * By setting this to 1 we presume that sets come first. The default boot > + * code will decrement this value from the Number of TLB entries. > + */ > +PROVIDE (__tlb_stride_length = 1); > + > +/* By default, XPA is not used even if available. To enable XPA, > + * __enable_xpa should be 1. > + */ > +PROVIDE (__enable_xpa = 0); > + > +/* > + * 0 = Do not use exception handler present in boot for UHI > + * 1 = Use exception handler present in boot for UHI if BEV is 0 at > + * startup > + * 2 = Always use exception handler present in boot for UHI > + */ > +PROVIDE (__use_excpt_boot = 1); > +/* > + * Include the code to be able to return to boot context. This is > + * necessary if __use_excpt_boot != 0. > + */ > +EXTERN (__register_excpt_boot); > + > +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0, > + "Registration for boot context is required for UHI chaining") > + > +/* Control if subnormal floating-point values are flushed to zero in > + hardware. This applies to both FPU and MSA operations. */ > +PROVIDE (__flush_to_zero = 1); > + > +/* Set up the public symbols depending on whether the user has chosen > + quiet or verbose exception handling above */ > +EXTERN (__exception_handle); > +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet) > + ? __exception_handle_quiet > + : __exception_handle_verbose)); > +PROVIDE(_mips_handle_exception = __exception_handle); > + > +/* > + * Initalize some symbols to be zero so we can reference them in the > + * crt0 without core dumping. These functions are all optional, but > + * we do this so we can have our crt0 always use them if they exist. > + * This is so BSPs work better when using the crt0 installed with gcc. > + * We have to initalize them twice, so we multiple object file > + * formats, as some prepend an underscore. > + */ > +PROVIDE (hardware_exit_hook = 0); > +PROVIDE (hardware_hazard_hook = 0); > +PROVIDE (hardware_init_hook = 0); > +PROVIDE (software_init_hook = 0); > + > +/* The default base address for application code is 0x80200000 which > + leaves 2M of space at the start of KSEG0 for a bootloader. */ > +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000); > +/* Set default vector spacing to 32 bytes. */ > +PROVIDE (__isr_vec_space = 32); > +/* Leave space for 9 vector entries by default. 8 entry points and one > + fallback handler. */ > +PROVIDE (__isr_vec_count = 9); > +/* > + * The start of flash must be set if including boot code. By default > + * the use of boot code will mean that application code is copied > + * from flash to RAM at runtime before being executed. > + */ > +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 : > __app_start); > +/* Set the default execution address for boot code. */ > +PROVIDE (__bev_override = 0x9fc00000); > + > +SECTIONS > +{ > + /* Start of bootrom */ > + .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is > + initialized. */ > + AT (__flash_start) > + { > + *(.reset) /* Reset entry point. */ > + *(.boot) /* Boot code. */ > + . = ALIGN(8); > + } = 0 > + > + PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start); > + > + __aligned_app_start = DEFINED(__xip) > + ? __bev_override + SIZEOF(.bootrom) > + : ALIGN(__app_start, 0x1000); > + > + PROVIDE (__ebase_size = 0x200); > + > + /* Start of the application */ > + .exception_vector __aligned_app_start : > + AT (__flash_app_start) > + { > + PROVIDE (__excpt_ebase = ABSOLUTE(.)); > + __base = .; > + KEEP(* (.text.__exception_entry)) > + . = __base + __ebase_size; > + KEEP(* (SORT(.text.__isr_vec*))) > + /* Leave space for all the vector entries */ > + . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count); > + ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1) > + ? __isr_vec_sw1 - __isr_vec_sw0 > + : __isr_vec_space), > + "Actual ISR vector spacing does not match __isr_vec_space"); > + ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0) > + ? __isr_vec_sw0 & 0xfffffffe > + : __base + __ebase_size), > + "__isr_vec_sw0 is not placed at EBASE + 0x200"); > + . = ALIGN(8); > + } = 0 > + > + .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector)) > { > + _ftext = . ; > + PROVIDE (eprol = .); > + *(.text) > + *(.text.*) > + *(.gnu.linkonce.t.*) > + *(.mips16.fn.*) > + *(.mips16.call.*) > + } > + .init . : AT (LOADADDR (.text) + SIZEOF(.text)) { > + KEEP (*(.init)) > + } > + .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) { > + KEEP (*(.fini)) > + } > + .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) { > + PROVIDE (__runtime_reloc_start = .); > + *(.rel.sdata) > + PROVIDE (__runtime_reloc_stop = .); > + } > + PROVIDE (etext = .); > + _etext = .; > + > + .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) { > *(.eh_frame_hdr) } > + .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) { > KEEP (*(.eh_frame)) } > + .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) { > *(.gcc_except_table) } > + .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table)) > { KEEP (*(.jcr)) } > + .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr)) > + { > + /* gcc uses crtbegin.o to find the start of > + the constructors, so we make sure it is > + first. Because this is a wildcard, it > + doesn't matter if the user does not > + actually link against crtbegin.o; the > + linker won't look for a file to match a > + wildcard. The wildcard also means that it > + doesn't matter which directory crtbegin.o > + is in. */ > + > + KEEP (*crtbegin.o(.ctors)) > + > + /* We don't want to include the .ctor section from > + from the crtend.o file until after the sorted ctors. > + The .ctor section from the crtend file contains the > + end of ctors marker and it must be last */ > + > + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) > + KEEP (*(SORT(.ctors.*))) > + KEEP (*(.ctors)) > + } > + > + .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors)) > + { > + KEEP (*crtbegin.o(.dtors)) > + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) > + KEEP (*(SORT(.dtors.*))) > + KEEP (*(.dtors)) > + } > + > + . = .; > + .MIPS.abiflags : { > + __MIPS_abiflags_start = .; > + *(.MIPS.abiflags) > + __MIPS_abiflags_end = .; > + } > + .rodata : { > + *(.rdata) > + *(.rodata) > + *(.rodata.*) > + *(.gnu.linkonce.r.*) > + } > + . = ALIGN(16); > + _fdata = .; > + .data : { > + *(.data) > + *(.data.*) > + *(.gnu.linkonce.d.*) > + } > + . = ALIGN(8); > + _gp = . + 0x8000; > + __global = _gp; > + .lit8 : { > + *(.lit8) > + } > + .lit4 : { > + *(.lit4) > + } > + .sdata : { > + *(.sdata) > + *(.sdata.*) > + *(.gnu.linkonce.s.*) > + } > + . = ALIGN(4); > + PROVIDE (edata = .); > + _edata = .; > + _fbss = .; > + .sbss : { > + *(.sbss) > + *(.sbss.*) > + *(.gnu.linkonce.sb.*) > + *(.scommon) > + } > + .bss : { > + _bss_start = . ; > + *(.bss) > + *(.bss.*) > + *(.gnu.linkonce.b.*) > + *(COMMON) > + } > + > + . = ALIGN(4); > + PROVIDE (end = .); > + _end = .; > + /* Now place the data that is only needed within start.S and can be > + overwritten by the heap. */ > + .startdata : { > + *(.startdata) > + } > + > + /* We do not support any runtime relocation handling with this script. > */ > + /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) } > + > + /* DWARF debug sections. > + Symbols in the DWARF debugging sections are relative to > + the beginning of the section so we begin them at 0. */ > + > + /* DWARF 1 */ > + .debug 0 : { *(.debug) } > + .line 0 : { *(.line) } > + > + /* GNU DWARF 1 extensions */ > + .debug_srcinfo 0 : { *(.debug_srcinfo) } > + .debug_sfnames 0 : { *(.debug_sfnames) } > + > + /* DWARF 1.1 and DWARF 2 */ > + .debug_aranges 0 : { *(.debug_aranges) } > + .debug_pubnames 0 : { *(.debug_pubnames) } > + > + /* DWARF 2 */ > + .debug_info 0 : { *(.debug_info) } > + .debug_abbrev 0 : { *(.debug_abbrev) } > + .debug_line 0 : { *(.debug_line) } > + .debug_frame 0 : { *(.debug_frame) } > + .debug_str 0 : { *(.debug_str) } > + .debug_loc 0 : { *(.debug_loc) } > + .debug_macinfo 0 : { *(.debug_macinfo) } > + .debug_ranges 0 : { *(.debug_ranges) } > + > + /* SGI/MIPS DWARF 2 extensions */ > + .debug_weaknames 0 : { *(.debug_weaknames) } > + .debug_funcnames 0 : { *(.debug_funcnames) } > + .debug_typenames 0 : { *(.debug_typenames) } > + .debug_varnames 0 : { *(.debug_varnames) } > + > + /* Special sections generated by gcc */ > + /* Newer GNU linkers strip by default */ > + .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) } > + .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) } > + .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) } > + .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) } > + .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) } > + .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) } > + .gcc_compiled_long32 0 : { KEEP(*(.gcc_compiled_long32)) } > + .gcc_compiled_long64 0 : { KEEP(*(.gcc_compiled_long64)) } > +} > diff --git a/libgloss/mips/uhi64_64.ld b/libgloss/mips/uhi64_64.ld > new file mode 100644 > index 000000000..15aeb2ecc > --- /dev/null > +++ b/libgloss/mips/uhi64_64.ld > @@ -0,0 +1,322 @@ > +/* > + * A platform and target independent link script to produce UHI > + * compliant binaries with varying levels of system initialization > + * support. > + */ > + > +__entry = DEFINED(__reset_vector) ? 0xffffffffbfc00000 : _start; > +ENTRY(__entry) > +OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", > "elf64-tradlittlemips") > +GROUP(-lc -luhi -lgcc -lhal) > +SEARCH_DIR(.) > +__DYNAMIC = 0; > +STARTUP(crt0.o) > +/* Force the exception handler to be registered */ > +EXTERN(__register_excpt_handler) > +/* Force the exception handler to be included in the link */ > +EXTERN(__exception_entry) > +/* > + * Require verbose exceptions. This can be changed to pull in > + * __exception_handle_quiet to reduce code size but be less > + * informative > + */ > +EXTERN(__exception_handle_verbose) > +/* Force ISRs 0-7 to be included in the link */ > +EXTERN(__isr_vec_007) > +/* Require the UHI getargs support */ > +EXTERN(__getargs) > +/* Include the breakpoint exception handler. */ > +EXTERN (__uhi_break); > + > +/* > + * Set the location of the top of the stack. A value of 0 means > + * that it will be automatically placed at the highest address > + * available as described by the __memory_* setttings > + */ > +PROVIDE (__stack = 0); > + > +/* Size of the memory returned by _get_ram_range */ > +PROVIDE (__memory_size = 3M); > + > +/* Base of the memory returned by _get_ram_range */ > +PROVIDE (__memory_base = 0xffffffff80000000); > + > +/* Stride length for tlb software invalidate for tlbinvf > + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways > + * differently in the index register. Either sets LSB or ways LSB. > + * > + * By setting this to 1 we presume that sets come first. The default boot > + * code will decrement this value from the Number of TLB entries. > + */ > +PROVIDE (__tlb_stride_length = 1); > + > +/* By default, XPA is not used even if available. To enable XPA, > + * __enable_xpa should be 1. > + */ > +PROVIDE (__enable_xpa = 0); > + > +/* > + * 0 = Do not use exception handler present in boot for UHI > + * 1 = Use exception handler present in boot for UHI if BEV is 0 at > + * startup > + * 2 = Always use exception handler present in boot for UHI > + */ > +PROVIDE (__use_excpt_boot = 1); > +/* > + * Include the code to be able to return to boot context. This is > + * necessary if __use_excpt_boot != 0. > + */ > +EXTERN (__register_excpt_boot); > + > +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0, > + "Registration for boot context is required for UHI chaining") > + > +/* Control if subnormal floating-point values are flushed to zero in > + hardware. This applies to both FPU and MSA operations. */ > +PROVIDE (__flush_to_zero = 1); > + > +/* Set up the public symbols depending on whether the user has chosen > + quiet or verbose exception handling above */ > +EXTERN (__exception_handle); > +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet) > + ? __exception_handle_quiet > + : __exception_handle_verbose)); > +PROVIDE(_mips_handle_exception = __exception_handle); > + > +/* > + * Initalize some symbols to be zero so we can reference them in the > + * crt0 without core dumping. These functions are all optional, but > + * we do this so we can have our crt0 always use them if they exist. > + * This is so BSPs work better when using the crt0 installed with gcc. > + * We have to initalize them twice, so we multiple object file > + * formats, as some prepend an underscore. > + */ > +PROVIDE (hardware_exit_hook = 0); > +PROVIDE (hardware_hazard_hook = 0); > +PROVIDE (hardware_init_hook = 0); > +PROVIDE (software_init_hook = 0); > + > +/* The default base address for application code is 0x80200000 which > + leaves 2M of space at the start of KSEG0 for a bootloader. */ > +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0xffffffff80000000 > :0xffffffff80200000); > +/* Set default vector spacing to 64 bytes. */ > +PROVIDE (__isr_vec_space = 64); > +/* Leave space for 9 vector entries by default. 8 entry points and one > + fallback handler. */ > +PROVIDE (__isr_vec_count = 9); > +/* > + * The start of flash must be set if including boot code. By default > + * the use of boot code will mean that application code is copied > + * from flash to RAM at runtime before being executed. > + */ > +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xffffffffbfc00000 : > __app_start); > +/* Set the default execution address for boot code. */ > +PROVIDE (__bev_override = 0xffffffff9fc00000); > + > +SECTIONS > +{ > + /* Start of bootrom */ > + .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is > + initialized. */ > + AT (__flash_start) > + { > + *(.reset) /* Reset entry point. */ > + *(.boot) /* Boot code. */ > + . = ALIGN(8); > + } = 0 > + > + PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start); > + > + __aligned_app_start = DEFINED(__xip) > + ? __bev_override + SIZEOF(.bootrom) > + : ALIGN(__app_start, 0x1000); > + > + PROVIDE (__ebase_size = 0x200); > + > + /* Start of the application */ > + .exception_vector __aligned_app_start : > + AT (__flash_app_start) > + { > + PROVIDE (__excpt_ebase = ABSOLUTE(.)); > + __base = .; > + KEEP(* (.text.__exception_entry)) > + . = __base + __ebase_size; > + KEEP(* (SORT(.text.__isr_vec*))) > + /* Leave space for all the vector entries */ > + . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count); > + ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1) > + ? __isr_vec_sw1 - __isr_vec_sw0 > + : __isr_vec_space), > + "Actual ISR vector spacing does not match __isr_vec_space"); > + ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0) > + ? __isr_vec_sw0 > + : __base + __ebase_size), > + "__isr_vec_sw0 is not placed at EBASE + 0x200"); > + . = ALIGN(8); > + } = 0 > + > + .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector)) > { > + _ftext = . ; > + PROVIDE (eprol = .); > + *(.text) > + *(.text.*) > + *(.gnu.linkonce.t.*) > + *(.mips16.fn.*) > + *(.mips16.call.*) > + } > + .init . : AT (LOADADDR (.text) + SIZEOF(.text)) { > + KEEP (*(.init)) > + } > + .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) { > + KEEP (*(.fini)) > + } > + .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) { > + PROVIDE (__runtime_reloc_start = .); > + *(.rel.sdata) > + PROVIDE (__runtime_reloc_stop = .); > + } > + PROVIDE (etext = .); > + _etext = .; > + > + .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) { > *(.eh_frame_hdr) } > + .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) { > KEEP (*(.eh_frame)) } > + .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) { > *(.gcc_except_table) } > + .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table)) > { KEEP (*(.jcr)) } > + .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr)) > + { > + /* gcc uses crtbegin.o to find the start of > + the constructors, so we make sure it is > + first. Because this is a wildcard, it > + doesn't matter if the user does not > + actually link against crtbegin.o; the > + linker won't look for a file to match a > + wildcard. The wildcard also means that it > + doesn't matter which directory crtbegin.o > + is in. */ > + > + KEEP (*crtbegin.o(.ctors)) > + > + /* We don't want to include the .ctor section from > + from the crtend.o file until after the sorted ctors. > + The .ctor section from the crtend file contains the > + end of ctors marker and it must be last */ > + > + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) > + KEEP (*(SORT(.ctors.*))) > + KEEP (*(.ctors)) > + } > + > + .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors)) > + { > + KEEP (*crtbegin.o(.dtors)) > + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) > + KEEP (*(SORT(.dtors.*))) > + KEEP (*(.dtors)) > + } > + > + . = .; > + .MIPS.abiflags : { > + __MIPS_abiflags_start = .; > + *(.MIPS.abiflags) > + __MIPS_abiflags_end = .; > + } > + .rodata : { > + *(.rdata) > + *(.rodata) > + *(.rodata.*) > + *(.gnu.linkonce.r.*) > + } > + . = ALIGN(16); > + _fdata = .; > + .data : { > + *(.data) > + *(.data.*) > + *(.gnu.linkonce.d.*) > + } > + . = ALIGN(8); > + _gp = . + 0x8000; > + __global = _gp; > + .lit8 : { > + *(.lit8) > + } > + .lit4 : { > + *(.lit4) > + } > + .sdata : { > + *(.sdata) > + *(.sdata.*) > + *(.gnu.linkonce.s.*) > + } > + . = ALIGN(4); > + PROVIDE (edata = .); > + _edata = .; > + _fbss = .; > + .sbss : { > + *(.sbss) > + *(.sbss.*) > + *(.gnu.linkonce.sb.*) > + *(.scommon) > + } > + .bss : { > + _bss_start = . ; > + *(.bss) > + *(.bss.*) > + *(.gnu.linkonce.b.*) > + *(COMMON) > + } > + > + . = ALIGN(4); > + PROVIDE (end = .); > + _end = .; > + /* Now place the data that is only needed within start.S and can be > + overwritten by the heap. */ > + .startdata : { > + *(.startdata) > + } > + > + /* We do not support any runtime relocation handling with this script. > */ > + /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) } > + > + /* DWARF debug sections. > + Symbols in the DWARF debugging sections are relative to > + the beginning of the section so we begin them at 0. */ > + > + /* DWARF 1 */ > + .debug 0 : { *(.debug) } > + .line 0 : { *(.line) } > + > + /* GNU DWARF 1 extensions */ > + .debug_srcinfo 0 : { *(.debug_srcinfo) } > + .debug_sfnames 0 : { *(.debug_sfnames) } > + > + /* DWARF 1.1 and DWARF 2 */ > + .debug_aranges 0 : { *(.debug_aranges) } > + .debug_pubnames 0 : { *(.debug_pubnames) } > + > + /* DWARF 2 */ > + .debug_info 0 : { *(.debug_info) } > + .debug_abbrev 0 : { *(.debug_abbrev) } > + .debug_line 0 : { *(.debug_line) } > + .debug_frame 0 : { *(.debug_frame) } > + .debug_str 0 : { *(.debug_str) } > + .debug_loc 0 : { *(.debug_loc) } > + .debug_macinfo 0 : { *(.debug_macinfo) } > + .debug_ranges 0 : { *(.debug_ranges) } > + > + /* SGI/MIPS DWARF 2 extensions */ > + .debug_weaknames 0 : { *(.debug_weaknames) } > + .debug_funcnames 0 : { *(.debug_funcnames) } > + .debug_typenames 0 : { *(.debug_typenames) } > + .debug_varnames 0 : { *(.debug_varnames) } > + > + /* Special sections generated by gcc */ > + /* Newer GNU linkers strip by default */ > + .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) } > + .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) } > + .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) } > + .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) } > + .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) } > + .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) } > + .gcc_compiled_long32 0 : { KEEP(*(.gcc_compiled_long32)) } > + .gcc_compiled_long64 0 : { KEEP(*(.gcc_compiled_long64)) } > +} > diff --git a/libgloss/mips/uhi64_n32.ld b/libgloss/mips/uhi64_n32.ld > new file mode 100644 > index 000000000..d68f2eaaa > --- /dev/null > +++ b/libgloss/mips/uhi64_n32.ld > @@ -0,0 +1,322 @@ > +/* > + * A platform and target independent link script to produce UHI > + * compliant binaries with varying levels of system initialization > + * support. > + */ > + > +__entry = DEFINED(__reset_vector) ? 0xbfc00000 : _start; > +ENTRY(__entry) > +OUTPUT_FORMAT("elf32-ntradlittlemips", "elf32-ntradbigmips", > "elf32-ntradlittlemips") > +GROUP(-lc -luhi -lgcc -lhal) > +SEARCH_DIR(.) > +__DYNAMIC = 0; > +STARTUP(crt0.o) > +/* Force the exception handler to be registered */ > +EXTERN(__register_excpt_handler) > +/* Force the exception handler to be included in the link */ > +EXTERN(__exception_entry) > +/* > + * Require verbose exceptions. This can be changed to pull in > + * __exception_handle_quiet to reduce code size but be less > + * informative > + */ > +EXTERN(__exception_handle_verbose) > +/* Force ISRs 0-7 to be included in the link */ > +EXTERN(__isr_vec_007) > +/* Require the UHI getargs support */ > +EXTERN(__getargs) > +/* Include the breakpoint exception handler. */ > +EXTERN (__uhi_break); > + > +/* > + * Set the location of the top of the stack. A value of 0 means > + * that it will be automatically placed at the highest address > + * available as described by the __memory_* setttings > + */ > +PROVIDE (__stack = 0); > + > +/* Size of the memory returned by _get_ram_range */ > +PROVIDE (__memory_size = 3M); > + > +/* Base of the memory returned by _get_ram_range */ > +PROVIDE (__memory_base = 0x80000000); > + > +/* Stride length for tlb software invalidate for tlbinvf > + * (mipsXXr3+). Some MIPS implementations may layout the sets/ways > + * differently in the index register. Either sets LSB or ways LSB. > + * > + * By setting this to 1 we presume that sets come first. The default boot > + * code will decrement this value from the Number of TLB entries. > + */ > +PROVIDE (__tlb_stride_length = 1); > + > +/* By default, XPA is not used even if available. To enable XPA, > + * __enable_xpa should be 1. > + */ > +PROVIDE (__enable_xpa = 0); > + > +/* > + * 0 = Do not use exception handler present in boot for UHI > + * 1 = Use exception handler present in boot for UHI if BEV is 0 at > + * startup > + * 2 = Always use exception handler present in boot for UHI > + */ > +PROVIDE (__use_excpt_boot = 1); > +/* > + * Include the code to be able to return to boot context. This is > + * necessary if __use_excpt_boot != 0. > + */ > +EXTERN (__register_excpt_boot); > + > +ASSERT (DEFINED(__register_excpt_boot) || __use_excpt_boot == 0, > + "Registration for boot context is required for UHI chaining") > + > +/* Control if subnormal floating-point values are flushed to zero in > + hardware. This applies to both FPU and MSA operations. */ > +PROVIDE (__flush_to_zero = 1); > + > +/* Set up the public symbols depending on whether the user has chosen > + quiet or verbose exception handling above */ > +EXTERN (__exception_handle); > +PROVIDE(__exception_handle = (DEFINED(__exception_handle_quiet) > + ? __exception_handle_quiet > + : __exception_handle_verbose)); > +PROVIDE(_mips_handle_exception = __exception_handle); > + > +/* > + * Initalize some symbols to be zero so we can reference them in the > + * crt0 without core dumping. These functions are all optional, but > + * we do this so we can have our crt0 always use them if they exist. > + * This is so BSPs work better when using the crt0 installed with gcc. > + * We have to initalize them twice, so we multiple object file > + * formats, as some prepend an underscore. > + */ > +PROVIDE (hardware_exit_hook = 0); > +PROVIDE (hardware_hazard_hook = 0); > +PROVIDE (hardware_init_hook = 0); > +PROVIDE (software_init_hook = 0); > + > +/* The default base address for application code is 0x80200000 which > + leaves 2M of space at the start of KSEG0 for a bootloader. */ > +PROVIDE (__app_start = DEFINED(__reset_vector) ? 0x80000000 : 0x80200000); > +/* Set default vector spacing to 32 bytes. */ > +PROVIDE (__isr_vec_space = 32); > +/* Leave space for 9 vector entries by default. 8 entry points and one > + fallback handler. */ > +PROVIDE (__isr_vec_count = 9); > +/* > + * The start of flash must be set if including boot code. By default > + * the use of boot code will mean that application code is copied > + * from flash to RAM at runtime before being executed. > + */ > +PROVIDE (__flash_start = DEFINED(__reset_vector) ? 0xbfc00000 : > __app_start); > +/* Set the default execution address for boot code. */ > +PROVIDE (__bev_override = 0x9fc00000); > + > +SECTIONS > +{ > + /* Start of bootrom */ > + .bootrom __bev_override : /* Runs uncached (from 0x9fc00000) until I$ is > + initialized. */ > + AT (__flash_start) > + { > + *(.reset) /* Reset entry point. */ > + *(.boot) /* Boot code. */ > + . = ALIGN(8); > + } = 0 > + > + PROVIDE (__flash_app_start = SIZEOF(.bootrom) + __flash_start); > + > + __aligned_app_start = DEFINED(__xip) > + ? __bev_override + SIZEOF(.bootrom) > + : ALIGN(__app_start, 0x1000); > + > + PROVIDE (__ebase_size = 0x200); > + > + /* Start of the application */ > + .exception_vector __aligned_app_start : > + AT (__flash_app_start) > + { > + PROVIDE (__excpt_ebase = ABSOLUTE(.)); > + __base = .; > + KEEP(* (.text.__exception_entry)) > + . = __base + __ebase_size; > + KEEP(* (SORT(.text.__isr_vec*))) > + /* Leave space for all the vector entries */ > + . = __base + __ebase_size + (__isr_vec_space * __isr_vec_count); > + ASSERT(__isr_vec_space == (DEFINED(__isr_vec_sw1) > + ? __isr_vec_sw1 - __isr_vec_sw0 > + : __isr_vec_space), > + "Actual ISR vector spacing does not match __isr_vec_space"); > + ASSERT(__base + __ebase_size == (DEFINED(__isr_vec_sw0) > + ? __isr_vec_sw0 > + : __base + __ebase_size), > + "__isr_vec_sw0 is not placed at EBASE + 0x200"); > + . = ALIGN(8); > + } = 0 > + > + .text . : AT (LOADADDR (.exception_vector) + SIZEOF(.exception_vector)) > { > + _ftext = . ; > + PROVIDE (eprol = .); > + *(.text) > + *(.text.*) > + *(.gnu.linkonce.t.*) > + *(.mips16.fn.*) > + *(.mips16.call.*) > + } > + .init . : AT (LOADADDR (.text) + SIZEOF(.text)) { > + KEEP (*(.init)) > + } > + .fini . : AT (LOADADDR (.init) + SIZEOF(.init)) { > + KEEP (*(.fini)) > + } > + .rel.sdata . : AT (LOADADDR (.fini) + SIZEOF(.fini)) { > + PROVIDE (__runtime_reloc_start = .); > + *(.rel.sdata) > + PROVIDE (__runtime_reloc_stop = .); > + } > + PROVIDE (etext = .); > + _etext = .; > + > + .eh_frame_hdr . : AT (LOADADDR (.rel.sdata) + SIZEOF(.rel.sdata)) { > *(.eh_frame_hdr) } > + .eh_frame . : AT (LOADADDR (.eh_frame_hdr) + SIZEOF(.eh_frame_hdr)) { > KEEP (*(.eh_frame)) } > + .gcc_except_table . : AT (LOADADDR (.eh_frame) + SIZEOF(.eh_frame)) { > *(.gcc_except_table) } > + .jcr . : AT (LOADADDR (.gcc_except_table) + SIZEOF(.gcc_except_table)) > { KEEP (*(.jcr)) } > + .ctors . : AT (LOADADDR (.jcr) + SIZEOF(.jcr)) > + { > + /* gcc uses crtbegin.o to find the start of > + the constructors, so we make sure it is > + first. Because this is a wildcard, it > + doesn't matter if the user does not > + actually link against crtbegin.o; the > + linker won't look for a file to match a > + wildcard. The wildcard also means that it > + doesn't matter which directory crtbegin.o > + is in. */ > + > + KEEP (*crtbegin.o(.ctors)) > + > + /* We don't want to include the .ctor section from > + from the crtend.o file until after the sorted ctors. > + The .ctor section from the crtend file contains the > + end of ctors marker and it must be last */ > + > + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) > + KEEP (*(SORT(.ctors.*))) > + KEEP (*(.ctors)) > + } > + > + .dtors . : AT (LOADADDR (.ctors) + SIZEOF(.ctors)) > + { > + KEEP (*crtbegin.o(.dtors)) > + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) > + KEEP (*(SORT(.dtors.*))) > + KEEP (*(.dtors)) > + } > + > + . = .; > + .MIPS.abiflags : { > + __MIPS_abiflags_start = .; > + *(.MIPS.abiflags) > + __MIPS_abiflags_end = .; > + } > + .rodata : { > + *(.rdata) > + *(.rodata) > + *(.rodata.*) > + *(.gnu.linkonce.r.*) > + } > + . = ALIGN(16); > + _fdata = .; > + .data : { > + *(.data) > + *(.data.*) > + *(.gnu.linkonce.d.*) > + } > + . = ALIGN(8); > + _gp = . + 0x8000; > + __global = _gp; > + .lit8 : { > + *(.lit8) > + } > + .lit4 : { > + *(.lit4) > + } > + .sdata : { > + *(.sdata) > + *(.sdata.*) > + *(.gnu.linkonce.s.*) > + } > + . = ALIGN(4); > + PROVIDE (edata = .); > + _edata = .; > + _fbss = .; > + .sbss : { > + *(.sbss) > + *(.sbss.*) > + *(.gnu.linkonce.sb.*) > + *(.scommon) > + } > + .bss : { > + _bss_start = . ; > + *(.bss) > + *(.bss.*) > + *(.gnu.linkonce.b.*) > + *(COMMON) > + } > + > + . = ALIGN(4); > + PROVIDE (end = .); > + _end = .; > + /* Now place the data that is only needed within start.S and can be > + overwritten by the heap. */ > + .startdata : { > + *(.startdata) > + } > + > + /* We do not support any runtime relocation handling with this script. > */ > + /DISCARD/ : { *(.rel.dyn) *(.rela.dyn) } > + > + /* DWARF debug sections. > + Symbols in the DWARF debugging sections are relative to > + the beginning of the section so we begin them at 0. */ > + > + /* DWARF 1 */ > + .debug 0 : { *(.debug) } > + .line 0 : { *(.line) } > + > + /* GNU DWARF 1 extensions */ > + .debug_srcinfo 0 : { *(.debug_srcinfo) } > + .debug_sfnames 0 : { *(.debug_sfnames) } > + > + /* DWARF 1.1 and DWARF 2 */ > + .debug_aranges 0 : { *(.debug_aranges) } > + .debug_pubnames 0 : { *(.debug_pubnames) } > + > + /* DWARF 2 */ > + .debug_info 0 : { *(.debug_info) } > + .debug_abbrev 0 : { *(.debug_abbrev) } > + .debug_line 0 : { *(.debug_line) } > + .debug_frame 0 : { *(.debug_frame) } > + .debug_str 0 : { *(.debug_str) } > + .debug_loc 0 : { *(.debug_loc) } > + .debug_macinfo 0 : { *(.debug_macinfo) } > + .debug_ranges 0 : { *(.debug_ranges) } > + > + /* SGI/MIPS DWARF 2 extensions */ > + .debug_weaknames 0 : { *(.debug_weaknames) } > + .debug_funcnames 0 : { *(.debug_funcnames) } > + .debug_typenames 0 : { *(.debug_typenames) } > + .debug_varnames 0 : { *(.debug_varnames) } > + > + /* Special sections generated by gcc */ > + /* Newer GNU linkers strip by default */ > + .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) } > + .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) } > + .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) } > + .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) } > + .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) } > + .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) } > + .gcc_compiled_long32 0 : { KEEP(*(.gcc_compiled_long32)) } > + .gcc_compiled_long64 0 : { KEEP(*(.gcc_compiled_long64)) } > +} > -- > 2.25.1 > >