9.2. How To Handle Exceptions At Current Exception Level

9.2.1. Problem Statement

In previous generations of QNX on ARMv7 based processors, the QNX HLOS would catch exceptions and log output to terminal window in appropriate signal errors (SIGBUS, SIGABORT, etc). On the Jacinto 7, the QNX running on A72 core (which is ARMv8 based), update to the EA bit bit of the ARM SCR_EL3 register is set high by default in the ATF code, which is causing all exceptions to be routed to EL3, which in turns results in exception at terminal window, and lock up of system.

Setting of the EA bit to 0, at least for development or debug builds should be considered.

9.2.2. Overview

For SBL boot flow, the TI Processor SDK (as of SDK 7.3) has set the ARM SCR_EL3 EA Bit to a value of 0 when building the ATF. Please refer to the makefile used to build the SBL.

The SPL-UBoot boot flow will by default have the ARM SCR_EL3, EA bit set to 1. When SPL boot flow is being used on QNX, for debugging purposes or for drivers which require generation of a SIGBUS on QNX, the ARM SCRL_EL3 EA Bit can be set to 0

9.2.3. Solution

9.2.3.1. Option 1 - ATF code update

In order to set the EA bit 0, the below makefile can be modified, and the ATF rebuilt:

Edit:

${PSDKLA_PATH}/board-support/trusted-firmware-a-2.4/plat/ti/k3/common/plat_common.mk

Modify:

From: HANDLE_EA_EL3_FIRST := 1

To: HANDLE_EA_EL3_FIRST :0

9.2.3.2. Option 2 - ATF Build time

The other easy option which avoids modifying the makefile is to specify the HANDLE_EA_EL3_FIRST flag as a command line option during the build of the ATF (bl31.bin)

cd $(ATF_DIR)
make  -s -j32 CROSS_COMPILE=$(GCC_LINUX_ARM_ROOT)/bin/aarch64-none-linux-gnu- PLAT=k3 TARGET_BOARD=generic SPD=opteed HANDLE_EA_EL3_FIRST=0

9.2.4. How to control SCR_EL3 EA bit for SBL Bootflow

This is already supported as part of the Processor SDK QNX provided build scripts, which is used to build the SBL and dependent BootApp and AppImage binaries.

The path to the makefile is: ${PSDK_QNX_PATH}/qnx/scripts/sbl/makefile

9.2.5. How To control SCR_EL3 EA bit for SPL-UBoot Bootflow

For the SPL boot flow, the Uboot tispl.bin binary needs to be rebuilt with an updated Arm Trusted Firmware (ATF). The steps to build the Uboot + ATF binary are below:

  • Download and install the Processor SDK Linux for which uboot binary is desired.

  • Set environment variables in the build window, which will be required for building in the following steps:

export PSDKLA_PATH=<PATH to PSDK Linux Installation>
export CROSS_COMPILE=${PSDKLA_PATH}/linux-devkit/sysroots/x86_64-arago-linux/usr/bin/aarch64-none-linux-gnu-
  • Modify the arm-trusted-firmware to be built with SCR_EL3, EA bit set to 0

    Edit:

    ${PSDKLA_PATH}/board-support/trusted-firmware-a-2.4/plat/ti/k3/common/plat_common.mk

    Modify:

    From: HANDLE_EA_EL3_FIRST := 1

    To: HANDLE_EA_EL3_FIRST :0

  • Rebuild the Arm Trusted Firmware with these new settings, to generate an updated bl31.bin

cd ${PSDKLA_PATH}/board-support/trusted-firmware-a-2.4
make -s -j32  PLAT=k3 TARGET_BOARD=generic SPD=opteed
  • Backup the old bl31.bin and overwrite with the newly generated image.

cd ${PSDKLA_PATH},
cp ./board-support/prebuilt-images/bl31.bin ./board-support/prebuilt-images/bl31.bin.prebuilt
cp ./board-support/trusted-firmware-a-2.4/build/k3/generic/release/bl31.bin ./board-support/prebuilt-images/bl31.bin
  • Rebuild uboot as below, which will pull in the updated bl31.bin

