Browse Source

Merge pull request #843 from jeenu-arm/cas-lock

Introduce locking primitives using CAS instruction
pull/851/head
danh-arm 8 years ago
committed by GitHub
parent
commit
8da12f612e
  1. 5
      Makefile
  2. 41
      docs/firmware-design.md
  3. 8
      docs/user-guide.md
  4. 70
      lib/locks/exclusive/aarch64/spinlock.S
  5. 12
      make_helpers/build_macros.mk
  6. 6
      make_helpers/defaults.mk

5
Makefile

@ -392,6 +392,9 @@ $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
$(eval $(call assert_numeric,ARM_ARCH_MAJOR))
$(eval $(call assert_numeric,ARM_ARCH_MINOR))
################################################################################
# Add definitions to the cpp preprocessor based on the current build options.
# This is done after including the platform specific makefile to allow the
@ -399,6 +402,8 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM))
################################################################################
$(eval $(call add_define,ARM_CCI_PRODUCT_ID))
$(eval $(call add_define,ARM_ARCH_MAJOR))
$(eval $(call add_define,ARM_ARCH_MINOR))
$(eval $(call add_define,ARM_GIC_ARCH))
$(eval $(call add_define,ASM_ASSERTION))
$(eval $(call add_define,COLD_BOOT_SINGLE_CPU))

41
docs/firmware-design.md

