11.2. How To Handle Exceptions At Current Exception Level

11.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’s A72 core(which is ARMv8),the ATF code sets up the default exception level to EL3 by configuring the EA bit in the ARM SCR_EL3 register. When running QNX HLOS, any exception generated by the software causes the exception to be handled by ATF, which in turn dumps the exception log and locks up the system.

11.2.2. Solution

Setting of the EA bit to 0, for development or debug builds should be considered, so that exceptions are handled by the QNX HLOS kernel.

For SBL boot flow, the TI Processor SDK (as of SDK 7.3) sets 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.

For the SPL-UBoot boot flow, ARM SCR_EL3 EA bit is set to 1 by default. When SPL boot flow is being used for booting QNX, it is desired that the software program exceptions (like SIGBUS) are handled by the QNX Kernel. To acheive this, we need to re-build ATF (part of U-Boot) with the ARM SCRL_EL3 EA Bit set to 0.

11.2.3. Building ATF

11.2.3.1. Option 1 - ATF makefile update

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

Edit:

${ATF_DIR}/plat/ti/k3/common/plat_common.mk

Modify:

From: HANDLE_EA_EL3_FIRST_NS := 1

To: HANDLE_EA_EL3_FIRST_NS :0

11.2.3.2. Option 2 - ATF build-command

The other easy option which avoids modifying the makefile is to specify the HANDLE_EA_EL3_FIRST_NS 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 HANDLE_EA_EL3_FIRST_NS=0

11.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 or Processor SDK RTOS provided vision_apps build scripts, which is used to build the SBL and dependent BootApp and AppImage binaries.

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

The Processor SDK RTOS path to the makefile is: ${PSDK_RTOS_PATH}/vision_apps/makerules/makefile_sbl.mak

11.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_NS := 1

    To: HANDLE_EA_EL3_FIRST_NS :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.

11.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