cd ${PSDKLA_PATH}
make u-boot_clean; make u-boot
  • Copy the ${PSDKLA_PATH}/ board-support/u-boot_build/a72/tispl.bin, to the boot media. If using SD boot, this would be the root directory of the SD card.

9.2.6. Test & Example Output:

Read an address for a module that is not enabled/clocked. For example 0x28000000.

SIGBUS when EA Bit is to 0

Process 57363 (in32) terminated SIGBUS code=5 fltno=11 ip=00000000100c8b08(/proc /boot/in32@_btext+0x0000000000000078) mapaddr=0000000000000b08. ref=000000002800 0000
Bus error (core dumped)

Exception when EA Bit is set to 1

ERROR: Unhandled External Abort received on 0x80000000 at EL3!
ERROR: exception reason=1 syndrome=0x92000210
PANIC in EL3.
x30 = 0x0000000070005650
x0 = 0x0000000000000000
x1 = 0x0000000000000060
x2 = 0x0000000000000060
x3 = 0x0000000000000008
x4 = 0x0000000000000039
x5 = 0x0000000000000039
x6 = 0x0000000000000009
x7 = 0x0000000000000000
x8 = 0x00000000a0000000
x9 = 0x0000000041023020
x10 = 0x000000000000073d
x11 = 0x0000000000000001
x12 = 0x000000000000000f
x13 = 0x0fffffffffffffff
x14 = 0x0000000000000000
x15 = 0x0000000000000000
x16 = 0x00000000010ae360
x17 = 0x0000000001040bd0
x18 = 0x00000000100c7af0
x19 = 0x0000000000000001
x20 = 0x0000000092000210
x21 = 0x0000000000000002
x22 = 0xffffff80830ad000
x23 = 0x000000000000000b
x24 = 0x00000000100c7f80
x25 = 0xffffff80830aa090
x26 = 0xffffff80830aa0a0
x27 = 0x000000000000000c
x28 = 0x0000000000000000
x29 = 0x000000007000b520
scr_el3 = 0x000000000000073d
sctlr_el3 = 0x0000000030cd183f
cptr_el3 = 0x0000000000000000
tcr_el3 = 0x0000000080803520
daif = 0x00000000000002c0
mair_el3 = 0x00000000004404ff
spsr_el3 = 0x0000000060000000
elr_el3 = 0x00000000100c8b08
ttbr0_el3 = 0x00000000700100e0
esr_el3 = 0x0000000092000210
far_el3 = 0x0000000028000000
spsr_el1 = 0x0000000060000000
elr_el1 = 0x0000000001051560
spsr_abt = 0x0000000000000000
spsr_und = 0x0000000000000000
spsr_irq = 0x0000000000000000
spsr_fiq = 0x0000000000000000
sctlr_el1 = 0x0000000034d5db1d
actlr_el1 = 0x0000000000000000
cpacr_el1 = 0x0000000000000000
csselr_el1 = 0x0000000000000002
sp_el1 = 0xffffff8083044000
esr_el1 = 0x0000000056000051
ttbr0_el1 = 0x00140008fa916000
ttbr1_el1 = 0x000000008000b000
mair_el1 = 0xff000044eeaa0400
amair_el1 = 0x0000000000000000
tcr_el1 = 0x00000014b5183519
tpidr_el1 = 0x0000000000000000
tpidr_el0 = 0x0000000000000000
tpidrro_el0 = 0x00000000100c7f90
par_el1 = 0x0000000000000000
mpidr_el1 = 0x0000000080000000
afsr0_el1 = 0x0000000000000000
afsr1_el1 = 0x0000000000000000
contextidr_el1 = 0x0000000000000000
vbar_el1 = 0xffffff8060085800
cntp_ctl_el0 = 0x0000000000000000
cntp_cval_el0 = 0x0000000000000000
cntv_ctl_el0 = 0x0000000000000005
cntv_cval_el0 = 0x0000000656368901
cntkctl_el1 = 0x0000000000000002
sp_el0 = 0x000000007000b520
isr_el1 = 0x0000000000000040
dacr32_el2 = 0x0000000000000000
ifsr32_el2 = 0x0000000000000000
cpuectlr_el1 = 0x0000001b00000040
cpumerrsr_el1 = 0x0000000000000000
l2merrsr_el1 = 0x0000000000000000