Commit 1355ea60 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Tweak VFPSupport API and add support for contexts stored in application space

  s/Module, hdr/VFPSupport - New/changed features:
  - Contexts can now be flagged as being in application space if they're created with the VFPSupport_Context_AppSpace flag
  - VFPSupport_ChangeContext accepts a VFPSupport_ChangeContext_AppSpace flag, which will force the context change to occur in a nonlazy manner if the currently active context is in application space
  - VFPSupport_CreateContext accepts a VFPSupport_CreateContext_LazyActivate flag, to indicate that after creation the context should be activated lazily (unlike VFSupport_CreateContext_Activate)
  - VFPSupport_Context_Activate renamed to VFPSupport_CreateContext_Activate for clarity
  - VFPSupport_CheckContext now ignores the Activate/LazyActivate flags, so the same flag word can be passed to Check & Create
  - "Context ID" simplified to just "Context pointer", as an indiciation of the fact that I now have no plans to make VFPSupport keep a master list of extant contexts
    - This makes it legal for programs to move/copy/delete contexts as long as they've made sure that the ExamineContext doesn't indicate that any part of the context is active
  - VFPSupport_ExamineContext now returns the context size in R4 instead of the context ID
  Test/test1,ffb - Updated to work with new API
  Tested on rev A2 BB-xM.
  VFPSupport_ExamineContext change is backwards-incompatible!

