Arm Community
Arm Community
  • Site
  • User
  • Site
  • Search
  • User
Open Source Software and Platforms
Open Source Software and Platforms
Wiki Guide to Debug Hafnium on Total Compute Platform
  • Help
  • Jump...
  • Cancel
  • About this wiki
  • Supported platforms
  • Obtaining support
  • +Arm Reference Platforms deliverables
  • -A-class platforms
    • +Juno
    • +FVPs
    • -Total Compute Platforms
      • Guide to Set Up Debugging Environment for Total Compute Software Stack
      • Guide to Debug RSS Firmware Booting on Total Compute Platform
      • Guide to Debug SCP Firmware Booting on Total Compute Platform
      • Guide to Set Up TF-A Firmwares Debug Environment on Arm DS for Total Compute Platform
      • Guide to Debug Hafnium on Total Compute Platform
      • Guide to Disable AP Secure Images on Total Compute Platform
      • Guide to Run OpenEuler Embedded on TC2 Platform
      • Guide to add "Hello World" application into edk2 of TC2 LSC platform?
      • Guide to Set Up Linux Kernel Debug Environment on Arm DS for Total Compute Platform
      • Guide to Set Up U-boot Debug Environment on Arm DS for Total Compute Platform
    • +Morello Platform
    • +System Guidance for Infrastructure (SGI)
    • +System Guidance for Mobile (SGM)
    • Corstone-500
    • Cortex-A5 DesignStart
    • +Neoverse N1 SDP
    • Neoverse Reference Designs
    • +Legacy platforms
  • +M-class platforms
  • +R-class platforms
  • +FPGA prototyping boards
  • +Open source software

You are currently reviewing an older revision of this page.

  • History View current version

Guide to Debug Hafnium on Total Compute Platform

Overview 

Hafnium is a reference Secure Partition Manager (SPM) for systems that implement the Armv8.4-A Secure-EL2 extension. It enables multiple, isolated Secure Partitions (SPs) to run at Secure-EL1. 

The Total Compute software stack also includes the BL32 (SPM), which is implemented as a Hafnium software component. You can find the introduction information at Total Compute Platform Software Components. 

The following figure shows the software stack of the TC platform: 

The TC software stack can support both the buildroot and Android file systems, because the hafnium is part of fimrware. This guide uess the buildroot file system as an example.

Step1: Setup the workspace for the TC software stack

Perform the following steps to build the whole software stack. Consider the buildroot file system as an example. For more information about seting up workspace, see the Total Compute (TC) User Guide.

  1. Download and set up the workspace , the content of the workspace directory is as follows: 



  2. Build the software stack. For example, you can use build command ./run_docker.sh ./build-all.sh build. After the build is successfully complete, the output images is as follows:



  3. Run the related image to boot up successfully
    ./run-scripts/tc2/run_model.sh -m <model binary path> -d buildroot

Step2: Work on the Hafnium component of TC software stack

The boot flow of AP firmware is as follows:

BL1 --> BL2 --> BL1 --> BL31 --> BL32(SPM) --> BL31 --> BL33

1. We need to add the debug build option to ensure that the symbol file can be used for later debugging as follows:

diff --git a/build/BUILD.gn b/build/BUILD.gn
index 1baac1ba..80b9f44d 100644
--- a/build/BUILD.gn
+++ b/build/BUILD.gn
@@ -20,6 +20,7 @@ config("compiler_defaults") {
     "-fstack-protector-all",
   ]

+  asmflags = ["-g"]
   cflags_c = [ "-std=c11" ]

   cflags_cc = [ "-std=c++2a" ]


2. Modify and build Hafnium seperatly

The build scirpt build-scripts/build-hafnium.sh can be used to build the Hafnium seperately, but the hafnium.bin image is added into the FIP package. Therefore, when you modify and build the source code of hafnium, you must re-package again. The steps can be as follows:

 

build-scripts/run_docker.sh build-scripts/build-hafnium.sh build
build-scripts/run_docker.sh build-scripts/build-hafnium.sh deploy
build-scripts/run_docker.sh build-scripts/build-tfa.sh build
build-scripts/run_docker.sh build-scripts/build-tfa.sh deploy
build-scripts/run_docker.sh build-scripts/build-flash-image.sh build
build-scripts/run_docker.sh build-scripts/build-flash-image.sh deploy

Step3: Setup Arm DS to debug Hafnium 

1. Import the TC22 FVP model 

a) New debug Connection

From the ARM DS  Debug control pannel, navigate to "Debug Congtrol--> New Debug Connection" as follows:


 

