arm-trusted-firmware/lib/cpus/aarch64/cpuamu_helpers.S
Alexei Fedorov 9fc59639e6 Add support for Branch Target Identification
This patch adds the functionality needed for platforms to provide
Branch Target Identification (BTI) extension, introduced to AArch64
in Armv8.5-A by adding BTI instruction used to mark valid targets
for indirect branches. The patch sets new GP bit [50] to the stage 1
Translation Table Block and Page entries to denote guarded EL3 code
pages which will cause processor to trap instructions in protected
pages trying to perform an indirect branch to any instruction other
than BTI.
BTI feature is selected by BRANCH_PROTECTION option which supersedes
the previous ENABLE_PAUTH used for Armv8.3-A Pointer Authentication
and is disabled by default. Enabling BTI requires compiler support
and was tested with GCC versions 9.0.0, 9.0.1 and 10.0.0.
The assembly macros and helpers are modified to accommodate the BTI
instruction.
This is an experimental feature.
Note. The previous ENABLE_PAUTH build option to enable PAuth in EL3
is now made as an internal flag and BRANCH_PROTECTION flag should be
used instead to enable Pointer Authentication.
Note. USE_LIBROM=1 option is currently not supported.

Change-Id: Ifaf4438609b16647dc79468b70cd1f47a623362e
Signed-off-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
2019-05-24 14:44:45 +01:00

99 lines
2.2 KiB
ArmAsm

/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <cpuamu.h>
.globl cpuamu_cnt_read
.globl cpuamu_cnt_write
.globl cpuamu_read_cpuamcntenset_el0
.globl cpuamu_read_cpuamcntenclr_el0
.globl cpuamu_write_cpuamcntenset_el0
.globl cpuamu_write_cpuamcntenclr_el0
/*
* uint64_t cpuamu_cnt_read(unsigned int idx);
*
* Given `idx`, read the corresponding AMU counter
* and return it in `x0`.
*/
func cpuamu_cnt_read
adr x1, 1f
add x1, x1, x0, lsl #3 /* each mrs/ret sequence is 8 bytes */
#if ENABLE_BTI
add x1, x1, x0, lsl #2 /* + "bti j" instruction */
#endif
br x1
1: read CPUAMEVCNTR0_EL0
read CPUAMEVCNTR1_EL0
read CPUAMEVCNTR2_EL0
read CPUAMEVCNTR3_EL0
read CPUAMEVCNTR4_EL0
endfunc cpuamu_cnt_read
/*
* void cpuamu_cnt_write(unsigned int idx, uint64_t val);
*
* Given `idx`, write `val` to the corresponding AMU counter.
*/
func cpuamu_cnt_write
adr x2, 1f
add x2, x2, x0, lsl #3 /* each msr/ret sequence is 8 bytes */
#if ENABLE_BTI
add x2, x2, x0, lsl #2 /* + "bti j" instruction */
#endif
br x2
1: write CPUAMEVCNTR0_EL0
write CPUAMEVCNTR1_EL0
write CPUAMEVCNTR2_EL0
write CPUAMEVCNTR3_EL0
write CPUAMEVCNTR4_EL0
endfunc cpuamu_cnt_write
/*
* unsigned int cpuamu_read_cpuamcntenset_el0(void);
*
* Read the `CPUAMCNTENSET_EL0` CPU register and return
* it in `x0`.
*/
func cpuamu_read_cpuamcntenset_el0
mrs x0, CPUAMCNTENSET_EL0
ret
endfunc cpuamu_read_cpuamcntenset_el0
/*
* unsigned int cpuamu_read_cpuamcntenclr_el0(void);
*
* Read the `CPUAMCNTENCLR_EL0` CPU register and return
* it in `x0`.
*/
func cpuamu_read_cpuamcntenclr_el0
mrs x0, CPUAMCNTENCLR_EL0
ret
endfunc cpuamu_read_cpuamcntenclr_el0
/*
* void cpuamu_write_cpuamcntenset_el0(unsigned int mask);
*
* Write `mask` to the `CPUAMCNTENSET_EL0` CPU register.
*/
func cpuamu_write_cpuamcntenset_el0
msr CPUAMCNTENSET_EL0, x0
ret
endfunc cpuamu_write_cpuamcntenset_el0
/*
* void cpuamu_write_cpuamcntenclr_el0(unsigned int mask);
*
* Write `mask` to the `CPUAMCNTENCLR_EL0` CPU register.
*/
func cpuamu_write_cpuamcntenclr_el0
msr CPUAMCNTENCLR_EL0, x0
ret
endfunc cpuamu_write_cpuamcntenclr_el0