You are on page 1of 28

Design a TrustZone-Enalble SoC using

the Xilinx VIVADO CAD Tool


El Mehdi Benhani, Lilian Bossuet
Hubert Curien Laboratoty
University of Lyon, Saint-Etienne, France
Emails: elmehdi.benhani@univ-st-etienne.fr,
lilian.bossuet@univ-st-etienne.fr,

Introduction
This tutorial will guide you through the steps of creating a TrustZone-enabled design using the Xilinx Vivado software. In this
guide, we will show you how to propagate the TrustZone security into the FPGA, how to configure the security signals in the FPGA
and how to separate the design into a secure world and a non-secure world.
Tutorial files:

For the secure world For the non-secure world


monitor.S boot.S
normal.S lscript.ld
platform.c
lscript.ld

The monitor.S file contains the SMC (Secure Monitor Call) routine, which is used to switch from a world to another by saving the
context of the initial world and restoring the context of the destination world. For each world, the context is saved on a different
stack. This file also contains the monitor mode initialization function which sets the monitor exception vector and initializes the
secure and non-secure stacks.
The normal.S file includes the link of the non-secure binary code.
The platform.c file includes the TrustZone initialization function.
The boot.S file is a modified Xilinx standalone boot file on which CP15 configurations that would cause an exception in non-secure
worlds have been removed.
The lscript.ld files are linked scripts, these files include modifications of the memory regions conforming to the Xilinx UG1019
TrustZone memory configuration.
For more details about these files, refer to the software implementation section.

1
1. Creating a new project
1-1. Launch Vivado 2017.1
1-2. Click Create Project to start a new project wizard. The Create a New Vivado Project dialog box will appear. Click Next.
1-3. Choose a project name in the Project Name field, then a location folder in Project Location field. Click Next.

Figure 1: Project Name Entry

1-4. In the Project Type form, select RTL Project, check Do not specify sources at this time and click Next.

Figure 2: Project Type selection

1-5. In the Default Part form, select Boards, choose the board you are using (Zybo in this example) and click Next.

2
Figure 3: Board selection

1-6. Click Finish to create an empty Vivado project.

2. Creating the System Using the IP Integrator


2-1. In the Flow Navigator, click Create Block Design under IP Integrator.

Figure 4: Create IP Integrator Block Diagram

2-2. Set Design name to system and click OK.

3
Figure 5: Creating a new block design

2-3. Click the Add IP icon in the block diagram.

2-4. Once the IP Catalogue is open, find and select. ZYNQ7 Processing System. Add it to the design by double-clicking on it or
pressing the Enter key.

Figure 6: IP Catalogue

2-5. Notice that a “Designer Assistance available” message appears after creating the Processing System IP (figure 7). Click Run
Block Automation and select /processing_system7_0.

Figure 7: Run block automation

2-6. In the Run Block Automation window, make sure Apply Board Preset is checked and leave the other parameters to their
default values. Click OK.

4
Figure 8 : Block Automation settings

2-7. Double-click on the ZYN7 Processing System block to customize it.

Figure 9 : ZYNQ7 Processing System Block

5
Figure 9 : ZYNQ7 Processing System block settings

2-8. Select the Interrupts tab on the page navigator. Expand Fabric Interrupts then expand PL-PS Interrupt Ports. Check Fabric
Interrupts, then check IRQ_F2P[15:0] and Core0_nFIQ. Click OK.

Figure 10 : IRQ and FIQ interrupts activation

2-9. Click the Add IP icon and find AXI GPIO in the IP catalogue.

6
Figure 11: GPIO IP

2-10. Add the AXI GPIO IP to the design. The block diagram will be updated.

Figure 12: Adding a new AXI GPIO to the design

2-11. Select the new AXI GPIO block. Rename the block to Leds in the Block Properties tab.

Figure 6 : Change AXI GPIO default name

