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:
parent
754a82e98b
commit
84204047c7
7 changed files with 182 additions and 29 deletions
|
@ -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 ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = .;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue