[PATCH,MIPS 3/3] Setting of status register based on .MIPS.abiflags
Matthew Fortune
Matthew.Fortune@imgtec.com
Tue Nov 18 12:26:00 GMT 2014
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
More information about the Newlib
mailing list