2-12. A “Design assistance available” message should be appearing. Click Run Connection Automation to open the connection
automation window. Check All Automation then select GPIO. On the Select Board Part Interface parameter, select leds_4bits.
Click OK to run the connection automation.

7
Figure 7 : LEDs Connection Automation

2-13. Notice that two additional blocks have been automatically added to the design: Processor System Reset and AXI
Interconnect. You can rearrange the design by clicking on the Regenerate icon .

Figure 8 : Design with leds automatically connected

2-14. Use Add IP icon + to add create two new instances of the AXI GPIO IP. Name them buttons_FIQ, and buttons_IRQ.
2-15. Double click on the buttons_IRQ block to open its customization window.
2-16. Move to the IP Configuration tab. Under GPIO, check All Inputs and set GPIO Width to 2. Make sure Enable Dual Channel
is unchecked and check Enable Interrupt. Click OK.

8
Figure 9 : GPIO interrupt enabled

2-17. Open the buttons_FIQ customization window and configure it like buttons_IRQ on step 2-16.
2-18. The “Design assistance available” message should be appearing. Click on Run Connection Automation, and check the All
Automation box.
2-19. Select GPIO under buttons_FIQ, and change Select Board Part Interface to Custom. Do the same configuration for GPIO
under buttons_IRQ. Click OK.

Figure 10 : buttons_IRQ and buttons_FIQ connection automation


9
2-20. Connect the interrupt port of buttons_IRQ to IRQ_F2P[0:0] in the ZYNQ7 Processing System block. Connect the interrupt
port of buttons_FIQ to Core0_nFIQ.

Figure 11 : Interrupts signals from the buttons to the processing system

2-21. The external port of buttons_FIQ should be named gpio_rtl or gpio_rtl_0. Rename it to but_FIQ. Rename the external
port of buttons_IRQ to but_IRQ.

Figure 12 : Final design

3. TrustZone activation in PL system


3-1. Double click on the ZYNQ7 Processing System block to open its customization window.
3-2. Select the PS-PL Configuration tab on the page navigator, and set AXI Non Secure Enablement to 1.
10
Figure 13 : Non-secure transactions enablement

This parameter will allow non-secure transactions to go through the AXI Bus in the PL system (FPGA part). We will now see how
to extend the TrustZone security to the FPGA by declaring secure IPs.
3-3. Double click on the AXI Interconnect block to open its customization window.

Figure 14 : The AXI Interconnect block

3-4. Check Enable Advanced Configuration Options and move to the Advanced Options tab.

11
Figure 15 : AXI interconnect advanced configuration options enablement

3-5. In our design, M00_AXI is the master controlling the LEDs GPIO peripheral. In order to make the LEDs IP secure, check the
Secure Slave option for M00_AXI. You can also make the button IPs secure. To find out which AXI Bus is used for the IP you want
to make secure, simply check the connections in the block design. For example, buttons_IRQ is connected to the AXI Interconnect
block through the M01_AXI port (figure 26).

Figure 26: AXI Connection ports

12
Figure 27: Enabling LEDs security

3-6. Run the design validation tool (Tools → Validate Design) and make sure there are no errors.

4. Generating the bitstream and exporting it to XSDK

4-1. In the Sources panel, right click on system (system.bd), and select Create HDL Wrapper. Leave the Let Vivado manage
wrapper and auto-update option selected, and click OK.

Figure 28: Creating HDL Wrapper

13
Figure 29: Creating HDL Wrapper validation

4-2. In the Flow Navigator, click Run Synthesis. If prompted, click Save. When the synthesis completes, select Open Synthesized
Design and click OK.
4-3. Select I/O Planning.

Figure 30: Synthesized design

4-4. In the I/O ports tab, expand the two GPIO ports then expand but_irq_tri_i and but_fiq_tri_i. You need to configure the I/O
Std and Package Pin parameters conforming to the board you are using. In this example, we are using the ZYBO ZYNQ-7000 board
and setting all IO/Std parameters to LVCMOS33. Refer to the Reference Manual of your board to find the Package Pins that
correspond to the peripherals you want to use.

