Source
...
Target
Commits (3)
  • Ben Avison's avatar
    Support ARMv8 (and potentially some ARMv7) cores. · dbed9538
    Ben Avison authored
    Detail:
      Replace conditionally executed undefined instructions with branches over
      on opposite condition.
    Admin:
      Tested on Raspberry Pi 3.
    
    Version 0.11. Tagged as 'VFPSupport-0_11'
    dbed9538
  • Jeffrey Lee's avatar
    Don't claim to support software emulation of short vectors if the FPSCR... · 07248a44
    Jeffrey Lee authored
    Don't claim to support software emulation of short vectors if the FPSCR doesn't implement the LEN/STRIDE fields
    
    Detail:
      In ARMv8, VFP short vectors are completely obsolete, to the point where implementations aren't even required to implement the FPSCR fields that control their operation.
      Our software short vector emulation relies on the hardware taking the undefined instruction vector when a VFP data processing op is executed with the LEN/STRIDE fields set to non-zero values; if those fields are hard-wired to zero then our emulation can never be run.
      File changes:
      - s/Module - Check whether FPSCR LEN+STRIDE fields are implemented before deciding whether to install the short vector support code
      - Test/test7,ffb - Refuse to run if short vectors aren't supported (whether hardware or software). Bail out early if we spot an FPSCR inconsistency.
    Admin:
      Tested on Cortex-A53, Cortex-A7
    
    
    Version 0.12. Tagged as 'VFPSupport-0_12'
    07248a44
  • Jeffrey Lee's avatar
    Add support for reporting the ARMv8 MVFR2 register. Improve safety of context switches. · 9dadbd27
    Jeffrey Lee authored
    Detail:
      hdr/VFPSupport - Define VFPSupport_Features reason code 3, for reading extra feature registers
      s/Macros - Use ELIF to shorten myVMRS & myVMSR macros. Add MVFR2 support to myVMRS.
      s/Module - Implement VFPSupport_Features 3, for reading MVFR2 (and three other values reserved for future proofing). Since there doesn't seem to be an easy way of detecting the presence of MVFR2, we fall back on a list of known-good FPSID values, like with MVFR0/MVFR1 on pre-VFPv3 systems. Also update VFPSupport_ChangeContext to do a dummy load from the new VFP context, to help trap bad contexts before we've updated our state to indicate that that context is active.
      Test/features,ffb - Add VFPSupport_Features 3 output
    Admin:
      Tested on Raspberry Pi 1, 2, 3
    
    
    Version 0.13. Tagged as 'VFPSupport-0_13'
    9dadbd27
