sw_apps:zynqmp_fsbl: Added A53 32-bit support in FSBL

This patch adds support for FSBL running in A53 32-bit mode and
also supports handing off to A53 32-bit applications from FSBL.

Signed-off-by: Sarat Chand Savitala <saratcha@xilinx.com>
Acked-by: Krishna Chaitanya Patakamuri <kpataka@xilinx.com>
This commit is contained in:
Sarat Chand Savitala 2015-08-06 01:36:31 +05:30 committed by Nava kishore Manne
parent 754a82e98b
commit 84204047c7
7 changed files with 182 additions and 29 deletions

View file

@ -119,7 +119,7 @@ proc swapp_generate {} {
set hw_processor [common::get_property HW_INSTANCE $proc_instance]
set proc_type [common::get_property IP_NAME [hsi::get_cells -hier $hw_processor]];
# based on the CPU (A53 or R5),
# based on the CPU (A53 64-bit, A53 32-bit or R5),
# remove unnecesary linker script and retain just one: lscript.ld
# set the compiler flags
if { $proc_type == "psu_cortexr5" } {
@ -130,16 +130,29 @@ proc swapp_generate {} {
-value {-Wall -fmessage-length=0 -mcpu=cortex-r5 -mfloat-abi=softfp} \
-objects [current_sw_design ]
} else {
set ld_file "lscript.ld"
file delete -force $ld_file
set compiler [get_property CONFIG.compiler $proc_instance]
set ld_file_a53 "lscript_a53.ld"
set ld_file_new "lscript.ld"
file rename -force $ld_file_a53 $ld_file_new
if {[string compare -nocase $compiler "arm-none-eabi-gcc"] == 0} {
# A53 32-bit : Use same linker script as that of R5
set ld_file_a53 "lscript_a53.ld"
file delete -force $ld_file_a53
set_property -name {APP_COMPILER_FLAGS} \
-value {-Wall -fmessage-length=0 -DXFSBL_A53} \
-objects [current_sw_design ]
set_property -name {APP_COMPILER_FLAGS} \
-value {-Wall -fmessage-length=0 -march=armv7-a} \
-objects [current_sw_design ]
} else {
#A53 64-bit
set ld_file "lscript.ld"
file delete -force $ld_file
set ld_file_a53 "lscript_a53.ld"
set ld_file_new "lscript.ld"
file rename -force $ld_file_a53 $ld_file_new
set_property -name {APP_COMPILER_FLAGS} \
-value {-Wall -fmessage-length=0 -DXFSBL_A53} \
-objects [current_sw_design ]
}
}
}

View file

@ -32,7 +32,7 @@
/*******************************************************************/
/* */
/* Description : FSBL R5 Linker Script */
/* Description : FSBL R5 and A53(32-bit) Linker Script */
/* */
/*******************************************************************/
@ -63,7 +63,7 @@ ENTRY(_vector_table)
SECTIONS
{
.text : {
*(.vectors)
KEEP (*(.vectors))
*(.boot)
*(.text)
*(.text.*)
@ -76,6 +76,7 @@ SECTIONS
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
*(.note.gnu.build-id)
} > psu_ram_0_S_AXI_BASEADDR
.init : {
@ -235,7 +236,7 @@ SECTIONS
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > psu_ram_0_S_AXI_BASEADDR
} > psu_ram_1_S_AXI_BASEADDR
.tdata : {
__tdata_start = .;

View file

@ -94,8 +94,19 @@ XFsbl_Exit:
mcr 15,0,r4,cr1,cr0,0
isb
cmp r1,#0
bne XFsbl_StartApp
cmp r1, #0 /* exit to wfe */
beq XFsbl_Loop
cmp r1, #2 /* x1 is 2 - exit in aarch32 */
beq XFsbl_StartApp
/* x1 is 1 - exit in aarch64 */
mov r2, #3 /* request for warm reset and aarch64 */
dsb
isb
mcr p15, 0, r2, c12, c0, 2 /* write to reset management register */
isb
#else
mov x30, x0 /* move the destination address into x30 register */
@ -120,7 +131,9 @@ XFsbl_Exit:
/* x1 is 2 - exit in aarch32 */
mov x2, #3 /* request for warm reset and aarch32 */
mov x2, #2 /* request for warm reset and aarch32 */
dsb sy
isb
msr RMR_EL3,x2 /* write to reset management register */
isb
#endif

View file

@ -69,6 +69,10 @@
#define APU_CONFIG_0_AA64N32_MASK_CPU2 (0x4U)
#define APU_CONFIG_0_AA64N32_MASK_CPU3 (0x8U)
#define OTHER_CPU_HANDOFF (0x0U)
#define A53_0_64_HANDOFF_TO_A53_0_32 (0x1U)
#define A53_0_32_HANDOFF_TO_A53_0_64 (0x2U)
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
@ -78,8 +82,9 @@
/************************** Function Prototypes ******************************/
static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags);
static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings);
static void XFsbl_CopyIVT(u32 CpuSettings);
static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings,
u32 HandoffType);
static void XFsbl_CopyIVT(u32 CpuSettings, u32 HandoffType);
static int XFsbl_Is32BitCpu(u32 CpuSettings);
/**
@ -572,7 +577,8 @@ void XFsbl_HandoffExit(u64 HandoffAddress, u32 Flags)
*
*
*****************************************************************************/
static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings)
static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings,
u32 HandoffType)
{
u32 HandOffAddressLow=0U;
u32 HandOffAddressHigh=0U;
@ -585,7 +591,7 @@ static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings)
/**
* copy the IVT to 0xffff0000
*/
XFsbl_CopyIVT(CpuSettings);
XFsbl_CopyIVT(CpuSettings, HandoffType);
/**
* Writing u64/u32 will be decided on the handoff Cpu
@ -593,11 +599,22 @@ static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings)
if (XFsbl_Is32BitCpu(CpuSettings) == TRUE)
{
/**
* for R5 cpu, write 32bit handoff address
* for R5 and A53(32-bit) cpus, write 32bit handoff address
* Hence is also applicable for A53_0_64_TO_A53_0_32
*/
XFsbl_Out32(XFSBL_HANDOFF_ADDR_PTR,
(u32 )HandOffAddress);
} else {
} else if (HandoffType == A53_0_32_HANDOFF_TO_A53_0_64) {
/**
* for A53_0_32_TO_A53_0_64 case, write 64 bit handoff address
* to the predfined location
*/
XFsbl_Out32(XFSBL_HANDOFF_ADDR_PTR,
(u32 )(HandOffAddress & 0xFFFFFFFFU));
XFsbl_Out32(XFSBL_HANDOFF_ADDR_PTR+4U,
(u32 )((HandOffAddress>>32) & 0xFFFFFFFFU));
}
else {
/**
* for A53 cpu, write 64bit handoff address
* to the RVBARADDR in APU
@ -642,14 +659,17 @@ static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings)
* This function will copy the Arm predefined code to the Reset IVT address
*
* @param CpuId is used to determine which arm predefined code to be loaded
Supports R5, A53/A53 processors
* by checking if the handoff cpu is of 32 bit
*
* @param HandoffType used to determine which arm A53 predefined code to be
* loaded. Supports handoff to A53(32-bit) and A53(64bit) processors
*
* @return
*
* @note
*
*****************************************************************************/
static void XFsbl_CopyIVT(u32 CpuSettings)
static void XFsbl_CopyIVT(u32 CpuSettings, u32 HandoffType)
{
u32 Index=0U;
const u32 XFsbl_ArmR5PredefinedCode[] =
@ -689,21 +709,89 @@ static void XFsbl_CopyIVT(u32 CpuSettings)
0xE12FFF1EU
};
const u32 XFsbl_ArmA53Cpu32PredefinedCode[] =
{
/**
* 1. Move 0xffffff00 to r0
* 2. load value stored in r0 to lr
* 3. dsb
* 4. isb
* 5. branch to lr
*/
/* mvn r0, #255 */
0xE3E000FFU,
/* ldr lr, [r0] */
0xE590E000U,
/* dsb */
0xF57FF04FU,
/* isb */
0xF57FF06FU,
/* bx lr */
0xE12FFF1EU
};
const u32 XFsbl_ArmA53Cpu64PredefinedCode[] =
{
/**
* 1. Move 0xffffff00 to x0
* 2. load value stored in x0 to x30
* 3. dsb
* 4. isb
* 5. branch to x30
*/
/* mov x0, #0xffffff00 */
0xB2785FE0U,
/* ldr x30, [x0] */
0xF940001EU,
/* dsb sy */
0xD5033F9FU,
/* isb */
0xD5033FDFU,
/* br x30 */
0xD61F03C0U
};
/**
* Load the predefined ARM code to the reset vector address
* For R5 load the R5 code otherwise A53 code
*/
if (XFsbl_Is32BitCpu(CpuSettings) == TRUE)
{
if ((XFsbl_Is32BitCpu(CpuSettings) == TRUE) &&
(HandoffType == OTHER_CPU_HANDOFF)) {
/**
* Load R5 code
*/
for (Index=0U;Index<10U;Index++)
for (Index=0U;
Index < sizeof(XFsbl_ArmR5PredefinedCode)/sizeof(u32); Index++)
{
XFsbl_Out32(XFSBL_IVT_ADDRESS + (Index*4U),
XFsbl_ArmR5PredefinedCode[Index]);
}
}
else if (HandoffType == A53_0_64_HANDOFF_TO_A53_0_32) {
for (Index=0U;
Index < sizeof(XFsbl_ArmA53Cpu32PredefinedCode)/sizeof(u32);
Index++) {
XFsbl_Out32(XFSBL_IVT_ADDRESS + (Index*4U),
XFsbl_ArmA53Cpu32PredefinedCode[Index]);
}
}
else if (HandoffType == A53_0_32_HANDOFF_TO_A53_0_64) {
for (Index=0U;
Index < sizeof(XFsbl_ArmA53Cpu64PredefinedCode)/sizeof(u32);
Index++) {
XFsbl_Out32(XFSBL_IVT_ADDRESS + (Index*4U),
XFsbl_ArmA53Cpu64PredefinedCode[Index]);
}
}
else {
/* for MISRA C compliance */
}
return;
}
@ -849,7 +937,8 @@ u32 XFsbl_Handoff (XFsblPs * FsblInstancePtr, u32 PartitionNum, u32 EarlyHandoff
/**
* Update the handoff address at reset vector address
*/
XFsbl_UpdateResetVector(HandoffAddress, CpuSettings);
XFsbl_UpdateResetVector(HandoffAddress, CpuSettings,
OTHER_CPU_HANDOFF);
XFsbl_Printf(DEBUG_INFO,"CPU 0x%0lx reset release, "
"Exec State 0x%0lx, HandoffAddress: %0lx\n\r",
@ -894,8 +983,30 @@ u32 XFsbl_Handoff (XFsblPs * FsblInstancePtr, u32 PartitionNum, u32 EarlyHandoff
*/
RunningCpuHandoffAddressPresent = TRUE;
RunningCpuHandoffAddress = (u64 )
FsblInstancePtr->HandoffValues[CpuIndex].HandoffAddress;
FsblInstancePtr->HandoffValues[CpuIndex].HandoffAddress;
RunningCpuExecState = ExecState;
/**
* Update reset vector address for
* - FSBL running on A53-0 (64bit), handoff to A53-0 (32 bit)
* - FSBL running on A53-0 (32bit), handoff to A53-0 (64 bit)
*/
if ((FsblInstancePtr->A53ExecState ==
XIH_PH_ATTRB_A53_EXEC_ST_AA64) &&
(ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32)) {
XFsbl_UpdateResetVector(RunningCpuHandoffAddress,
CpuSettings, A53_0_64_HANDOFF_TO_A53_0_32);
}
else if ((FsblInstancePtr->A53ExecState ==
XIH_PH_ATTRB_A53_EXEC_ST_AA32) &&
(ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA64)) {
XFsbl_UpdateResetVector(RunningCpuHandoffAddress,
CpuSettings, A53_0_32_HANDOFF_TO_A53_0_64);
}
else
{
/* for MISRA C compliance */
}
}
}

View file

@ -170,6 +170,7 @@ extern "C" {
#define XIH_PH_ATTRB_A53_EXEC_ST_AA32 (0x0008U)
#define XIH_PH_ATTRB_A53_EXEC_ST_AA64 (0x0000U)
#define XIH_INVALID_EXEC_ST (0xFFFFU)
/**
* Below is the bit mapping of fields in the ATF Handoff parameters
* with that of Partition header. The number of bits shifted is

View file

@ -259,10 +259,23 @@ static u32 XFsbl_ProcessorInit(XFsblPs * FsblInstancePtr)
* Need a check for unsupported Cluster ID
*/
if ((ClusterId & XFSBL_CLUSTER_ID_MASK) == XFSBL_A53_PROCESSOR) {
XFsbl_Printf(DEBUG_GENERAL,"Running on A53-0 Processor \n\r");
XFsbl_Printf(DEBUG_GENERAL,"Running on A53-0 ");
FsblInstancePtr->ProcessorID =
XIH_PH_ATTRB_DEST_CPU_A53_0;
#ifndef __aarch32__
/* Running on A53 64-bit */
XFsbl_Printf(DEBUG_GENERAL,"(64-bit) Processor \n\r");
FsblInstancePtr->A53ExecState = XIH_PH_ATTRB_A53_EXEC_ST_AA64;
#else
/* Running on A53 32-bit */
XFsbl_Printf(DEBUG_GENERAL,"(32-bit) Processor \n\r");
FsblInstancePtr->A53ExecState = XIH_PH_ATTRB_A53_EXEC_ST_AA32;
#endif
} else {
/* A53ExecState is not valid for R5 */
FsblInstancePtr->A53ExecState = XIH_INVALID_EXEC_ST;
RegValue = XFsbl_In32(RPU_RPU_GLBL_CNTL);
if ((RegValue & RPU_RPU_GLBL_CNTL_SLSPLIT_MASK) == 0U) {
XFsbl_Printf(DEBUG_GENERAL,

View file

@ -81,6 +81,7 @@ typedef struct {
u32 Version; /**< FSBL Version */
u32 PresentStage; /**< Stage */
u32 ProcessorID; /**< One of R5-0, R5-LS, A53-0 */
u32 A53ExecState; /**< One of A53 64-bit, A53 32-bit */
u32 BootHdrAttributes; /**< Boot Header attributes */
u32 ImageOffsetAddress; /**< Flash offset address */
XFsblPs_ImageHeader ImageHeader; /** Image header */