b) Choose "Model Connection"

Then, create the "Debug connection" name, such as "TC22-Hafnium-debug" as follows:

c)  Add new model  

Then, choose "Next" button  for "Target Selection", we can choose "Add a new model ..." as follows:

d) Configure the FVP model path

Then, follow the steps of below, "Select Model Interface(Iris)" --> Next--> choose "Launch and connect to specific model" --> Next --> Browse the Model Path to select the downloaded file path of “TC22 model” as follows:

e) Show the imported model

At last, the model is imported as follows:

2 Connect the model

a) Find the created debug connection

Open the debug configration as follows:



b) Setup the model parameters

For example, copy below model paramters into the label as follows:

-C board.flashloader0.fname=/data/jetzho01/tc22-2023.04.21/build-scripts/output/deploy/tc2/fip_gpt-tc.bin -C css.rss.rom.raw_image=/data/jetzho01/tc22-2023.04.21/build-scripts/output/deploy/tc2/rss_rom.bin -C css.scp.c0_pik.rvbaraddr_lw=0x1000 -C css.scp.c0_pik.rvbaraddr_up=0x0000 -C css.rss.VMADDRWIDTH=23 -C css.rss.CMU0_NUM_DB_CH=16 -C displayController=2 -C board.smsc_91c111.enabled=1 -C board.hostbridge.userNetworking=1 -C board.hostbridge.userNetPorts="5555=5555,8080=80,8022=22" --data board.dram=/data/jetzho01/tc22-2023.04.21/build-scripts/output/deploy/tc2/tc-fitImage.bin@0x20000000

c) Loaded the symbol files to apply and debug as follows:


On the window that opens, navigate to the "Debugger" tab, tick "Connect only", tick "Execute debugger commands", and copy-paste the following into the text box to automatically load all symbols into the correct virtual address space each time you connect to the model:

add-symbol-file "<workspace>/build-scripts/output/tmp_build/tfa/build/tc/debug/bl1/bl1.elf" EL3:0x0
add-symbol-file "<workspace>/build-scripts/output/tmp_build/tfa/build/tc/debug/bl2/bl2.elf" EL1S:0x0
add-symbol-file "<workspace>/build-scripts/output/tmp_build/tfa/build/tc/debug/bl31/bl31.elf" EL3:0x0
add-symbol-file "<workspace>/build-scripts/output/tmp_build/hafnium/secure_tc_clang/hafnium.elf" EL2S:0x0

Replacing <workspace> with the path to your workspace directory.

The EL and number at the end of each command (e.g. `EL2S:0') ensure the symbols are loaded into the correct virtual address space and at the correct memory offset, for software uses absolute addresses for its symbols so we ensure an offset of 0.

Click "Apply" and then "Debug" to connect to the paused model. You can now step through the Hafnium code or set a breakpoint on the symbol corresponding to the functionality that you are interested.

3 Debugging entrypoint for Hafnium

a) Find the entrypoint for Hafnium image

Entry point of Hafnium code piece is here, for example

.section .init.entry, "ax"
.global entry
entry:
	/* Linux aarch64 image header. */
	b 0f
	.word 0
	.quad 0x1000      /* text_offset */
	.quad image_size  /* image_size */
	.quad 0           /* flags */
	.quad 0           /* res2 */
	.quad 0           /* res3 */
	.quad 0           /* res4 */
	.word 0x644d5241  /* magic */
	.word 0

	/*
	 * Calculate the difference between the actual load address and the
	 * preferred one. We'll use this to relocate.
	 */
0:	adrp x25, entry
	add x25, x25, :lo12:entry

Regarding the entrypoint(loading address) of Hafnium for TC22 platform. The Hafnium(BL32) is loaded by AP BL2, the image address is defined as "BL32_BASE" which can be found at here, specifically for the TC22 platform, the address is redefined as:

"#define TC_EL2SPMC_LOAD_ADDR            (TC_TZC_DRAM1_BASE + 0x04000000)"

The TC_TZC_DRAM1_BASE is defined as 0xF900_0000, so the loading address for Hafnium(BL32_BASE) is 0xFD00_0000.

More plaform definition about this can be found here.

b) Stop at the entrypoint

Set the breakpoint of "entry" which is the entrypoint of Hafnium as follows:

c) Check the entry address of Hafnium 

Then Run, it will stop the first instruction, the address is 0xFD000000 as follows:

              

About Debuging other related functions

The initialize flow of Hafnium is as follows:





Example function of "one_time_init"

For example, set breakpoint of "one_time_init", jump into it as follows