14
Figure 31: The IP port pin constraints

4-4. Save your modifications (File → Save Constraints or hit Ctrl+S) in constraint file. A save window will appear, type a file name
then click OK.

Figure 32: saving constraints file

4-5. Go back to the Flow Navigator and click on Generate Bitstream.


4-6. Click on File → Export → Export Hardware. Check Include bistream and click OK.

Figure 32 : Exporting the hardware

15
4-7. Click on File → Launch SDK to open XSDK with your project files.

5. Software implementation
5-1. Before creating the software projects, it is recommended to disable the automatic build feature (Project → Build
Automatically). To create a new project, select File → New →Application Project.
5-2. In the Project name field, type secure. Click Next.

Figure 16 : Application creation

5-3. Select Hello World from the available templates and click Finish.

16
Figure 17 : Application templates

5-4. Follow the same steps to create a non_secure application. In the secure application, rename helloworld.c to main_secure.c.
Rename helloworld.c of the non_secure application to main_nonsecure.c.

Figure 18: secure and non-secure applications

5-5. Change main_nonsecure.c to the example code of figure 36.

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"

#define SMC __asm__("SMC #0")

int main()
{
/* Move to the secure world */
SMC;

17
for (unsigned char i = 0; i < 5; i++)
{
/* Print a message then move to the secure world */
xil_printf("Hello from non_secure world !\n");
SMC;
}

return 0;
}

Figure 19 : non-secure main code example

5-6. Replace non_secure/src/lscript.ld with the lscript.ld file you can find on the Annex of this tutorial.
By default, the main memory is divided into 64 Mbit memory regions. XSDK provides a register configuration to make each
memory region either secure or non-secure. The non-secure lscript.ld provided with this tutorial maps the non-secure code in
the second 64Mbit memory region.
5-7. Using the project explorer, move to the non_secure_bsp/ps7_cortexa9_0/libsrc/standalone_v6_2/src/ folder. Replace the
boot.S file with the one you can find on the Annex of this tutorial.
Secure configurations have been removed from the non-secure boot.S to allow the non-secure world to boot without causing
exceptions.
5-8. If you haven’t enabled the automatic build feature, build the non_secure application by selecting it and clicking the build IP
icon .
5-9. Change main_secure.c to the example code of figure 37.
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"

#define SMC __asm__("SMC #0")

extern void monitorInit();

int main()
{
init_platform();

/* Monitor mode initialization */


monitorInit();

for (unsigned char i = 0; i < 5; i++)


{
/* Print a message then move to the normal world */
xil_printf("Hello from secure world !\n");
SMC;
}

cleanup_platform();
return 0;
}

Figure 20 : secure main code example

5-10. Replace secure/src/platform.c with the platform.c file provided on the Annex of this tutorial.

18
5-11. Replace secure/src/lscript.ld with the lscript.ld file provided on the Annex of this tutorial.
5-12. Copy monitor.S and normal.S from the Annex of this tutorial to the secure/src/ folder on the project explorer.

Figure 21 : Secure application after modification

5-13. We will now convert the non_secure.elf file in the non_secure/Binaries folder to binary file (.bin). In the next steps, we
will copy this file to the secure/Debug/src/ folder to allow the secure project to build with the normal world binary.
5-14. Go to Window → Show View → Other and find XSCT Console. Click OK to add the XSCT Console to your view.
5-15. In the XSCT Console, move to the .sdk folder of your project. For example, if your project is named trustzone_app, you can
move by using this command :
cd trustzone_app.sdk

5-15. Execute the following commands in the XSCT Console :


exec arm-none-eabi-objcopy -S -O binary non_secure/Debug/non_secure.elf non_secure.bin
exec cp non_secure/Debug/non_secure.bin secure/Debug/src
exec rm secure/Debug/src/normal.o

To avoid typing these commands after each creation of a new non-secure build, you can create a TCL file (for example,
auto_build.tcl) and put the commands on this file. This file needs to be placed on the .sdk folder of your project. You can execute
it using this command :
source auto_build.tcl

5-16. Build the secure application by selecting it and clicking the build icon .

5-17. Once the compilation finishes, you can debug your application to the destination platform.

Figure 39: Expected result using the example codes

19
Annex:
In this annex, some file are not complete. We just present the modification with blue to apply to the file generated
by Xilinx.
Non-secure :
lscript.ld
You need to change only the start address of the non_secure application, and it size.
…………………..

MEMORY
{
ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x4000000, LENGTH = 0x4000000
ps7_qspi_linear_0_S_AXI_BASEADDR : ORIGIN = 0xFC000000, LENGTH = 0x1000000
ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x0, LENGTH = 0x30000
ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
}

…………………..

boot.S
.globl MMUTable
.global _prestart
.global _boot
.global __stack
.global __irq_stack
.global __supervisor_stack
.global __abort_stack
.global __fiq_stack
.global __undef_stack
.global _vector_table

.set TblBase , MMUTable

/* Stack Pointer locations for boot code */


.set Undef_stack, __undef_stack
.set FIQ_stack, __fiq_stack
.set Abort_stack, __abort_stack
.set SPV_stack, __supervisor_stack
.set IRQ_stack, __irq_stack
.set SYS_stack, __stack

.set vector_base, _vector_table

.section .boot,"ax"

/* this initializes the various processor modes */

_prestart:
_boot:

/* set VBAR to the _vector_table address in linker script */


ldr r0, =vector_base
mcr p15, 0, r0, c12, c0, 0
20
/* Invalidate caches and TLBs */
mov r0,#0 /* r0 = 0 */
mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */

/* Disable MMU, if enabled */


mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 */
bic r0, r0, #0x1 /* clear bit 0 */
mcr p15, 0, r0, c1, c0, 0 /* write value back */

mrs r0, cpsr /* get the current PSR */


mvn r1, #0x1f /* set up the irq stack pointer */
and r2, r1, r0
orr r2, r2, #0x12 /* IRQ mode */
msr cpsr, r2
ldr r13,=IRQ_stack /* IRQ stack pointer */
bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */
msr spsr_fsxc,r2

mrs r0, cpsr /* get the current PSR */


mvn r1, #0x1f /* set up the supervisor stack pointer */
and r2, r1, r0
orr r2, r2, #0x13 /* supervisor mode */
msr cpsr, r2
ldr r13,=SPV_stack /* Supervisor stack pointer */
bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */
msr spsr_fsxc,r2

mrs r0, cpsr /* get the current PSR */


mvn r1, #0x1f /* set up the Abort stack pointer */
and r2, r1, r0
orr r2, r2, #0x17 /* Abort mode */
msr cpsr, r2
ldr r13,=Abort_stack /* Abort stack pointer */
bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */
msr spsr_fsxc,r2

mrs r0, cpsr /* get the current PSR */


mvn r1, #0x1f /* set up the FIQ stack pointer */
and r2, r1, r0
orr r2, r2, #0x11 /* FIQ mode */
msr cpsr, r2
ldr r13,=FIQ_stack /* FIQ stack pointer */
bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */
msr spsr_fsxc,r2

mrs r0, cpsr /* get the current PSR */


mvn r1, #0x1f /* set up the Undefine stack pointer */
and r2, r1, r0
orr r2, r2, #0x1b /* Undefine mode */
msr cpsr, r2
ldr r13,=Undef_stack /* Undefine stack pointer */
bic r2, r2, #(0x1 << 9) /* Set EE bit to little-endian */
msr spsr_fsxc,r2

mrs r0, cpsr /* get the current PSR */


mvn r1, #0x1f /* set up the system stack pointer */
and r2, r1, r0
orr r2, r2, #0x1F /* SYS mode */
msr cpsr, r2