@ -16,8 +16,9 @@ Contents :
11. [Use of coherent memory in Trusted Firmware](#11--use-of-coherent-memory-in-trusted-firmware)
12. [Isolating code and read-only data on separate memory pages](#12--isolating-code-and-read-only-data-on-separate-memory-pages)
13. [Performance Measurement Framework](#13--performance-measurement-framework)
14. [Code Structure](#14--code-structure)
15. [References](#15--references)
14. [ARMv8 Architecture Extensions](#14--armv8-architecture-extensions)
15. [Code Structure](#15--code-structure)
16. [References](#16--references)
1. Introduction
@ -2208,7 +2209,39 @@ in this implementation.
5. `pmf_helpers.h` is an internal header used by `pmf.h`.
14. Code Structure
14. ARMv8 Architecture Extensions
----------------------------------
ARM Trusted Firmware makes use of ARMv8 Architecture Extensions where
applicable. This section lists the usage of Architecture Extensions, and build
flags controlling them.
In general, and unless individually mentioned, the build options
`ARM_ARCH_MAJOR` and `ARM_ARCH_MINOR` selects the Architecture Extension to
target when building ARM Trusted Firmware. Subsequent ARM Architecture
Extensions are backward compatible with previous versions.
The build system only requires that `ARM_ARCH_MAJOR` and `ARM_ARCH_MINOR` have a
valid numeric value. These build options only control whether or not
Architecture Extension-specific code is included in the build. Otherwise, ARM
Trusted Firmware targets the base ARMv8.0 architecture; i.e. as if
`ARM_ARCH_MAJOR` == 8 and `ARM_ARCH_MINOR` == 0, which are also their respective
default values.
See also the _Summary of build options_ in [User Guide].
For details on the Architecture Extension and available features, please refer
to the respective Architecture Extension Supplement.
### ARMv8.1
This Architecture Extension is targeted when `ARM_ARCH_MAJOR` >= 8, or when
`ARM_ARCH_MAJOR` == 8 and `ARM_ARCH_MINOR` >= 1.
* The Compare and Swap instruction is used to implement spinlocks. Otherwise,
the load-/store-exclusive instruction pair is used.
15. Code Structure
-------------------
Trusted Firmware code is logically divided between the three boot loader
@ -2252,7 +2285,7 @@ FDTs provide a description of the hardware platform and are used by the Linux
kernel at boot time. These can be found in the `fdts` directory.
15. References
16. References
---------------
1. Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available

8
docs/user-guide.md

@ -184,6 +184,14 @@ performed.
is used to determine the number of valid slave interfaces available in the
ARM CCI driver. Default is 400 (that is, CCI-400).
* `ARM_ARCH_MAJOR`: The major version of ARM Architecture to target when
compiling ARM Trusted Firmware. Its value must be numeric, and defaults to
8. See also, _ARMv8 Architecture Extensions_ in [Firmware Design].
* `ARM_ARCH_MINOR`: The minor version of ARM Architecture to target when
compiling ARM Trusted Firmware. Its value must be a numeric, and defaults
to 0. See also, _ARMv8 Architecture Extensions_ in [Firmware Design].
* `ARM_GIC_ARCH`: Choice of ARM GIC architecture version used by the ARM
Legacy GIC driver for implementing the platform GIC API. This API is used
by the interrupt management framework. Default is 2 (that is, version 2.0).

70
lib/locks/exclusive/aarch64/spinlock.S

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@ -33,7 +33,66 @@
.globl spin_lock
.globl spin_unlock
#if (ARM_ARCH_MAJOR > 8) || ((ARM_ARCH_MAJOR == 8) && (ARM_ARCH_MINOR >= 1))
/*
* When compiled for ARMv8.1 or later, choose spin locks based on Compare and
* Swap instruction.
*/
# define USE_CAS 1
/*
* Lock contenders using CAS, upon failing to acquire the lock, wait with the
* monitor in open state. Therefore, a normal store upon unlocking won't
* generate an SEV. Use explicit SEV instruction with CAS unlock.
*/
# define COND_SEV() sev
#else
# define USE_CAS 0
/*
* Lock contenders using exclusive pairs, upon failing to acquire the lock, wait
* with the monitor in exclusive state. A normal store upon unlocking will
* implicitly generate an envent; so, no explicit SEV with unlock is required.
*/
# define COND_SEV()
#endif
#if USE_CAS
.arch armv8.1-a
/*
* Acquire lock using Compare and Swap instruction.
*
* Compare for 0 with acquire semantics, and swap 1. Wait until CAS returns
* 0.
*
* void spin_lock(spinlock_t *lock);
*/
func spin_lock
mov w2, #1
sevl
1:
wfe
mov w1, wzr
casa w1, w2, [x0]
cbnz w1, 1b
ret
endfunc spin_lock
.arch armv8-a
#else /* !USE_CAS */
/*
* Acquire lock using load-/store-exclusive instruction pair.
*
* void spin_lock(spinlock_t *lock);
*/
func spin_lock
mov w2, #1
sevl
@ -45,8 +104,17 @@ l2: ldaxr w1, [x0]
ret
endfunc spin_lock
#endif /* USE_CAS */
/*
* Release lock previously acquired by spin_lock.
*
* Unconditionally write 0, and conditionally generate an event.
*
* void spin_unlock(spinlock_t *lock);
*/
func spin_unlock
stlr wzr, [x0]
COND_SEV()
ret
endfunc spin_unlock

12
make_helpers/build_macros.mk

@ -1,5 +1,5 @@
#
# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@ -81,6 +81,16 @@ define assert_boolean
$(and $(patsubst 0,,$(value $(1))),$(patsubst 1,,$(value $(1))),$(error $(1) must be boolean))
endef
0-9 := 0 1 2 3 4 5 6 7 8 9
# Function to verify that a given option $(1) contains a numeric value
define assert_numeric
$(if $($(1)),,$(error $(1) must not be empty))
$(eval __numeric := $($(1)))
$(foreach d,$(0-9),$(eval __numeric := $(subst $(d),,$(__numeric))))
$(if $(__numeric),$(error $(1) must be numeric))
endef
# IMG_LINKERFILE defines the linker script corresponding to a BL stage
# $(1) = BL stage (2, 30, 31, 32, 33)
define IMG_LINKERFILE

6
make_helpers/defaults.mk

@ -1,5 +1,5 @@
#
# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@ -44,6 +44,10 @@ ARCH := aarch64
# port can change this value if needed.
ARM_CCI_PRODUCT_ID := 400
# ARM Architecture major and minor versions: 8.0 by default.
ARM_ARCH_MAJOR := 8
ARM_ARCH_MINOR := 0
# Determine the version of ARM GIC architecture to use for interrupt management
# in EL3. The platform port can change this value if needed.
ARM_GIC_ARCH := 2

Loading…
Cancel
Save