Commit d7299988 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Prevent disabling of the D-cache on Cortex-A53. Other OS_MMUControl 0 fixes.

Detail:
  On Cortex-A53, a load/store exclusive instruction will abort if it targets non-cacheable memory or if the D-cache is disabled. Since the correct operation of these instructions is important to the OS and apps, it makes sense to prevent *Cache Off / OS_MMUControl 0 from being able to disable the D-cache on such systems.
  hdr/OSMisc, s/ARMops - Add new OS_PlatformFeatures 0 flag to indicate when disabling of the D-cache isn't allowed
  s/VMSAv6 - Update MMUControl_ModifyControl to force the D-cache to always be on when the "unsafe to disable D-cache" PlatformFeatures flag is set. Also, disallow mismatched I+D cache settings if we have an L2 cache (causes issues due to IMB ops only flushing to PoU), and fix dangerous D-cache invalidation when it's only the I-cache which is being disabled
  s/ARM600 - Clean up MMUControl_ModifyControl a bit so that it's a closer match to the VMSAv6 version, and fix the dangerous D-cache invalidation.
Admin:
  Tested on ARM11, Cortex-A7, Cortex-A53


Version 5.62. Tagged as 'Kernel-5_62'
parent fe59a83a
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.61"
Module_Version SETA 561
Module_MajorVersion SETS "5.62"
Module_Version SETA 562
Module_MinorVersion SETS ""
Module_Date SETS "09 Oct 2016"
Module_ApplicationDate SETS "09-Oct-16"
Module_Date SETS "17 Oct 2016"
Module_ApplicationDate SETS "17-Oct-16"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.61"
Module_HelpVersion SETS "5.61 (09 Oct 2016)"
Module_FullVersion SETS "5.62"
Module_HelpVersion SETS "5.62 (17 Oct 2016)"
END
/* (5.61)
/* (5.62)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 5.61
#define Module_MajorVersion_CMHG 5.62
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 09 Oct 2016
#define Module_Date_CMHG 17 Oct 2016
#define Module_MajorVersion "5.61"
#define Module_Version 561
#define Module_MajorVersion "5.62"
#define Module_Version 562
#define Module_MinorVersion ""
#define Module_Date "09 Oct 2016"
#define Module_Date "17 Oct 2016"
#define Module_ApplicationDate "09-Oct-16"
#define Module_ApplicationDate "17-Oct-16"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.61"
#define Module_HelpVersion "5.61 (09 Oct 2016)"
#define Module_LibraryVersionInfo "5:61"
#define Module_FullVersion "5.62"
#define Module_HelpVersion "5.62 (17 Oct 2016)"
#define Module_LibraryVersionInfo "5:62"
......@@ -39,6 +39,7 @@ CPUFlag_DSP * 1:SHL:10 ; Has E extensions (QADD etc)
CPUFlag_NoSWP * 1:SHL:11 ; CPU does not support SWP/SWPB
CPUFlag_LoadStoreEx * 1:SHL:12 ; Has LDR/STREX
CPUFlag_LoadStoreClearExSizes * 1:SHL:13 ; Has CLREX and LDR/STREX[B|H|D]
CPUFlag_NoDCacheDisable * 1:SHL:14 ; D-cache can't be disabled safely & OS_MMUControl won't allow it
CPUFlag_ExtendedPages * 1:SHL:15 ; Supports extended small page L2 descriptors
CPUFlag_NoWBDrain * 1:SHL:16 ; CPU does not support Drain Write Buffer instruction
CPUFlag_AbortRestartBroken * 1:SHL:17 ; Aborts do not correctly follow documented abort model
......
......@@ -281,7 +281,7 @@ PageShifts
; out: r1 = old value
; r2 = new value
MMUControl_ModifyControl ROUT
Push "r3,r4,r5"
Push "r0,r3,r4,r5"
CMP r1,#0
CMPEQ r2,#&FFFFFFFF
BEQ MMUC_modcon_readonly
......@@ -291,62 +291,54 @@ MMUControl_ModifyControl ROUT
CMP r5,#ARMv4
LDRLO lr, [r3, #MMUControlSoftCopy]
ARM_read_control lr,HS
; MOVHS lr,lr,LSL #19
; MOVHS lr,lr,LSR #19 ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
ARM_read_control lr,HS ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
AND r2, r2, lr
EOR r2, r2, r1
MOV r1, lr
LDR r5, [r3, #ProcessorFlags]
TST r5, #CPUFlag_SplitCache
BEQ %FT05
[ {FALSE}
TST r2,#MMUC_C ; if split caches, then I bit mirrors C bit
ORRNE r2,r2,#MMUC_I
BICEQ r2,r2,#MMUC_I
]
05
STR r2, [r3, #MMUControlSoftCopy]
BIC lr, r2, r1 ; lr = bits going from 0->1
TST lr, #MMUC_C ; if cache turning on then flush cache before we do it
TSTEQ lr, #MMUC_I
BEQ %FT10
BEQ %FT05
ARMop Cache_InvalidateAll,,,r3 ; D-cache turning on, I-cache invalidate is either necessary (both turning on) or a safe side-effect
B %FT10
05
TST lr, #MMUC_I
ARMop IMB_Full,NE,,r3 ; I-cache turning on, Cache_InvalidateAll could be unsafe
Push "r0"
ARMop Cache_InvalidateAll,,,r3
Pull "r0"
10
BIC lr, r1, r2 ; lr = bits going from 1->0
TST lr, #MMUC_C ; if cache turning off then clean data cache first
BEQ %FT15
Push "r0"
ARMop Cache_CleanAll,,,r3
Pull "r0"
15
ARM_write_control r2
BIC lr, r1, r2 ; lr = bits going from 1->0
TST lr, #MMUC_C ; if cache turning off then flush cache afterwards
TSTNE lr, #MMUC_I
BEQ %FT17
LDR r3,=ZeroPage
ARMop Cache_InvalidateAll,,,r3 ; D-cache turned off, can safely invalidate I+D
B %FT20
17
TST lr, #MMUC_I
BEQ %FT20
Push "r0"
ARMop Cache_InvalidateAll,,,r3
Pull "r0"
LDR r3,=ZeroPage
ARMop IMB_Full,,,r3 ; Only I-cache which turned off, clean D-cache & invalidate I-cache
20
PLP r4 ; restore IRQ state
Pull "r3,r4,r5,pc"
Pull "r0,r3,r4,r5,pc"
MMUC_modcon_readonly
LDR r3, =ZeroPage
LDRB r5, [r3, #ProcessorArch]
CMP r5, #ARMv4
LDRLO lr, [r3, #MMUControlSoftCopy]
ARM_read_control lr,HS
; MOVHS lr,lr,LSL #19
; MOVHS lr,lr,LSR #19 ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
ARM_read_control lr,HS ; if ARMv4 or later, we can read control reg. - trust this more than soft copy
STRHS lr, [r3, #MMUControlSoftCopy]
MOV r1, lr
MOV r2, lr
Pull "r3,r4,r5,pc"
Pull "r0,r3,r4,r5,pc"
; If extended pages are supported:
; PPLTrans should contain L2X_AP + L2_ExtPage
......
......@@ -928,7 +928,7 @@ KnownCPUFlags
DCD 0, 0 ; Cortex_A12
DCD 0, 0 ; Cortex_A15
DCD 0, 0 ; Cortex_A17
DCD 0, 0 ; Cortex_A53
DCD CPUFlag_NoDCacheDisable, 0 ; Cortex_A53
DCD 0, 0 ; Cortex_A57
DCD 0, 0 ; Cortex_A72
......
......@@ -340,17 +340,46 @@ MMUControl_ModifyControl ROUT
AND r2, r2, lr
EOR r2, r2, r1
MOV r1, lr
; On some CPUs LDREX/STREX only work on cacheable memory. Allowing the
; D-cache to be disabled in this situation is likely to result in near-
; instant failure of the OS.
LDR r5, [r3, #ProcessorFlags]
TST r5, #CPUFlag_SplitCache
BEQ %FT05
05
TST r5, #CPUFlag_NoDCacheDisable
ORRNE r2, r2, #MMUC_C
; If we have multiple cache levels, assume it's split caches ontop of a
; unified cache. In which case, having mismatched I+D cache settings can
; be pretty dangerous due to the IMB ARMops assuming that cleaning to
; PoU is sufficient (D-cache on but I-cache off will fail due to the
; instruction fetches bypassing the unified cache, D-cache off but
; I-cache on will fail because the I-cache will pull code into the
; unified cache which an IMB won't clean)
; If we have the ability to disable the L2 cache then this would be OK,
; but we can't guarantee that ability
Push "r1-r4"
MOV r1, #1
ARMop Cache_Examine,,,r3
CMP r0, #0
Pull "r1-r4"
BEQ %FT04
LDR lr, =MMUC_C+MMUC_I
TST r2, lr
ORRNE r2, r2, lr ; If one cache is on, force both on
04
STR r2, [r3, #MMUControlSoftCopy]
BIC lr, r2, r1 ; lr = bits going from 0->1
TST lr, #MMUC_C ; if cache turning on then flush cache before we do it
TSTEQ lr, #MMUC_I
BEQ %FT10
BEQ %FT05
ARMop Cache_InvalidateAll,,,r3 ; D-cache turning on, I-cache invalidate is either necessary (both turning on) or a safe side-effect
B %FT10
05
TST lr, #MMUC_I
ARMop IMB_Full,NE,,r3 ; I-cache turning on, Cache_InvalidateAll could be unsafe
ARMop Cache_InvalidateAll,,,r3
10
; If I+D currently enabled, and at least one is turning off, turn off
; HAL L2 cache
......@@ -382,10 +411,16 @@ MMUControl_ModifyControl ROUT
myISB ,lr ; Must be running on >=ARMv6, so perform ISB to ensure CP15 write is complete
BIC lr, r1, r2 ; lr = bits going from 1->0
TST lr, #MMUC_C ; if cache turning off then flush cache afterwards
TSTNE lr, #MMUC_I
BEQ %FT17
LDR r3,=ZeroPage
ARMop Cache_InvalidateAll,,,r3 ; D-cache turned off, can safely invalidate I+D
B %FT19
17
TST lr, #MMUC_I
BEQ %FT20
LDR r3,=ZeroPage
ARMop Cache_InvalidateAll,,,r3
ARMop IMB_Full,,,r3 ; Only I-cache which turned off, clean D-cache & invalidate I-cache
19
; Undo any stack uncaching we performed above
BIC lr, r1, r2
TST lr, #MMUC_C
......
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