Commit ebe048fb authored by Ben Avison's avatar Ben Avison
Browse files

Extra function to assist with ARMv8 compatibility

Detail:
  atomic_update_byte() is the equivalent of atomic_update() but deals with
  byte-wide rather than word-wide data fields. It operates using either
  SWPB or LDREXB/STREXB instructions, depending upon the architecture, and
  is therefore suitable for updating any modules which currently use SWPB
  explicitly in order to make them compatible with ARMv8 where the SWPB
  instruction has been removed.
Admin:
  Tested on Raspberry Pi 3.

Version 0.02. Tagged as 'SyncLib-0_02'
parent 2fec96d6
/* (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 29 May 2012
#define Module_Date_CMHG 29 Feb 2016
#define Module_MajorVersion "0.01"
#define Module_Version 1
#define Module_MajorVersion "0.02"
#define Module_Version 2
#define Module_MinorVersion ""
#define Module_Date "29 May 2012"
#define Module_Date "29 Feb 2016"
#define Module_ApplicationDate "29-May-12"
#define Module_ApplicationDate "29-Feb-16"
#define Module_ComponentName "SyncLib"
#define Module_ComponentPath "bsd/RiscOS/Sources/Lib/SyncLib"
#define Module_FullVersion "0.01"
#define Module_HelpVersion "0.01 (29 May 2012)"
#define Module_LibraryVersionInfo "0:1"
#define Module_FullVersion "0.02"
#define Module_HelpVersion "0.02 (29 Feb 2016)"
#define Module_LibraryVersionInfo "0:2"
......@@ -43,6 +43,14 @@
*/
uint32_t atomic_update(uint32_t new_value, volatile uint32_t *address);
/** Atomic read/write of an 8-bit value.
* Can be entered in any processor mode.
* \arg new_value Value to write.
* \arg address Memory location at which to perform the read/write.
* \return Value that was read.
*/
uint8_t atomic_update_byte(uint8_t new_value, volatile uint8_t *address);
/** User-defined atomic operation on a 32-bit value.
* Can be entered in any processor mode unless you need to support
* architecture 5 or earlier, in which case must be entered in privileged mode.
......
......@@ -32,5 +32,6 @@ CPU_Events * 1:SHL:1
CPU_CP15DSB * 1:SHL:2
CPU_CP15DMB * 1:SHL:3
CPU_Barriers * 1:SHL:4 ; instruction forms
CPU_ExclusiveB * 1:SHL:5 ; 8-bit accesses
END
......@@ -38,12 +38,13 @@ Strex_Failed * 1
AREA |Asm$$Code|, CODE, READONLY
IF SupportARMv6 :LAND: NoARMv6 ; i.e. run-time detection is required
IF (SupportARMv6 :LAND: NoARMv6) :LOR: (SupportARMK :LAND: NoARMK) ; i.e. run-time detection is required
EXPORT atomic_init
atomic_init ROUT
[ zM
StaticBaseFromSL a4
]
[ SupportARMv6 :LAND: NoARMv6
ADR a2, atomic_update_uniproc
ADR a3, atomic_process_uniproc
TST a1, #CPU_Exclusive
......@@ -51,6 +52,13 @@ atomic_init ROUT
ADRNE a3, atomic_process_smp
Store a2, a4, update_fn, ip
Store a3, a4, process_fn, ip
]
[ SupportARMK :LAND: NoARMK
ADR a2, atomic_update_byte_uniproc
TST a1, #CPU_ExclusiveB
ADRNE a2, atomic_update_byte_smp
Store a2, a4, update_byte_fn, ip
]
Return , LinkNotStacked
ENDIF
......@@ -74,6 +82,18 @@ atomic_process ROUT
Load pc, a4, process_fn, ip
ENDIF
IF :LNOT: SupportARMK
atomic_update_byte * atomic_update_byte_uniproc
ELIF :LNOT: NoARMv6
atomic_update_byte * atomic_update_byte_smp
ELSE
atomic_update_byte ROUT
[ zM
StaticBaseFromSL a4
]
Load pc, a4, update_byte_fn, ip
ENDIF
IF NoARMv6
......@@ -100,6 +120,15 @@ atomic_process_uniproc ROUT
ENDIF
IF NoARMK
atomic_update_byte_uniproc ROUT
; Let's not worry about ARM2 support
SWPB a1, a1, [a2]
Return , LinkNotStacked
ENDIF
IF SupportARMv6
......@@ -128,20 +157,39 @@ atomic_process_smp ROUT
ENDIF
IF SupportARMK
atomic_update_byte_smp ROUT
MOV a3, a1
01 LDREXB a1, [a2]
STREXB a4, a3, [a2]
TEQ a4, #Strex_Failed
BEQ %B01 ; another exclusive access happened between LDREXB and STREXB
Return , LinkNotStacked
ENDIF
IF SupportARMv6 :LAND: NoARMv6
IF (SupportARMv6 :LAND: NoARMv6) :LOR: (SupportARMK :LAND: NoARMK)
AREA |Asm$$Data|, DATA
[ SupportARMv6 :LAND: NoARMv6
update_fn
DCD 0
process_fn
DCD 0
]
[ SupportARMK :LAND: NoARMK
update_byte_fn
DCD 0
]
ENDIF
EXPORT atomic_update
EXPORT atomic_update_byte
EXPORT atomic_process
......
......@@ -43,15 +43,17 @@
AREA |Asm$$Code|, CODE, READONLY
; LDREX/STREX are available in arch v6 or later.
; LDREXB/STREXB are available in arch v6K or later.
; CP15DMB and CP15DSB may be available in any v6 CPU - need to test at runtime.
; They are deprecated in favour of the new instructions in ARMv7.
; DMB and DSB instructions are available in arch v7 or later.
; SEV and WFE are available in arch v6K or later, but also act as NOPs on v6T2.
;
; ID_ISAR3[15:12] for LDREX/STREX
; ID_ISAR3[15:12] for LDREX(B)/STREX(B)
; ID_ISAR3[27:24] for SEV/WFE
; ID_MMFR2[23:20] for CP15 barrier operations
; ID_ISAR4[19:16] for barrier instructions (DMB/DSB/ISB)
; ID_ISAR4[20:23] for LDREXB/STREXB
synclib_init ROUT
FunctionEntry "v1"
......@@ -60,7 +62,7 @@ synclib_init ROUT
MRC p15, 0, r0, c0, c0, 0
ANDS r1, r0, #(1:SHL:19):OR:(&F:SHL:12)
TEQNE r1, #7:SHL:12
; EQ => ARM7 or earler CPU, none of which have any of the fancu new instructions
; EQ => ARM7 or earler CPU, none of which have any of the fancy new instructions
BEQ %F90
ANDS r1, r0, #&F:SHL:16
CMP r1, #7:SHL:16
......@@ -71,6 +73,8 @@ synclib_init ROUT
MRC p15, 0, r0, c0, c2, 3
TST r0, #&F :SHL: 12
ORRNE v1, v1, #CPU_Exclusive
TST r0, #&E :SHL: 12 ; LDREXD implies LDREXB
ORRNE v1, v1, #CPU_ExclusiveB
TST r0, #&F :SHL: 24
ORRNE v1, v1, #CPU_Events
; Read ID_MMFR2 to determine if CP15 barrier operations are available
......@@ -79,14 +83,18 @@ synclib_init ROUT
CMP r0, #&1 :SHL: 20
ORRHS v1, v1, #CPU_CP15DSB
ORRHI v1, v1, #CPU_CP15DMB
; Read ID_ISAR4 register to determine if barrier instructions are available
; Read ID_ISAR4 register to determine if LDREXB or barrier instructions are available
MRC p15, 0, r0, c0, c2, 4
TST r0, #&F :SHL: 16
ORRNE v1, v1, #CPU_Barriers
TST r0, #&F :SHL: 20
ORRNE v1, v1, #CPU_ExclusiveB
90
[ SupportARMv6 :LAND: NoARMv6
[ (SupportARMv6 :LAND: NoARMv6) :LOR: (SupportARMK :LAND: NoARMK)
MOV a1, v1
BL atomic_init
]
[ SupportARMv6 :LAND: NoARMv6
MOV a1, v1
BL spin_init
MOV a1, v1
......
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