No preview for this file type
No preview for this file type
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "0.10"
Module_Version SETA 10
Module_MajorVersion SETS "0.13"
Module_Version SETA 13
Module_MinorVersion SETS ""
Module_Date SETS "08 Feb 2015"
Module_ApplicationDate SETS "08-Feb-15"
Module_Date SETS "20 Feb 2018"
Module_ApplicationDate SETS "20-Feb-18"
Module_ComponentName SETS "VFPSupport"
Module_ComponentPath SETS "mixed/RiscOS/Sources/HWSupport/VFPSupport"
Module_FullVersion SETS "0.10"
Module_HelpVersion SETS "0.10 (08 Feb 2015)"
Module_FullVersion SETS "0.13"
Module_HelpVersion SETS "0.13 (20 Feb 2018)"
END
/* (0.10)
/* (0.13)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.10
#define Module_MajorVersion_CMHG 0.13
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 08 Feb 2015
#define Module_Date_CMHG 20 Feb 2018
#define Module_MajorVersion "0.10"
#define Module_Version 10
#define Module_MajorVersion "0.13"
#define Module_Version 13
#define Module_MinorVersion ""
#define Module_Date "08 Feb 2015"
#define Module_Date "20 Feb 2018"
#define Module_ApplicationDate "08-Feb-15"
#define Module_ApplicationDate "20-Feb-18"
#define Module_ComponentName "VFPSupport"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/VFPSupport"
#define Module_FullVersion "0.10"
#define Module_HelpVersion "0.10 (08 Feb 2015)"
#define Module_LibraryVersionInfo "0:10"
#define Module_FullVersion "0.13"
#define Module_HelpVersion "0.13 (20 Feb 2018)"
#define Module_LibraryVersionInfo "0:13"
......@@ -86,6 +86,7 @@ VFPSupport_Field_RegDump * 5
VFPSupport_Features_SystemRegs * 0
VFPSupport_Features_VFPExceptions * 1
VFPSupport_Features_Misc * 2
VFPSupport_Features_SystemRegs2 * 3
; Misc feature flags
VFPSupport_MiscFeature_VFPVectors_HW * 1 :SHL: 0 ; VFP short vectors are supported by hardware
......
......@@ -48,55 +48,41 @@
; VMRS
MACRO
myVMRS $cond,$reg,$fpreg
[ "$fpreg" = "FPSID"
[ "$fpreg" = "FPSID"
MRC$cond p10,7,$reg,c0,c0,0
|
[ "$fpreg" = "FPSCR"
ELIF "$fpreg" = "FPSCR"
MRC$cond p10,7,$reg,c1,c0,0
|
[ "$fpreg" = "MVFR1"
ELIF "$fpreg" = "MVFR2"
MRC$cond p10,7,$reg,c5,c0,0
ELIF "$fpreg" = "MVFR1"
MRC$cond p10,7,$reg,c6,c0,0
|
[ "$fpreg" = "MVFR0"
ELIF "$fpreg" = "MVFR0"
MRC$cond p10,7,$reg,c7,c0,0
|
[ "$fpreg" = "FPEXC"
ELIF "$fpreg" = "FPEXC"
MRC$cond p10,7,$reg,c8,c0,0
|
[ "$fpreg" = "FPINST"
ELIF "$fpreg" = "FPINST"
MRC$cond p10,7,$reg,c9,c0,0
|
ASSERT "$fpreg" = "FPINST2"
MRC$cond p10,7,$reg,c10,c0,0
]
]
]
]
]
]
MEND
; VMSR
MACRO
myVMSR $cond,$fpreg,$reg
[ "$fpreg" = "FPSID"
[ "$fpreg" = "FPSID"
MCR$cond p10,7,$reg,c0,c0,0
|
[ "$fpreg" = "FPSCR"
ELIF "$fpreg" = "FPSCR"
MCR$cond p10,7,$reg,c1,c0,0
|
[ "$fpreg" = "FPEXC"
ELIF "$fpreg" = "FPEXC"
MCR$cond p10,7,$reg,c8,c0,0
|
[ "$fpreg" = "FPINST"
ELIF "$fpreg" = "FPINST"
MCR$cond p10,7,$reg,c9,c0,0
|
ASSERT "$fpreg" = "FPINST2"
MCR$cond p10,7,$reg,c10,c0,0
]
]
]
]
MEND
......
......@@ -98,6 +98,7 @@ BadClasses # 4 ; Instruction class flags which indicate it's not a va
SoftFPSID # 4 ; FPSID
SoftMVFR0 # 4 ; MVFR0
SoftMVFR1 # 4 ; MVFR1
SoftMVFR2 # 4 ; MVFR2
ExceptionContext # 4
ExceptionDump # :INDEX:Context_RegDump+MaxDRegs*8
......@@ -107,7 +108,7 @@ WSSize * :INDEX: @
Subarch_VFPv1_IMP * 0 ; VFPv1 arch with implementation defined subarch
Subarch_VFPv2_v1Sub * 1 ; VFPv2 arch with v1 common subarch (ARM1176JZF-S)
Subarch_VFPv3_v2Sub * 2 ; >=VFPv3 arch with v2 common subarch (Cortex-A7)
Subarch_VFPv3_NoSub * 3 ; >=VFPv3 arch with no subarch (Cortex-A8, Cortex-A9)
Subarch_VFPv3_NoSub * 3 ; >=VFPv3 arch with no subarch (Cortex-A8, Cortex-A9, Cortex-A53)
Subarch_VFPv3_v3Sub * 4 ; >=VFPv3 arch with v3 common subarch (Cortex-A15)
......@@ -258,9 +259,10 @@ CheckHardware
MRC p15,0,r3,c1,c0,2 ; read it back to get status
AND r4, r3, #&F<<20
CMP r4, #&F<<20
MCRNE p15,0,r2,c1,c0,2 ; restore original CPACR
BNE NoVFP_v6v7
CMP r0, #&F
BEQ %FT05
MCR p15,0,r2,c1,c0,2 ; restore original CPACR
B NoVFP_v6v7
05 CMP r0, #&F
BNE %FT10
; Both ARMv6 and ARMv7 identify themselves with &F in the main ID register
; To work out which is which, it looks like the only (or easiest) way is to check the cache type register
......@@ -366,16 +368,19 @@ BadVFP
NoMVFR ; Currently we don't cope with situations where the MVFR registers are absent
; Restore CPACR if ARMv6+
CMP r0, #&7
MCRGE p15,0,r2,c1,c0,2
myISB GE,r0 ; Deal with pipelined CP15 ops on ARMv6+. TODO - ARMv5
; Restore interrupts
BLT %FT01
MCR p15,0,r2,c1,c0,2
myISB ,r0 ; Deal with pipelined CP15 ops on ARMv6+. TODO - ARMv5
01 ; Restore interrupts
MSR CPSR_c, R1
ADRL r0, ErrorBlock_VFPSupport_BadHW
B ReturnError_Stacked
HasMVFRTable
DCW &FFF0 ; FPSID mask (part & variant fields)
DCW &20B0 ; VFP11
; Bottom nibble of the below values are used to store the number of implemented feature registers
DCW &20B2 ; VFP11 has MVFR0, MVFR1
DCW &4033 ; Cortex-A53 has MVFR0, MVFR1, MVFR2
DCW 0
ALIGN
......@@ -386,37 +391,47 @@ GoodVFP
; r3 = FPSID subarchitecture field
; r4 = FPSID
; Read MVFR0/1 if they're available
CMP r3, #Subarch_VFPv2_v1Sub<<16
BGE HasMVFR ; Subarchitecture 2+ is required to have them
; In subarchitecture 1 and below, the registers are optional.
; E.g. VFP9-S doesn't have them but VFP11 does, even though they're both subarchitecture 1/VFPv2.
; Search through a list of VFP variants which are known to contain the registers
; For ARMv8, there's also the MVFR2 register, which isn't present on earlier ARM versions, and can't be probed for since access to undefined registers is unpredictable
; So to deal with these annoying cases, search through a list of VFP variants which are known to contain specific numbers of registers
ADR r7, HasMVFRTable
LDRH r8, [r7], #2
AND r8, r8, r4
10
LDRH r9, [r7], #2
CMP r9, #0
BEQ NoMVFR
CMP r9, r8
BEQ HasMVFR
BEQ %FT20
EOR r9, r9, r8
CMP r9, #16
BLO HasMVFR
B %BT10
20
; Subarchitecture 2+ is required to have at least MVFR0 & MVFR1
CMP r3, #Subarch_VFPv2_v1Sub<<16
BLO NoMVFR
MOV r9, #2
; Fall through...
HasMVFR
myVMRS ,r5,MVFR0
MOV r7, #0
myVMRS ,r5,MVFR0 ; Assume the first two are always present
myVMRS ,r6,MVFR1
CMP r9, #3
myVMRS GE,r7,MVFR2
; Done for now, make sure VFP access is disabled
; For the moment we just disable access via the FPEXC.EN bit. This will disable everything except VMSR & VMRS from privileged modes
MOV r7, #0
myVMSR ,FPEXC, r7
MOV lr, #0
myVMSR ,FPEXC, lr
; Store our results
; TODO - Calculate fake MVFR0/MVFR1 values where necessary
MOV r3, r3, LSR #16
STRB r3, VFPSubarch
STR r4, SoftFPSID
STR r5, SoftMVFR0
STR r6, SoftMVFR1
; Work out how many registers there are
ASSERT SoftMVFR0 = SoftFPSID+4
ASSERT SoftMVFR1 = SoftFPSID+8
ASSERT SoftMVFR2 = SoftFPSID+12
ADR lr, SoftFPSID
STMIA lr, {r4-r7}
; Work out how many data registers there are
; Assumes we've faked up MVFR0!
AND r3, r5, #&F
CMP r3, #2
......@@ -470,9 +485,10 @@ InstallHandler ROUT
; * Cortex-A9: Support code required for short vector support. Indicated by Subarch_VFPv3_NoSub, no response to FPEXC EX, but response to DEX (+ MVFR0 indicates no short vector support)
; * Cortex-A7: Support code required for short vector support. Indicated by Subarch_VFPv3_v2Sub, no response to FPEXC EX, but response to DEX (+ MVFR0 indicates no short vector support)
; * Cortex-A15: Support code required for short vector support. Also requires special abort handler due to lack of DEX. Indicated by Subarch_VFPv3_v3Sub, no response to FPEXC EX & DEX bits (+ MVRF0 indicates no short vector support)
; * Cortex-A53: Support code not required. Indicated by Subarch_VFPv3_NoSub & no response to FPEXC EX & DEX bits. Also no possibility of emulating short vector support (FPSCR LEN/STRIDE is zero)
; So logic to follow is:
; * If EX or DEX supported, pick based around SubArch version
; * If MVFR0 indicates no short vector support, use special abort handler
; * If MVFR0 indicates no short vector support, and FPSCR LEN/STRIDE can be set, use special abort handler
; When testing for support, avoid setting both EX and DEX at once, as that's an invalid combination
MOV r10, #0 ; r10 is used as our 'support handler installed' flag
MOV r11, #FPEXC_EX
......@@ -489,7 +505,17 @@ InstallHandler ROUT
LDR r11, SoftMVFR0
TST r11, #&F<<24
BNE %FT80 ; (no support code needed at all)
; Short vector support required
; Short vectors not supported in hardware, install support code to emulate them if the FPSCR has LEN+STRIDE fields
MOV r11, #FPEXC_EN
myVMSR ,FPEXC,r11
MOV r11, #&310000 ; length 2, stride 2
myVMSR ,FPSCR,r11
myVMRS ,r10,FPSCR
TEQ r10,r11
MOV r10,#0
myVMSR ,FPEXC,r10
BNE %FT80 ; (short vector emulation not possible)
; Short vector emulation possible
ADRL r10, VFPSupportCode_SV
ADR r0, SupportHandlerTemplateSV
B %FT50
......@@ -723,6 +749,11 @@ SWI_ChangeContext
; TODO - rewrite to use state machine based around array of function pointers?
; TODO - make use of user mode flag
Entry "r1-r4"
; Perform a dummy load from the context ptr so that if it's bad we'll
; crash now instead of after we've updated a load of state (n.b. we
; should really check the high address as well)
CMP r0, #0
LDRNE r2, [r0]
MRS r4, CPSR
ORR r3, r4, #I32_bit
MSR CPSR_c, r3
......@@ -924,6 +955,7 @@ FeaturesJumpTable
B Feature_SystemRegs
B Feature_VFPExceptions
B Feature_Misc
B Feature_SystemRegs2
EndOfFeaturesJumpTable
UnknownFeature
......@@ -977,6 +1009,18 @@ Feature_Misc ROUT
; Insert new flags here
MOV pc, lr
Feature_SystemRegs2
; in: R0 = 3
; out: R0 = MVFR2
; R1 = Reserved (zero)
; R2 = Reserved (zero)
; R3 = Reserved (zero)
LDR r0, SoftMVFR2
MOV r1, #0
MOV r2, #0
MOV r3, #0
MOV pc, lr
SWI_ExceptionDump
; in: R0 = flags
; R1 = context (if Create)
......