This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH,MIPS 3/3] Setting of status register based on .MIPS.abiflags


Hi,

This patch adds support for automatically configuring a processor
based on the overall requirements of a program rather than just the
build flags used for the crt0.S module. The .MIPS.abiflags section as
defined in:

https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking

provides runtime accessible information about the requirements of a
program including architecture revision, size of registers, floating
point ABI, ASEs and ISA extensions.  From this information the
configurable aspects of a processor can be set to correctly execute
the code. In particular this includes correctly setting up the size
of the floating-point registers and enabling MSA if required. Further
configuration registers will be added in the future to handle other
ASEs but MSA is being used as the example.

When the .MIPS.abiflags section is missing then the code falls back to
the previous mechanism of configuring the core based on the flags used
to build crt0.S. However, the code to check for presence of an FPU has
been removed as it would always raise an exception if the FPU was
missing anyway which made it somewhat pointless.

This patch is dependent on the removal of .set noreorder in crt0.S.

Testing has been done using GNU SIM and checking that things like the
FPU are correctly enabled and disabled based on the content of
.MIPS.abiflags and also that the static definitions kick in when
.MIPS.abiflags is missing.

Thanks,
Matthew

libgloss/

2014-11-18  Jaydeep Patil  <jaydeep.patil@imgtec.com>
            Matthew Fortune  <matthew.fortune@imgtec.com

	* mips/crt0.S: Configure processor based on .MIPS.abiflags.
	Remove FPU availability check, just use the pre-processor flags
	to indicicate what the user wanted.
	* mips/abiflags.S: New file.
	* mips/regs.S (SR_MSA): Define macro.
	* mips/mti32.ld: Place .MIPS.abiflags and wrap in marker symbols.
	* mips/mti64.ld: Likewise.
	* mips/mti64_64.ld: Likewise.
	* mips/mti64_n32.ld: Likewise.
---
 libgloss/mips/abiflags.S   | 82 ++++++++++++++++++++++++++++++++++++++
 libgloss/mips/crt0.S       | 98 +++++++++++++++++++++++++++++++++-------------
 libgloss/mips/mti32.ld     |  6 +++
 libgloss/mips/mti64.ld     |  6 +++
 libgloss/mips/mti64_64.ld  |  6 +++
 libgloss/mips/mti64_n32.ld |  6 +++
 libgloss/mips/regs.S       |  2 +
 7 files changed, 178 insertions(+), 28 deletions(-)
 create mode 100644 libgloss/mips/abiflags.S

diff --git a/libgloss/mips/abiflags.S b/libgloss/mips/abiflags.S
new file mode 100644
index 0000000..953caaf
--- /dev/null
+++ b/libgloss/mips/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/crt0.S b/libgloss/mips/crt0.S
index f66ef1b..40d272b 100644
--- a/libgloss/mips/crt0.S
+++ b/libgloss/mips/crt0.S
@@ -14,12 +14,16 @@
  * 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.
@@ -82,45 +86,83 @@ _start:
 #    endif
 #  endif
 #endif
-	li	v0, STATUS_MASK
-	mtc0	v0, C0_SR
-	mtc0	zero, C0_CAUSE
+
+	/* Clear Cause register.  */
+	mtc0	zero,C0_CAUSE
 	nop
 
-	/* Avoid hazard from FPU enable and other SR changes.  */
-	LA (t0, hardware_hazard_hook)
-	beq	t0,zero,1f
-	jalr	t0
-1:
+	/* 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.  */
+	bne	t0,t1,1f
 
-/* Check for FPU presence.  Don't check if we know that soft_float is
-   being used.  (This also avoids illegal instruction exceptions.)  */
+	/* 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
 
-#ifndef __mips_soft_float
-	li	t2,0xAAAA5555
-	mtc1	t2,fp0		/* write to FPR 0 */
-	mtc1	zero,fp1	/* write to FPR 1 */
-	mfc1	t0,fp0
-	mfc1	t1,fp1
-	nop
-	bne	t0,t2,1f	/* check for match */
-	bne	t1,zero,1f	/* double check */
-	j	2f		/* FPU is present. */
-#endif
 1:
-	/* FPU is not present.  Set status register to say that. */
-	li	v0, (STATUS_MASK-(STATUS_MASK & SR_CU1))
-	mtc0	v0, C0_SR
+	/* 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 FPU disable.  */
-	LA (t0, hardware_hazard_hook)
+
+	/* 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.  */
+/* Fix high bits, if any, of the PC so that exception handling doesn't get
+   confused.  */
 	LA (v0, 3f)
 	jr	v0
 3:
diff --git a/libgloss/mips/mti32.ld b/libgloss/mips/mti32.ld
index 715639e..2739c62 100644
--- a/libgloss/mips/mti32.ld
+++ b/libgloss/mips/mti32.ld
@@ -93,6 +93,11 @@ SECTIONS
   }
 
   . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
   .rodata : {
     *(.rdata)
     *(.rodata)
@@ -137,6 +142,7 @@ SECTIONS
     *(COMMON)
   }
 
+  . = ALIGN(4);
   PROVIDE (end = .);
   _end = .;
 
diff --git a/libgloss/mips/mti64.ld b/libgloss/mips/mti64.ld
index 1bd11f6..15975ad 100644
--- a/libgloss/mips/mti64.ld
+++ b/libgloss/mips/mti64.ld
@@ -95,6 +95,11 @@ SECTIONS
   }
 
   . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
   .rodata : {
     *(.rdata)
     *(.rodata)
@@ -139,6 +144,7 @@ SECTIONS
     *(COMMON)
   }
 
+  . = ALIGN(4);
   PROVIDE (end = .);
   _end = .;
 
diff --git a/libgloss/mips/mti64_64.ld b/libgloss/mips/mti64_64.ld
index a058b96..7a2074f 100644
--- a/libgloss/mips/mti64_64.ld
+++ b/libgloss/mips/mti64_64.ld
@@ -98,6 +98,11 @@ SECTIONS
   }
 
   . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
   .rodata : {
     *(.rdata)
     *(.rodata)
@@ -142,6 +147,7 @@ SECTIONS
     *(COMMON)
   }
 
+  . = ALIGN(4);
   PROVIDE (end = .);
   _end = .;
 
diff --git a/libgloss/mips/mti64_n32.ld b/libgloss/mips/mti64_n32.ld
index 279571b..4003845 100644
--- a/libgloss/mips/mti64_n32.ld
+++ b/libgloss/mips/mti64_n32.ld
@@ -98,6 +98,11 @@ SECTIONS
   }
 
   . = .;
+  .MIPS.abiflags : {
+    __MIPS_abiflags_start = .;
+    *(.MIPS.abiflags)
+    __MIPS_abiflags_end = .;
+  }
   .rodata : {
     *(.rdata)
     *(.rodata)
@@ -142,6 +147,7 @@ SECTIONS
     *(COMMON)
   }
 
+  . = ALIGN(4);
   PROVIDE (end = .);
   _end = .;
 
diff --git a/libgloss/mips/regs.S b/libgloss/mips/regs.S
index bdf933f..e4b1343 100644
--- a/libgloss/mips/regs.S
+++ b/libgloss/mips/regs.S
@@ -98,6 +98,8 @@
 #define SR_SX		0x00000040	/* Supervisor extended addressing enabled */
 #define SR_UX		0x00000020	/* User extended addressing enabled */
 
+#define SR_MSA		0x08000000	/* MSA ASE */
+
 /* Standard (R4000) cache operations. Taken from "MIPS R4000
    Microprocessor User's Manual" 2nd edition: */
 
-- 
1.9.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]