21
ldr r13,=SYS_stack /* SYS stack pointer */

MOV r0, #0x0


MCR p15, 0, r0, c8, c7, 0

ldr r0,=TblBase /* Load MMU translation table base */


mcr 15, 0, r0, c2, c0, 0 /* TTB0 */

mvn r0,#0 /* Load MMU domains -- all ones=manager */


mcr p15,0,r0,c3,c0,0

mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 */


orr r0, r0, #0x1 /* clear bit 0 */
mcr p15, 0, r0, c1, c0, 0 /* write value back */
dsb /* dsb allow the MMU to start up */
isb /* isb flush prefetch buffer */

/* Write to ACTLR */
mrc p15, 0, r0, c1, c0, 1 /* Read ACTLR*/
orr r0, r0, #(0x01 << 6) /* set SMP bit */
orr r0, r0, #(0x01 ) /* Cache/TLB maintenance broadcast */
mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/

b _start /* jump to C startup code */


and r0, r0, r0 /* no op */

.Ldone: b .Ldone /* Paranoia: we should never get here */

.end

Secure:
monitor.S
.section .vector_mon, "ax"
.align 5

.global monitor
monitor:
B . /* Reset - not used by Monitor */
B . /* Undef - not used by Monitor */
B SMC_Handler
B . /* Prefetch - can by used by Monitor */
B . //Data_abort /* can by used by Monitor */
B . /* RESERVED */
B . //IRQ_monitor /* can by used by Monitor */
B . //FIQ_monitor /* can by used by Monitor */

Mode_MON = 0x16
Mode_SVP = 0x13
NS_BIT = 0x1

@ -----------------------------------------------------------
@ Fonction définie au monde sécurisé sur laquelle on rentre
@ après chaque SMC du monde normal
@ ------------------------------------------------------------
.extern SecureWorldEnter

22
@ ------------------------------------------------------------
@ SMC Handler
@
@ - Detect which world executed SMC
@ - Saves state to appropriate stack
@ - Restores other worlds state
@ - Switches world
@ - Performs exception return
@ ------------------------------------------------------------
.global SMC_Handler
SMC_Handler:

PUSH {r0-r3} @ R0-r3 contain args to be passed between worlds


@ Temporarily stack, so can be
used as scratch regs

@ Which world have we come from


@ ------------------------------
MRC p15, 0, r0, c1, c1, 0 @ Read Secure Configuration Register data
TST r0, #NS_BIT @ Is the NS bit set?
EOR r0, r0, #NS_BIT @ Toggle NS bit
MCR p15, 0, r0, c1, c1, 0 @ Write Secure Configuration Register data

@ Load save to pointer


@ ---------------------
LDREQ r0, =S_STACK_SP @ If NS bit set, was in Normal world. So restore
Secure state
LDRNE r0, =NS_STACK_SP
LDR r2, [r0]

@ Load restore from pointer


@ --------------------------
LDREQ r1, =NS_STACK_SP
LDRNE r1, =S_STACK_SP
LDR r3, [r1]

@ r2 <-- save to
@ r3 <-- restore from

@ Save general purpose registers, SPSR and LR


@ --------------------------------------------
STMFD r2!, {r4-r12} @ Save r4 to r12
@ ADD SUPPORT FOR SPs
MRS r4, spsr @ Also get a copy of the SPSR
STMFD r2!, {r4, lr} @ Save original SPSR and LR

STR r2, [r0] @ Save updated pointer back, r0 and r2 now free

@ Restore other world registers, SPSR and LR


@ ---------------------------------------------
LDMFD r3!, {r0, lr} @ Get SPSR and LR from
@ ADD SUPPORT FOR SPs
MSR spsr_cxsf, r0 @ Restore SPSR
LDMFD r3!, {r4-r12} @ Restore registers r4 to r12

STR r3, [r1] @ Save updated pointer back, r1 and r3 now free

@ Clear local monitor


@ --------------------
CLREX