Version 0.02. Tagged as 'VFPSupport-0_02'
parent 636765ec
......@@ -32,6 +32,7 @@ DIM temp% 128
REM VFPSupport_Version
SYS "VFPSupport_Version" TO A
PRINT "VFPSupport version ";(A/100)
IF A<2 THEN PRINT "Version too old!" : END
REM VFPSupport_Features
SYS "VFPSupport_Features" TO A,B,C
......@@ -154,22 +155,26 @@ REM VFPSupport_ExmaineContext
DEF PROCExamine(ctx%,serialise%)
LOCAL flags%,regs%,status%,format%,dump%,reg%,type%,offset%
SYS "VFPSupport_ExamineContext",ctx%,serialise% TO flags%,regs%,status%,format%,dump%
SYS "VFPSupport_ExamineContext",ctx%,serialise% TO flags%,regs%,status%,format%,size%
dump% = ctx%
PRINT "Context &";FNhex8(ctx%);" status:"
PRINT " Flags = &";FNhex8(flags%);":"
IF flags% AND 1 THEN PRINT " Supports usermode operation" ELSE PRINT " Privileged operation only"
IF flags% AND 2 THEN PRINT " Is located in application space" ELSE PRINT " Isn't located in application space"
IF flags% AND (1<<29) THEN PRINT " Awaiting lazy activation" ELSE PRINT " Not awaiting lazy activation"
IF flags% AND (1<<30) THEN PRINT " Status registers active" ELSE PRINT " Status registers inactive"
IF flags% AND (1<<31) THEN PRINT " Memory allocated by VFPSupport" ELSE PRINT " Memory allocated by user"
IF flags% AND &1FFFFFFE THEN PRINT " Unknown flag bits set!"
IF flags% AND &1FFFFFFC THEN PRINT " Unknown flag bits set!"
PRINT " Register count = ";regs%
PRINT " Register status = &";FNhex8(status%)
PRINT " Context size = ";size%;" bytes"
PRINT " Dump at &";FNhex8(dump%);" format &";FNhex8(format%);":"
WHILE format%!0<>-1
type%=format%?0 + ((format%?1)<<8)
offset%=format%?2 + ((format%?3)<<8)
PRINT " Type ";type%;" offset ";offset%;": ";
IF offset%+4>=size% THEN PRINT "ERROR: Offset is outside context" : END
CASE type% OF
WHEN 0: PRINT "FPSCR=&";FNhex8(dump%!offset%)
WHEN 1: PRINT "FPEXC=&";FNhex8(dump%!offset%)
......@@ -260,11 +265,11 @@ ENDPROC
DEF FNGetRegs(ctx%)
LOCAL format%,dump%,type%,offset%
SYS "VFPSupport_ExamineContext",ctx%,1 TO ,,,format%,dump%
SYS "VFPSupport_ExamineContext",ctx%,1 TO ,,,format%
WHILE format%!0<>-1
type%=format%?0 + ((format%?1)<<8)
offset%=format%?2 + ((format%?3)<<8)
IF type%=5 THEN =dump%+offset%
IF type%=5 THEN =ctx%+offset%
PRINT "ERROR: Failed to find registers in context dump" : END
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "0.01"
Module_Version SETA 1
Module_MajorVersion SETS "0.02"
Module_Version SETA 2
Module_MinorVersion SETS ""
Module_Date SETS "25 Nov 2010"
Module_ApplicationDate SETS "25-Nov-10"
Module_Date SETS "01 Feb 2011"
Module_ApplicationDate SETS "01-Feb-11"
Module_ComponentName SETS "VFPSupport"
Module_ComponentPath SETS "bsd/RiscOS/Sources/HWSupport/VFPSupport"
Module_FullVersion SETS "0.01"
Module_HelpVersion SETS "0.01 (25 Nov 2010)"
Module_FullVersion SETS "0.02"
Module_HelpVersion SETS "0.02 (01 Feb 2011)"
/* (0.01)
/* (0.02)
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
#define Module_MajorVersion_CMHG 0.01
#define Module_MajorVersion_CMHG 0.02
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 25 Nov 2010
#define Module_Date_CMHG 01 Feb 2011
#define Module_MajorVersion "0.01"
#define Module_Version 1
#define Module_MajorVersion "0.02"
#define Module_Version 2
#define Module_MinorVersion ""
#define Module_Date "25 Nov 2010"
#define Module_Date "01 Feb 2011"
#define Module_ApplicationDate "25-Nov-10"
#define Module_ApplicationDate "01-Feb-11"
#define Module_ComponentName "VFPSupport"
#define Module_ComponentPath "bsd/RiscOS/Sources/HWSupport/VFPSupport"
#define Module_FullVersion "0.01"
#define Module_HelpVersion "0.01 (25 Nov 2010)"
#define Module_LibraryVersionInfo "0:1"
#define Module_FullVersion "0.02"
#define Module_HelpVersion "0.02 (01 Feb 2011)"
#define Module_LibraryVersionInfo "0:2"
......@@ -46,12 +46,14 @@ SWIClass SETS VFPSupportSWI_Name
VFPSupportSWICheckValue * @
; Flags suitable for CheckContext
; Base flags used for CheckContext, CreateContext, ExamineContext
VFPSupport_Context_UserMode * 1 :SHL: 0
VFPSupport_Context_AppSpace * 1 :SHL: 1
; Additional flags suitable for CreateContext
VFPSupport_Context_LazyActivate * 1 :SHL: 30
VFPSupport_Context_Activate * 1 :SHL: 31
; Additional flags returned by ExamineContext
......@@ -63,6 +65,7 @@ VFPSupport_Context_VFPMemory * 1 :SHL: 31
; Flags for ChangeContext
VFPSupport_ChangeContext_Lazy * 1 :SHL: 0
VFPSupport_ChangeContext_AppSpace * 1 :SHL: 1
; Flags for ExamineContext
......@@ -342,13 +342,18 @@ UnknownSWI
; in: R0 = flags
; b0 = user mode flag (0=user mode access not required, 1=user mode access required)
; b1 = application space flag (0=not in application space, 1=in application space)
; b30 = ignored (for CreateContext compatability)
; b31 = ignored (for CreateContext compatability)
; other bits reserved, sbz
; R1 = number of doubleword registers required (1-32)
; out: R0 = required size of context save area
; Validate flags & reg count
CMP r1,#0
CMP r0,#1
; Note that this next bit relies on C being set by the above CMP
ASSERT VFPSupport_Context_UserMode+VFPSupport_Context_AppSpace+VFPSupport_Context_LazyActivate+VFPSupport_Context_Activate >= &80000000 ; Must clear sign bit
BICS r0,r0,#VFPSupport_Context_UserMode+VFPSupport_Context_AppSpace+VFPSupport_Context_LazyActivate+VFPSupport_Context_Activate
CMPLS r1,r0
MOVLS r0,#Context_RegDump
......@@ -362,16 +367,18 @@ SWI_CheckContext
; in: R0 = flags
; b0 = user mode flag (0=user mode access not required, 1=user mode access required)
; b1 = application space flag (0=not in application space, 1=in application space)
; b30 = lazy activation flag (0=leave context inactive, 1=activate lazily. Supercedes b31.)
; b31 = activate flag (0=leave context inactive, 1=activate now)
; other bits reserved, sbz
; R1 = number of doubleword registers required (1-32)
; R2 = pointer to word-aligned context save area of the size indicated by VFPSupport_CheckContext, or 0 if VFPSupport is to allocate memory itself
; R3 = FPSCR value to initialise context with
; out: R0 = context ID
; out: R0 = context pointer
; R1 = previously active context ID/preserved
Push "r0-r3,lr"
CMP r2,#0
BIC r0,r0,#VFPSupport_Context_Activate
BIC r0,r0,#VFPSupport_Context_LazyActivate+VFPSupport_Context_Activate ; Clear unwanted flags
BL SWI_CheckContext
MOVVC r3,r0
......@@ -394,19 +401,21 @@ SWI_CreateContext
Pull "r1" ; Actually R0 on input
MOV r0,r2
TST r1,#VFPSupport_Context_Activate
Pull "r1-r3,pc",EQ
TST r1,#VFPSupport_Context_LazyActivate+VFPSupport_Context_Activate ; Check activation flags
Pull "r1-r3,pc",EQ ; Exit if context doesn't need activating
STR r0,[sp]
MOV r1,#0 ; activate non-lazily
ASSERT VFPSupport_Context_Activate = &80000000
MOVMI r1,#0 ; Nonlazy activation
MOVPL r1,#VFPSupport_ChangeContext_Lazy ; Lazy activation
BL SWI_ChangeContext
; Assumes that ChangeContext won't return an error
MOV r1,r0
Pull "r0,r2-r3,pc"
; in: R0 = context ID
; R1 = context ID to activate if R0 was the active context
; out: R0 = context ID that's now active
; in: R0 = context to destroy
; R1 = context to activate if R0 was the active context
; out: R0 = context that's now active
Entry "r1-r4"
ORR r3, r4, #I32_bit
......@@ -436,21 +445,33 @@ SWI_DestroyContext
; in: R0 = context ID to activate
; in: R0 = context to activate
; R1 = flags
; b0 = lazy activation (0=activate now, 1=use lazy activation)
; b1 = application space changing (0=no change, 1=changing)
; other bits reserved, sbz
; out: R0 = previously active context ID
; out: R0 = previously active context
; TODO - rewrite to use state machine based around array of function pointers?
; TODO - make use of user mode flag
Entry "r1-r4"
ORR r3, r4, #I32_bit
MSR CPSR_c, r3
; If application space is being moved, and ActiveContext is in app
; space, clear the lazy activation flag to ensure that the context
; gets flushed out of the system
LDR r3, ActiveContext
TST r1, #VFPSupport_ChangeContext_AppSpace
CMP r3, #0
LDRNE r2, [r3, #Context_Flags]
ASSERT VFPSupport_Context_AppSpace = VFPSupport_ChangeContext_Lazy*2
BICNE r1, r1, r2, LSR #1
LDR r2, LazyContext
TST r1, #VFPSupport_ChangeContext_Lazy
LDR r1, ActiveContext
STR r0, LazyContext
MOV r1, r3
BEQ ChangeContext_Now
; Lazy activation
CMP r2, r0
......@@ -504,39 +525,36 @@ ChangeContext_Exit_IRQ_R2_Disable
; in: R0 = context ID
; in: R0 = context
; R1 = flags
; b0 = Serialise context
; out: R0 = flags:
; b0 = User mode flag (0=user mode access not required, 1=user mode access required)
; b1 = application space flag (0=not in application space, 1=in application space)
; b29 = context is awaiting lazy activation (1=yes, 0=no)
; b30 = context status registers are active (1=active, 0=saved)
; b31 = memory allocation method (0=user allocated, 1=VFPSupport allocated)
; R1 = number of doubleword registers (may be greater than number requested upon context creation)
; R2 = register status. bit n is 1 if doubleword register is active, 0 if saved.
; R3 = pointer to dump format descriptor block
; R4 = pointer to context register dump
CMP r0, #0
ADRL r0, ErrorBlock_BadContext
B ReturnError_LR
TST r1, #VFPSupport_ExamineContext_Serialise
; R4 = context size
MOVS r4, r0
; Serialise it the easy way
TST r1, #VFPSupport_ExamineContext_Serialise
; Serialise it if it's active
; TODO - Do something a bit more sophisticated!
Push "r0-r1,lr"
LDR r1, [r0, #Context_NumRegs]
MOV r0, #VFPSupport_Context_Activate
MOV r2, #0
MOV r3, #0
BL SWI_CreateContext
BLVC SWI_DestroyContext
ADDVS sp, sp, #4
Pull "pc",VS
Pull "r0-r1,lr"
MOV r4, r0
LDR r2, ActiveContext
CMP r2, r0
MOV r3, lr
MOV r0, #0
MOV r1, #0
BL SWI_ChangeContext ; Deactivate it
BLVC SWI_ChangeContext ; Reactivate it
MOVVS pc, r3
MOV lr, r3
; Check the FPEXC value in the dump as a method of determining which format of descriptor block we should use
; This won't work too well if programs use this as a method of inserting fake exceptions!
LDR r2, [r0, #Context_FPEXC]
......@@ -560,8 +578,14 @@ SWI_ExamineContext
MOVNE r2, #0
ORREQ r0, r0, #VFPSupport_Context_StatusRegsActive
RSBEQ r2, r2, r2, LSL r1
; Compute R4
MOV r4, #Context_RegDump
ADD r4, r4,r1,LSL #3
MOV pc, lr
ADRL r0, ErrorBlock_BadContext
B ReturnError_LR
DCD VFPSupport_Field_FPINST2 + Context_FPINST2<<16
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