Commit 9dadbd27 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Add support for reporting the ARMv8 MVFR2 register. Improve safety of context switches.

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'
parent 07248a44
No preview for this file type
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "0.12"
Module_Version SETA 12
Module_MajorVersion SETS "0.13"
Module_Version SETA 13
Module_MinorVersion SETS ""
Module_Date SETS "20 Feb 2017"
Module_ApplicationDate SETS "20-Feb-17"
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.12"
Module_HelpVersion SETS "0.12 (20 Feb 2017)"
Module_FullVersion SETS "0.13"
Module_HelpVersion SETS "0.13 (20 Feb 2018)"
END
/* (0.12)
/* (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.12
#define Module_MajorVersion_CMHG 0.13
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 20 Feb 2017
#define Module_Date_CMHG 20 Feb 2018
#define Module_MajorVersion "0.12"
#define Module_Version 12
#define Module_MajorVersion "0.13"
#define Module_Version 13
#define Module_MinorVersion ""
#define Module_Date "20 Feb 2017"
#define Module_Date "20 Feb 2018"
#define Module_ApplicationDate "20-Feb-17"
#define Module_ApplicationDate "20-Feb-18"
#define Module_ComponentName "VFPSupport"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/VFPSupport"
#define Module_FullVersion "0.12"
#define Module_HelpVersion "0.12 (20 Feb 2017)"
#define Module_LibraryVersionInfo "0:12"
#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
......@@ -377,7 +378,9 @@ NoMVFR ; Currently we don't cope with situations where the MVFR registers are ab
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
......@@ -388,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
......@@ -736,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
......@@ -937,6 +955,7 @@ FeaturesJumpTable
B Feature_SystemRegs
B Feature_VFPExceptions
B Feature_Misc
B Feature_SystemRegs2
EndOfFeaturesJumpTable
UnknownFeature
......@@ -990,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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment