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

Streamline PL310 ARMops

Detail:
  Some closer examination of the PL310 TRM reveals that there's no need to poll for completion of maintenance operations if we only use atomic ops.
  Since there's no particular need for us to use the background ops, just rewrite everything to use the atomic ops and get rid of the polling.
  This should also avoid the need for any costly locking in SMP setups.
  File changes:
  - s/ARMops - Updated as above
Admin:
  Tested on Pandaboard, iMx6


Version 5.79. Tagged as 'Kernel-5_79'
parent f1802d76
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.78"
Module_Version SETA 578
Module_MajorVersion SETS "5.79"
Module_Version SETA 579
Module_MinorVersion SETS ""
Module_Date SETS "11 Feb 2017"
Module_ApplicationDate SETS "11-Feb-17"
Module_Date SETS "17 Feb 2017"
Module_ApplicationDate SETS "17-Feb-17"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.78"
Module_HelpVersion SETS "5.78 (11 Feb 2017)"
Module_FullVersion SETS "5.79"
Module_HelpVersion SETS "5.79 (17 Feb 2017)"
END
/* (5.78)
/* (5.79)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 5.78
#define Module_MajorVersion_CMHG 5.79
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 11 Feb 2017
#define Module_Date_CMHG 17 Feb 2017
#define Module_MajorVersion "5.78"
#define Module_Version 578
#define Module_MajorVersion "5.79"
#define Module_Version 579
#define Module_MinorVersion ""
#define Module_Date "11 Feb 2017"
#define Module_Date "17 Feb 2017"
#define Module_ApplicationDate "11-Feb-17"
#define Module_ApplicationDate "17-Feb-17"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.78"
#define Module_HelpVersion "5.78 (11 Feb 2017)"
#define Module_LibraryVersionInfo "5:78"
#define Module_FullVersion "5.79"
#define Module_HelpVersion "5.79 (17 Feb 2017)"
#define Module_LibraryVersionInfo "5:79"
......@@ -3287,6 +3287,9 @@ ICache_InvalidateAll_WB_CR7_Lx ROUT
; cache maintenance ops. Currently they're only used on Cortex-A9 systems, so
; may need modifications to work with other systems.
; Specifically, the code assumes the PL310 is being used in non-exclusive mode.
;
; To make the code fully re-entrant and MP-safe, we avoid using the background
; operations (INV_WAY, CLEAN_WAY, CLEAN_INV_WAY).
MACRO
PL310Sync $regs, $temp
......@@ -3298,16 +3301,13 @@ ICache_InvalidateAll_WB_CR7_Lx ROUT
MOV $temp, #0
STREQ $temp, [$regs, #PL310_REG7_CACHE_SYNC_753970]
STRNE $temp, [$regs, #PL310_REG7_CACHE_SYNC]
10
LDR $temp, [$regs, #PL310_REG7_CACHE_SYNC]
TST $temp, #1
BNE %BT10
MEND
PL310Threshold * 1024*1024 ; Arbitrary threshold for full clean
Cache_CleanInvalidateAll_PL310 ROUT
; Errata 727915 workaround - use CLEAN_INV_INDEX instead of CLEAN_INV_WAY
; Also, CLEAN_INV_WAY is a background op, while CLEAN_INV_INDEX is atomic.
Entry "a2-a4"
LDR a2, =ZeroPage
LDR a2, [a2, #Cache_HALDevice]
......@@ -3323,70 +3323,50 @@ Cache_CleanInvalidateAll_PL310 ROUT
LDR a4, =&FF<<5
ORR a3, a3, #7<<28 ; a3 = max way number (inclusive)
ORR a4, a4, a4, LSL a1 ; a4 = max index number (inclusive)
; Ensure no operation currently in progress
05
LDR lr, [a2, #PL310_REG7_CLEAN_INV_INDEX]
TST lr, #1
BNE %BT05
10
ORR a1, a3, a4
20
STR a1, [a2, #PL310_REG7_CLEAN_INV_INDEX]
30
LDR lr, [a2, #PL310_REG7_CLEAN_INV_INDEX]
TST lr, #1
BNE %BT30
SUBS a1, a1, #1<<28 ; next way
BCS %BT20 ; underflow?
SUBS a4, a4, #1<<5 ; next index
BGE %BT10
; Sync PL310
PL310Sync a2, a1
; Ensure the ops are actually complete
DSB
; Clean & invalidate ARM caches
PullEnv
B Cache_CleanInvalidateAll_WB_CR7_Lx
Cache_CleanAll_PL310 ROUT
Entry "a2"
Entry "a2-a4"
LDR a2, =ZeroPage
LDR a2, [a2, #Cache_HALDevice]
LDR a2, [a2, #HALDevice_Address]
; Clean ARM caches
BL Cache_CleanAll_WB_CR7_Lx
; Clean PL310
; Determine PL310 way, index count
LDR a1, [a2, #PL310_REG1_AUX_CONTROL]
TST a1, #1<<16
MOV a1, #&FF
ORRNE a1, a1, #&FF00 ; Mask of all ways
STR a1, [a2, #PL310_REG7_CLEAN_WAY]
AND a3, a1, #1<<16
AND a1, a1, #7<<17
MOV a3, a3, LSL #15
MOV a1, a1, LSR #17
LDR a4, =&FF<<5
ORR a3, a3, #7<<28 ; a3 = max way number (inclusive)
ORR a4, a4, a4, LSL a1 ; a4 = max index number (inclusive)
10
LDR a1, [a2, #PL310_REG7_CLEAN_WAY]
TEQ a1, #0
BNE %BT10
; Sync PL310
PL310Sync a2, a1
ORR a1, a3, a4
20
STR a1, [a2, #PL310_REG7_CLEAN_INDEX]
SUBS a1, a1, #1<<28 ; next way
BCS %BT20 ; underflow?
SUBS a4, a4, #1<<5 ; next index
BGE %BT10
; Ensure the ops are actually complete
DSB
EXIT
Cache_InvalidateAll_PL310 ROUT
Entry "a2"
LDR a2, =ZeroPage
LDR a2, [a2, #Cache_HALDevice]
LDR a2, [a2, #HALDevice_Address]
; Invalidate PL310
LDR a1, [a2, #PL310_REG1_AUX_CONTROL]
TST a1, #1<<16
MOV a1, #&FF
ORRNE a1, a1, #&FF00 ; Mask of all ways
STR a1, [a2, #PL310_REG7_INV_WAY]
10
LDR a1, [a2, #PL310_REG7_INV_WAY]
TEQ a1, #0
BNE %BT10
; Sync PL310
PL310Sync a2, a1
; Invalidate ARM caches
PullEnv
B Cache_InvalidateAll_WB_CR7_Lx
; This op will be rarely (if ever) used, just implement as clean + invalidate
Cache_InvalidateAll_PL310 * Cache_CleanInvalidateAll_PL310
Cache_RangeThreshold_PL310 ROUT
MOV a1, #PL310Threshold
......@@ -3428,8 +3408,8 @@ DSB_ReadWrite_PL310 ROUT
DSB SY
; Drain PL310 write buffer
PL310Sync lr, a1
; Additional barrier necessary here, to prevent reads from occuring before the PL310Sync has completed. DMB should be sufficient, rather than DSB.
DMB SY
; Ensure the PL310 sync is complete
DSB SY
EXIT
DSB_Write_PL310 ROUT
......@@ -3441,7 +3421,8 @@ DSB_Write_PL310 ROUT
DSB ST
; Drain PL310 write buffer
PL310Sync lr, a1
; Assume that no barrier needed here (we don't care about reads, and there's surely no such thing as a speculative write)
; Ensure the PL310 sync is complete
DSB ST
EXIT
DMB_ReadWrite_PL310 ROUT
......@@ -3453,7 +3434,7 @@ DMB_ReadWrite_PL310 ROUT
DMB SY
; Drain PL310 write buffer
PL310Sync lr, a1
; Additional barrier necessary here, to prevent reads from occuring before the PL310Sync has completed
; Ensure the PL310 sync is complete
DMB SY
EXIT
......@@ -3466,7 +3447,8 @@ DMB_Write_PL310 ROUT
DMB ST
; Drain PL310 write buffer
PL310Sync lr, a1
; Assume that no barrier needed here (we don't care about reads, and there's surely no such thing as a speculative write)
; Ensure the PL310 sync is complete
DMB ST
EXIT
MMU_Changing_PL310 ROUT
......@@ -3547,11 +3529,6 @@ Cache_CleanInvalidateRange_PL310 ROUT
LDR a1, =ZeroPage
LDR a2, [a1, #Cache_HALDevice]
LDR a2, [a2, #HALDevice_Address]
; Ensure we haven't re-entered an in-progress op
40
LDR lr, [a2, #PL310_REG7_CLEAN_INV_PA]
TST lr, #1
BNE %BT40
; Clean & invalidate each line/index of the pages
50
; Convert logical addr to physical.
......@@ -3570,10 +3547,6 @@ Cache_CleanInvalidateRange_PL310 ROUT
BIC a1, a1, #&01F
60
STR a1, [a2, #PL310_REG7_CLEAN_INV_PA]
70
LDR lr, [a2, #PL310_REG7_CLEAN_INV_PA]
TST lr, #1
BNE %BT70
TST a1, #&FE0
SUB a1, a1, #1<<5 ; next index
BNE %BT60
......@@ -3581,7 +3554,7 @@ Cache_CleanInvalidateRange_PL310 ROUT
CMP a4, a3
BNE %BT50
; Sync
PL310Sync a2, a1
DSB
; Clean & invalidate ARM
SUB a1, a3, v1
MOV a2, a3
......@@ -3634,11 +3607,6 @@ Cache_CleanRange_PL310 ROUT
LDR a1, =ZeroPage
LDR a2, [a1, #Cache_HALDevice]
LDR a2, [a2, #HALDevice_Address]
; Ensure we haven't re-entered an in-progress op
40
LDR lr, [a2, #PL310_REG7_CLEAN_INV_PA]
TST lr, #1
BNE %BT40
; Clean & invalidate each line/index of the pages
50
; Convert logical addr to physical.
......@@ -3657,10 +3625,6 @@ Cache_CleanRange_PL310 ROUT
BIC a1, a1, #&01F
60
STR a1, [a2, #PL310_REG7_CLEAN_PA]
70
LDR lr, [a2, #PL310_REG7_CLEAN_PA]
TST lr, #1
BNE %BT70
TST a1, #&FE0
SUB a1, a1, #1<<5 ; next index
BNE %BT60
......@@ -3668,7 +3632,7 @@ Cache_CleanRange_PL310 ROUT
CMP a4, a3
BNE %BT50
; Sync
PL310Sync a2, a1
DMB
EXIT
90
......
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