Commit f6c764dd authored by Robert Sprowson's avatar Robert Sprowson
Browse files

Add support for LDRSB to data abort handler

ARM600:
Decode LDRSB, do the sign extend, and fault all the other loads and stores not understood.
VMSAv6:
As the loads and stores not understood are now vetted properly, it should be safe to UseProcessTransfer (previously they'd have been disassembled incorrectly).
Paste in LDRSB code from ARM600.
Fix dubious looking access of CurrentGraphicsVDriver from WsPtr.

Tested briefly on StrongARM.

Version 5.35, 4.79.2.209. Tagged as 'Kernel-5_35-4_79_2_209'
parent 55118466
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.208"
Module_Date SETS "19 Jan 2014"
Module_ApplicationDate SETS "19-Jan-14"
Module_MinorVersion SETS "4.79.2.209"
Module_Date SETS "26 Jan 2014"
Module_ApplicationDate SETS "26-Jan-14"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.208)"
Module_HelpVersion SETS "5.35 (19 Jan 2014) 4.79.2.208"
Module_FullVersion SETS "5.35 (4.79.2.209)"
Module_HelpVersion SETS "5.35 (26 Jan 2014) 4.79.2.209"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.208
#define Module_Date_CMHG 19 Jan 2014
#define Module_MinorVersion_CMHG 4.79.2.209
#define Module_Date_CMHG 26 Jan 2014
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.208"
#define Module_Date "19 Jan 2014"
#define Module_MinorVersion "4.79.2.209"
#define Module_Date "26 Jan 2014"
#define Module_ApplicationDate "19-Jan-14"
#define Module_ApplicationDate "26-Jan-14"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.208)"
#define Module_HelpVersion "5.35 (19 Jan 2014) 4.79.2.208"
#define Module_FullVersion "5.35 (4.79.2.209)"
#define Module_HelpVersion "5.35 (26 Jan 2014) 4.79.2.209"
#define Module_LibraryVersionInfo "5:35"
......@@ -706,15 +706,14 @@ DAbPreVeneer ROUT
TST r0, #T32_bit ; were they in Thumb mode? if so, give up now
BNE %FT90
;ARM 810 or StrongARM allow signed byte load or half-word load/stores - not supported at present
;***KJB - need to think about LDRH family
;ARMv4+ allow half-word load/stores - not supported at present
;ARMv5TE+ allow double-word load/stores - not supported at present
;ARMv6 allow load/store exclusive - not supported at present
LDR r10, [r4, #-8]! ; r10 = actual instruction that aborted, and r4 points to it
AND r9, r10, #&0E000000
TEQ r9, #&08000000 ; test for LDM/STM
AND r9, r10, #2_1110 :SHL: 24
TEQ r9, #2_1000 :SHL: 24 ; test for LDM/STM
BNE %FT50 ; if not LDM/STM, then it's an "easy" LDR/STR
; Write "It's an LDM/STM"
[ DebugAborts
DLINE "It's an LDM/STM"
]
......@@ -886,12 +885,36 @@ DAbPreVeneer ROUT
50
; it's an LDR/STR - first work out offset
; it's an LDR/STR
TEQ r9, #2_0000 :SHL: 24 ; is it the extra load/store family?
BNE %FT55 ; no, plain LDR[B]
[ DebugAborts
DLINE "It's an LDR/STR"
DLINE "It's LDR[EX|SB|H|SH|D]/STR[EX|H|D]"
]
AND r9, r10, #2_1111 :SHL: 4
TEQ r9, #2_1101 :SHL: 4
BNE %FT90 ; Abort if LDR[EX|H|SH]/STR[EX|H|D]
TST r10, #1 :SHL: 20
BEQ %FT90 ; Abort if LDRD (encoded where STRSB would be)
TST r10, #1 :SHL: 22 ; if immediate
BICNE r9, r10, 2_1111 :SHL: 4
ORRNE r9, r9, r9, LSR #4
ANDNE r9, r9, #&FF ; then extract imm8 bits
ANDEQ r8, r10, #&0F ; register offset
LDREQ r9, [r11, r8, LSL #2] ; get actual value of register
ORR r10, r10, #1 :SHL: 22 ; ensure it looks like a byte access
B %FT60
; We've effectively reencoded the weird load/stores to look like
; cccc 0zxp ubwl nnnn tttt xxxx xxxx xxxx
; z = zero/sign extend b = byte/word
; p = pre/post l = load/store
; u = up/down x = don't care from here on
55
[ DebugAborts
DLINE "It's an LDR[B]/STR[B]"
]
TST r10, #1 :SHL: 25 ; if immediate
MOVEQ r9, r10, LSL #(31-11) ; then extract bottom 12 bits
MOVEQ r9, r9, LSR #(31-11)
......@@ -923,29 +946,6 @@ DAbPreVeneer ROUT
TST r10, #1 :SHL: 23 ; test for up/down
RSBEQ r9, r9, #0 ; if down then negate
;;;assume ARM 6 configured for LateAbort - others cannot be configured
;;;so, at run time, ARM 6 or 7 means late, ARM 8 or StrongARM means early
;;;
;;; [ LateAborts
;;; TST r10, #1 :SHL: 21 ; if write-back
;;; MOVNE r8, #0 ; then no post-inc
;;; RSBEQ r8, r9, #0 ; else post-inc = - pre-inc
;;; ADD r0, r8, r9 ; amount to subtract off base register for correction
;;; TST r10, #1 :SHL: 24 ; however, if we're doing post-increment
;;; MOVEQ r8, r9 ; then post-inc = what was pre-inc
;;; MOVEQ r0, r9 ; and adjustment is what was added on
;;; RSB r9, r8, #0 ; and pre-inc = -post-inc
;;; |
;;; TST r10, #1 :SHL: 21 ; if write-back
;;; MOVNE r8, #0 ; then no post-inc
;;; RSBEQ r8, r9, #0 ; else post-inc = - pre-inc
;;; TST r10, #1 :SHL: 24 ; however, if we're doing post-increment
;;; MOVEQ r8, r9 ; then post-inc = what was pre-inc
;;; MOVEQ r9, #0 ; and pre-inc = 0
;;; ]
LDR r8, =ZeroPage
LDR r8, [r8, #ProcessorFlags]
TST r8, #CPUFlag_BaseRestored
......@@ -976,11 +976,6 @@ DAbPreVeneer ROUT
MOV r7, r7, LSR #28 ; r7 = base register number
LDR r6, [r11, r7, LSL #2] ; r6 = base register value
;;; [ LateAborts
;;; SUB r0, r6, r0 ; compute adjusted base register
;;; STR r0, [r11, r7, LSL #2] ; and store back in case we decide to abort after all
;;; ]
LDR r1, =ZeroPage
LDR r1, [r1, #ProcessorFlags]
TST r1, #CPUFlag_BaseRestored
......@@ -1032,13 +1027,19 @@ DAbPreVeneer ROUT
ADDEQ sp, sp, #4 ; then junk stack frame
BEQ %FT70 ; and tidy up
Pull "r6" ; LDR/LDRB, so get value to load into register
TST r10, #1 :SHL: 22 ; if LDRB
ANDNE r6, r6, #&FF ; then put zero in top 3 bytes of word
ANDEQ r9, r9, #3 ; else rotate word to correct position - r9 = bottom 2 bits of address
MOVEQ r9, r9, LSL #3 ; multiply by 8 to get rotation factor
MOVEQ r6, r6, ROR r9 ; rotate to correct position in register
Pull "r6" ; LDR/LDRB/LDRSB: get value to load into register
TST r10, #1 :SHL: 22
BEQ %FT67
TST r10, #1 :SHL: 26 ; LDRB: see if zero fill or sign extend is needed
MOVEQ r6, r6, LSL #24
MOVEQ r6, r6, ASR #24 ; fill with b7
ANDNE r6, r6, #&FF ; fill with zero
B %FT69
67
AND r9, r9, #3 ; LDR: rotate word to correct position - r9 = bottom 2 bits of address
MOV r9, r9, LSL #3 ; multiply by 8 to get rotation factor
MOV r6, r6, ROR r9 ; rotate to correct position in register
69
MOV r5, r10, LSR #12 ; test for LDR PC
AND r5, r5, #&0F ; r5 = dest register number
TEQ r5, #15 ; if PC
......
......@@ -18,7 +18,7 @@
DebugAborts SETL {FALSE}
GBLL UseProcessTransfer
UseProcessTransfer SETL {FALSE} ; Needs updating to cope with HiProcVecs (for proc. vector protection) and all the ARMv6+ (ARMv3+?) load/store instructions
UseProcessTransfer SETL :LNOT: HiProcVecs ; Needs updating to cope with HiProcVecs (for proc. vector protection)
; MMU interface file - VMSAv6 version
......@@ -78,7 +78,7 @@ BangCamUpdate ROUT
ADD r6, r6, r4, LSR #12 ; put back the ones which were too many
ADD r0, r0, r6, LSL #12 ; move on address by the number of pages left
LDR r6, [r13] ; reload old logical address
LDR r6, [sp] ; reload old logical address
; now we have r6 = old logical address, r2 = physical page number, r0 = physical address
......@@ -299,7 +299,7 @@ SSETMEMC ROUT
MOVNE r0, #0 ; unblank (video DMA enable)
MOV r1, #0 ; no funny business with DPMS
ADD r4, r12, #VduDriverWorkSpace
LDR r4, [WsPtr, #CurrentGraphicsVDriver]
LDR r4, [r4, #CurrentGraphicsVDriver]
MOV r4, r4, LSL #24
ORR r4, r4, #GraphicsV_SetBlank
BL CallGraphicsV
......@@ -550,21 +550,19 @@ DAbPreVeneer ROUT
SUB r11, r2, #8*4 ; r11 -> register bank
STR r4, [sp, #7*4] ; store aborter's PC in user register bank
; B %FT90
[ UseProcessTransfer
TST r0, #T32_bit ; were they in Thumb mode? if so, give up now
BNE %FT90
;ARM 810 or StrongARM allow signed byte load or half-word load/stores - not supported at present
;***KJB - need to think about LDRH family
;ARMv4+ allow half-word load/stores - not supported at present
;ARMv5TE+ allow double-word load/stores - not supported at present
;ARMv6 allow load/store exclusive - not supported at present
LDR r10, [r4, #-8]! ; r10 = actual instruction that aborted, and r4 points to it
AND r9, r10, #&0E000000
TEQ r9, #&08000000 ; test for LDM/STM
AND r9, r10, #2_1110 :SHL: 24
TEQ r9, #2_1000 :SHL: 24 ; test for LDM/STM
BNE %FT50 ; if not LDM/STM, then it's an "easy" LDR/STR
; Write "It's an LDM/STM"
[ DebugAborts
DLINE "It's an LDM/STM"
]
......@@ -736,12 +734,36 @@ DAbPreVeneer ROUT
50
; it's an LDR/STR - first work out offset
; it's an LDR/STR
TEQ r9, #2_0000 :SHL: 24 ; is it the extra load/store family?
BNE %FT55 ; no, plain LDR[B]
[ DebugAborts
DLINE "It's an LDR/STR"
DLINE "It's LDR[EX|SB|H|SH|D]/STR[EX|H|D]"
]
AND r9, r10, #2_1111 :SHL: 4
TEQ r9, #2_1101 :SHL: 4
BNE %FT90 ; Abort if LDR[EX|H|SH]/STR[EX|H|D]
TST r10, #1 :SHL: 20
BEQ %FT90 ; Abort if LDRD (encoded where STRSB would be)
TST r10, #1 :SHL: 22 ; if immediate
BICNE r9, r10, 2_1111 :SHL: 4
ORRNE r9, r9, r9, LSR #4
ANDNE r9, r9, #&FF ; then extract imm8 bits
ANDEQ r8, r10, #&0F ; register offset
LDREQ r9, [r11, r8, LSL #2] ; get actual value of register
ORR r10, r10, #1 :SHL: 22 ; ensure it looks like a byte access
B %FT60
; We've effectively reencoded the weird load/stores to look like
; cccc 0zxp ubwl nnnn tttt xxxx xxxx xxxx
; z = zero/sign extend b = byte/word
; p = pre/post l = load/store
; u = up/down x = don't care from here on
55
[ DebugAborts
DLINE "It's an LDR[B]/STR[B]"
]
TST r10, #1 :SHL: 25 ; if immediate
MOVEQ r9, r10, LSL #(31-11) ; then extract bottom 12 bits
MOVEQ r9, r9, LSR #(31-11)
......@@ -854,13 +876,19 @@ DAbPreVeneer ROUT
ADDEQ sp, sp, #4 ; then junk stack frame
BEQ %FT70 ; and tidy up
Pull "r6" ; LDR/LDRB, so get value to load into register
TST r10, #1 :SHL: 22 ; if LDRB
ANDNE r6, r6, #&FF ; then put zero in top 3 bytes of word
ANDEQ r9, r9, #3 ; else rotate word to correct position - r9 = bottom 2 bits of address
MOVEQ r9, r9, LSL #3 ; multiply by 8 to get rotation factor
MOVEQ r6, r6, ROR r9 ; rotate to correct position in register
Pull "r6" ; LDR/LDRB/LDRSB: get value to load into register
TST r10, #1 :SHL: 22
BEQ %FT67
TST r10, #1 :SHL: 26 ; LDRB: see if zero fill or sign extend is needed
MOVEQ r6, r6, LSL #24
MOVEQ r6, r6, ASR #24 ; fill with b7
ANDNE r6, r6, #&FF ; fill with zero
B %FT69
67
AND r9, r9, #3 ; LDR: rotate word to correct position - r9 = bottom 2 bits of address
MOV r9, r9, LSL #3 ; multiply by 8 to get rotation factor
MOV r6, r6, ROR r9 ; rotate to correct position in register
69
MOV r5, r10, LSR #12 ; test for LDR PC
AND r5, r5, #&0F ; r5 = dest register number
TEQ r5, #15 ; if PC
......
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