23
@ Move to SecureWorldEnter if we're going to the secure world
@ --------------------
MRC p15, 0, r0, c1, c1, 0
CMP r0, #NS_BIT
POP {r0-r3}
MOVS pc, lr

/* FPU enable bit, (1 << 30) */


.set FPEXC_EN, 0x4000000

@ ------------------------------------------------------------
@ Monitor Initialization
@
@ This is called the first time the Secure world wishes to
@ move to the Normal world.
@ ------------------------------------------------------------

.global monitorInit
.global ns_image
monitorInit:

@ Install Secure Monitor


@ -----------------------
LDR r0, =monitor @ Get address of Monitors vector table
MCR p15, 0, r0, c12, c0, 1 @ Write Monitor Vector Base Address Register
LDR r1, =ns_image /* R1 is used !!!!*/

@ Save Secure state


@ ------------------
LDR r0, =S_STACK_LIMIT @ Get address of Secure state stack
STMFD r0!, {r4-r12} @ Save general purpose registers
@ ADD support for SPs
MRS r1, cpsr @ Also get a copy of the CPSR
STMFD r0!, {r1, lr} @ Save CPSR and LR

@ Switch to Monitor mode


@ -----------------------
CPS #Mode_MON @ Move to Monitor mode after saving Secure state

@ Save Secure state stack pointer


@ --------------------------------
LDR r1, =S_STACK_SP @ Get address of global
STR r0, [r1] @ Save pointer

@ Set up initial NS state stack pointer


@ --------------------------------------
LDR r0, =NS_STACK_SP @ Get address of global
LDR r1, =NS_STACK_LIMIT @ Get top of Normal state stack (assuming FD model)
STR r1, [r0] @ Save pointer

MRC p15, 0, r0, c1, c1, 2


ORR r0, r0, #(0x3<<10)
ORR r0, r0, #(0x3<<17)
MCR p15, 0, r0, c1, c1, 2

LDR r0, =(0xF << 20)


MCR p15, 0, r0, c1, c0, 2

24
@ Set up exception return information
@ ------------------------------------
@IMPORT ns_image

LDR lr, =ns_image @ ns_image


MSR spsr_cxsf, #Mode_SVP @ Set SPSR to be SVC mode

@ Switch to Normal world


@ -----------------------
MRC p15, 0, r4, c1, c1, 0 @ Read Secure Configuration Register data
ORR r4, #NS_BIT @ Set NS bit
MCR p15, 0, r4, c1, c1, 0 @ Write Secure Configuration Register data

@ Enable FPU
@ -------------
fmrx r1, FPEXC /* read the exception register */
orr r1,r1, #FPEXC_EN /* set VFP enable bit, leave the others in orig
state */
fmxr FPEXC, r1 /* write back the exception register */

@ Clear general purpose registers


@ --------------------------------
MOV r0, #0
MOV r1, #0
MOV r2, #0
MOV r3, #0
MOV r4, #0
MOV r5, #0
MOV r6, #0
MOV r7, #0
MOV r8, #0
MOV r9, #0
MOV r10, #0
MOV r11, #0
MOV r12, #0

MOVS pc, lr

@ ------------------------------------------------------------
@ Space reserved for stacks
@ ------------------------------------------------------------

NS_STACK_BASE:
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
NS_STACK_LIMIT:

S_STACK_BASE:
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
S_STACK_LIMIT:

NS_STACK_SP:
.word 0

S_STACK_SP:
.word 0

@.end

25
normal.S

.global ns_image
.align 8
.section .NSECURE_IMAGE, "ax"

ns_image:
.incbin "src/normal.bin"

.end

platform.c

Addition of some macro define for Trustzone registers, and an initialization function for that init the Trustzone
blocks.

………………

#define SECURITY2_SDIO0 0XE0200008


#define SECURITY3_SDIO1 0XE020000C
#define SECURITY4_QSPI 0XE0200010
#define SECURITY5_MIOU 0XE0200014
#define SECURITY6_APB_SLAVES 0XE0200018
#define SECURITY7_SMC 0XE020001C

#define SECURE_CONFIG_LOCK 0xF8000000


#define SCLR_LOCK 0xF8000004
#define SCLR_LOCK_VAL 0x0000767B
#define SCLR_UNLOCK 0xF8000008
#define SCLR_UNLOCK_VAL 0x0000DF0D

#define DMAC_RST_CTRL 0XF800020C


#define TZ_OCM_RAM0 0XF8000400
#define TZ_OCM_RAM1 0XF8000404
#define TZ_OCM_ROM 0XF8000408
#define TZ_DDR_RAM 0XF8000430
#define TZ_DMA_NS 0XF8000440
#define TZ_DMA_IRQ_NS 0XF8000444
#define TZ_DMA_PERIPH_NS 0XF8000448
#define TZ_GEM 0XF8000450
#define TZ_SDIO 0XF8000454
#define TZ_USB 0XF8000458
#define TZ_FPGA_M 0XF8000484
#define TZ_FPGA_AFI 0XF8000488
#define SECURITY_FSSW_S0 0XF890001C
#define SECURITY_FSSW_S1 0XF8900020
#define SECURITY_APB 0XF8900028

void init_TZ()
{
Xil_Out32(SCLR_UNLOCK,SCLR_UNLOCK_VAL);
Xil_Out32(SECURITY6_APB_SLAVES,0x80);
Xil_Out32(TZ_DDR_RAM,0x6);
Xil_Out32(SCLR_LOCK,SCLR_LOCK_VAL);
}

………………
26
void
init_platform()
{
/*
* If you want to run this example outside of SDK,
* uncomment one of the following two lines and also #include "ps7_init.h"
* or #include "ps7_init.h" at the top, depending on the target.
* Make sure that the ps7/psu_init.c and ps7/psu_init.h files are included
* along with this example source files for compilation.
*/
/* ps7_init();*/
/* psu_init();*/

init_TZ();

enable_caches();
init_uart();
}

………………

lscript.ld

Modification of the start address of the secure application,


Addition of a section for the non-secure binary,
Addition of the monitor stack with two partition, one secure and one non-secure.

…………………………………………………………………………………………………

_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;


_MON_STACK_SIZE = DEFINED(_MON_STACK_SIZE) ? _MON_STACK_SIZE : 1024;
_TAB_SIZE = DEFINED(_TAB_SIZE) ? _TAB_SIZE : 32;

/* Define Memories in the system */

MEMORY
{
ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x100000, LENGTH = 0x4000000
ps7_ddr_1_S_AXI_BASEADDR : ORIGIN = 0x4000000, LENGTH = 0x4000000
ps7_ddr_share : ORIGIN = 0x8000000, LENGTH = 0x4000000
axi_bram_ctrl_0_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x2000
}

/* Specify the default entry point to the program */

ENTRY(_vector_table)

/* Define the sections, and where they are mapped in memory */

/* ../../secure_bsp/ps7_cortexa9_0/libsrc/standalone_v6_0/src/ */

SECTIONS
{
.text : {

27
KEEP (*(.vectors))
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ddr_0_S_AXI_BASEADDR

…………………………………………………………………………………………………

__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
_mon_stack_end = .;
_s_stack_end = .;
. += _TAB_SIZE;
. = ALIGN(16);
__s_stack = .;
. += _MON_STACK_SIZE;
. = ALIGN(16);
_ns_stack_end = .;
. += _TAB_SIZE;
. = ALIGN(16);
__ns_stack = .;
__mon_stack = .;
} > ps7_ddr_0_S_AXI_BASEADDR

.NORMAL_IMAGE : {
__NORMAL_IMAGE_start = .;
KEEP (*(.NSECURE_IMAGE))
__NORMAL_IMAGE_end = .;
} > ps7_ddr_1_S_AXI_BASEADDR

_end = .;
}

28

You might also like