mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
commit
50f7101a49
19 changed files with 438 additions and 145 deletions
|
@ -126,7 +126,7 @@ static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t
|
|||
|
||||
/*
|
||||
* Set up SCTLR_ELx for the target exception level:
|
||||
* EE bit is taken from the entrpoint attributes
|
||||
* EE bit is taken from the entrypoint attributes
|
||||
* M, C and I bits must be zero (as required by PSCI specification)
|
||||
*
|
||||
* The target exception level is based on the spsr mode requested.
|
||||
|
|
|
@ -21,14 +21,17 @@ make ERROR_DEPRECATED=1 RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=zyn
|
|||
```
|
||||
|
||||
# ZynqMP platform specific build options
|
||||
* `ZYNQMP_ATF_LOCATION`: Specifies the location of the bl31 binary. Options:
|
||||
- `tsram` : bl31 will be located in OCM (default)
|
||||
- `tdram` : bl31 will be located in DRAM (address: 0x30000000)
|
||||
* `ZYNQMP_ATF_MEM_BASE`: Specifies the base address of the bl31 binary.
|
||||
* `ZYNQMP_ATF_MEM_SIZE`: Specifies the size of the memory region of the bl31 binary.
|
||||
* `ZYNQMP_BL32_MEM_BASE`: Specifies the base address of the bl32 binary.
|
||||
* `ZYNQMP_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
|
||||
|
||||
* `ZYNQMP_TSP_RAM_LOCATION`: Specifies the location of the bl32 binary and
|
||||
secure payload dispatcher. Options:
|
||||
- `tsram` : bl32/spd will be located in OCM (default)
|
||||
- `tdram` : bl32/spd will be located in DRAM (address: 0x30000000)
|
||||
# FSBL->ATF Parameter Passing
|
||||
The FSBL populates a data structure with image information for the ATF. The ATF
|
||||
uses that data to hand off to the loaded images. The address of the handoff data
|
||||
structure is passed in the ```PMU_GLOBAL.GLOBAL_GEN_STORAGE6``` register. The
|
||||
register is free to be used by other software once the ATF is bringing up
|
||||
further firmware images.
|
||||
|
||||
# Power Domain Tree
|
||||
The following power domain tree represents the power domain model used by the
|
||||
|
|
|
@ -28,12 +28,8 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <cci.h>
|
||||
#include <debug.h>
|
||||
#include <gicv2.h>
|
||||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform.h>
|
||||
#include <xlat_tables.h>
|
||||
#include "../zynqmp_private.h"
|
||||
|
@ -187,11 +183,9 @@ static char *zynqmp_print_silicon_idcode(void)
|
|||
|
||||
tmp = id;
|
||||
tmp &= ZYNQMP_CSU_IDCODE_XILINX_ID_MASK |
|
||||
ZYNQMP_CSU_IDCODE_FAMILY_MASK |
|
||||
ZYNQMP_CSU_IDCODE_REVISION_MASK;
|
||||
ZYNQMP_CSU_IDCODE_FAMILY_MASK;
|
||||
maskid = ZYNQMP_CSU_IDCODE_XILINX_ID << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT |
|
||||
ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT |
|
||||
ZYNQMP_CSU_IDCODE_REVISION << ZYNQMP_CSU_IDCODE_REVISION_SHIFT;
|
||||
ZYNQMP_CSU_IDCODE_FAMILY << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT;
|
||||
if (tmp != maskid) {
|
||||
ERROR("Incorrect XILINX IDCODE 0x%x, maskid 0x%x\n", id, maskid);
|
||||
return "UNKN";
|
||||
|
@ -275,13 +269,13 @@ int zynqmp_is_pmu_up(void)
|
|||
return zynqmp_pmufw_present;
|
||||
}
|
||||
|
||||
/*
|
||||
* A single boot loader stack is expected to work on both the Foundation ZYNQMP
|
||||
* models and the two flavours of the Base ZYNQMP models (AEMv8 & Cortex). The
|
||||
* SYS_ID register provides a mechanism for detecting the differences between
|
||||
* these platforms. This information is stored in a per-BL array to allow the
|
||||
* code to take the correct path.Per BL platform configuration.
|
||||
*/
|
||||
unsigned int zynqmp_get_bootmode(void)
|
||||
{
|
||||
uint32_t r = mmio_read_32(CRL_APB_BOOT_MODE_USER);
|
||||
|
||||
return r & CRL_APB_BOOT_MODE_MASK;
|
||||
}
|
||||
|
||||
void zynqmp_config_setup(void)
|
||||
{
|
||||
zynqmp_discover_pmufw();
|
||||
|
|
|
@ -113,25 +113,25 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
* present.
|
||||
*/
|
||||
|
||||
/* Populate entry point information for BL32 and BL33 */
|
||||
/* Populate common information for BL32 and BL33 */
|
||||
SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
|
||||
SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
|
||||
bl32_image_ep_info.pc = BL32_BASE;
|
||||
bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
|
||||
|
||||
NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
|
||||
|
||||
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
|
||||
|
||||
/*
|
||||
* Tell BL31 where the non-trusted software image
|
||||
* is located and the entry state information
|
||||
*/
|
||||
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
|
||||
bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
|
||||
if (zynqmp_get_bootmode() == ZYNQMP_BOOTMODE_JTAG) {
|
||||
/* use build time defaults in JTAG boot mode */
|
||||
bl32_image_ep_info.pc = BL32_BASE;
|
||||
bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry();
|
||||
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
|
||||
bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
/* use parameters from FSBL */
|
||||
fsbl_atf_handover(&bl32_image_ep_info, &bl33_image_ep_info);
|
||||
}
|
||||
|
||||
NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
|
||||
NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,64 +50,62 @@
|
|||
/*******************************************************************************
|
||||
* BL31 specific defines.
|
||||
******************************************************************************/
|
||||
|
||||
#define ZYNQMP_BL31_SIZE 0x1b000
|
||||
/*
|
||||
* Put BL31 at the top of the Trusted SRAM (just below the shared memory, if
|
||||
* present). BL31_BASE is calculated using the current BL31 debug size plus a
|
||||
* little space for growth.
|
||||
*/
|
||||
#if ZYNQMP_ATF_LOCATION_ID == ZYNQMP_IN_TRUSTED_SRAM
|
||||
# define BL31_BASE (ZYNQMP_TRUSTED_SRAM_LIMIT - \
|
||||
ZYNQMP_BL31_SIZE)
|
||||
# define BL31_PROGBITS_LIMIT (ZYNQMP_TRUSTED_SRAM_LIMIT - 0x6000)
|
||||
# define BL31_LIMIT ZYNQMP_TRUSTED_SRAM_LIMIT
|
||||
#elif ZYNQMP_ATF_LOCATION_ID == ZYNQMP_IN_TRUSTED_DRAM
|
||||
# define BL31_BASE (ZYNQMP_TRUSTED_DRAM_LIMIT - \
|
||||
ZYNQMP_BL31_SIZE)
|
||||
# define BL31_PROGBITS_LIMIT (ZYNQMP_TRUSTED_DRAM_LIMIT - 0x6000)
|
||||
# define BL31_LIMIT (ZYNQMP_TRUSTED_DRAM_BASE + \
|
||||
ZYNQMP_TRUSTED_DRAM_SIZE)
|
||||
#ifndef ZYNQMP_ATF_MEM_BASE
|
||||
# define BL31_BASE 0xfffe5000
|
||||
# define BL31_PROGBITS_LIMIT 0xffffa000
|
||||
# define BL31_LIMIT 0xffffffff
|
||||
#else
|
||||
# error "Unsupported ZYNQMP_ATF_LOCATION_ID value"
|
||||
# define BL31_BASE (ZYNQMP_ATF_MEM_BASE)
|
||||
# define BL31_LIMIT (ZYNQMP_ATF_MEM_BASE + ZYNQMP_ATF_MEM_SIZE - 1)
|
||||
# ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
|
||||
# define BL31_PROGBITS_LIMIT (ZYNQMP_ATF_MEM_BASE + ZYNQMP_ATF_MEM_PROGBITS_SIZE - 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* BL32 specific defines.
|
||||
******************************************************************************/
|
||||
/*
|
||||
* On ZYNQMP, the TSP can execute either from Trusted SRAM or Trusted DRAM.
|
||||
*/
|
||||
#if ZYNQMP_TSP_RAM_LOCATION_ID == ZYNQMP_IN_TRUSTED_SRAM
|
||||
# define TSP_SEC_MEM_BASE ZYNQMP_TRUSTED_SRAM_BASE
|
||||
# define TSP_SEC_MEM_SIZE ZYNQMP_TRUSTED_SRAM_SIZE
|
||||
# define TSP_PROGBITS_LIMIT (ZYNQMP_TRUSTED_SRAM_LIMIT - \
|
||||
ZYNQMP_BL31_SIZE)
|
||||
# define BL32_BASE ZYNQMP_TRUSTED_SRAM_BASE
|
||||
# define BL32_LIMIT (ZYNQMP_TRUSTED_SRAM_LIMIT - \
|
||||
ZYNQMP_BL31_SIZE)
|
||||
#elif ZYNQMP_TSP_RAM_LOCATION_ID == ZYNQMP_IN_TRUSTED_DRAM
|
||||
# define TSP_SEC_MEM_BASE ZYNQMP_TRUSTED_DRAM_BASE
|
||||
# define TSP_SEC_MEM_SIZE (ZYNQMP_TRUSTED_DRAM_LIMIT - \
|
||||
ZYNQMP_BL31_SIZE)
|
||||
# define BL32_BASE ZYNQMP_TRUSTED_DRAM_BASE
|
||||
# define BL32_LIMIT (ZYNQMP_TRUSTED_DRAM_LIMIT - \
|
||||
ZYNQMP_BL31_SIZE)
|
||||
#ifndef ZYNQMP_BL32_MEM_BASE
|
||||
# define BL32_BASE 0x60000000
|
||||
# define BL32_LIMIT 0x7fffffff
|
||||
#else
|
||||
# error "Unsupported ZYNQMP_TSP_RAM_LOCATION_ID value"
|
||||
# define BL32_BASE (ZYNQMP_BL32_MEM_BASE)
|
||||
# define BL32_LIMIT (ZYNQMP_BL32_MEM_BASE + ZYNQMP_BL32_MEM_SIZE - 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ID of the secure physical generic timer interrupt used by the TSP.
|
||||
*/
|
||||
/*******************************************************************************
|
||||
* BL33 specific defines.
|
||||
******************************************************************************/
|
||||
#ifndef PRELOADED_BL33_BASE
|
||||
# define PLAT_ARM_NS_IMAGE_OFFSET 0x8000000
|
||||
#else
|
||||
# define PLAT_ARM_NS_IMAGE_OFFSET PRELOADED_BL33_BASE
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* TSP specific defines.
|
||||
******************************************************************************/
|
||||
#define TSP_SEC_MEM_BASE BL32_BASE
|
||||
#define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE + 1)
|
||||
|
||||
/* ID of the secure physical generic timer interrupt used by the TSP */
|
||||
#define TSP_IRQ_SEC_PHY_TIMER ARM_IRQ_SEC_PHY_TIMER
|
||||
|
||||
/*******************************************************************************
|
||||
* Platform specific page table and MMU setup constants
|
||||
******************************************************************************/
|
||||
#define ADDR_SPACE_SIZE (1ull << 32)
|
||||
#define MAX_XLAT_TABLES 5
|
||||
#define MAX_MMAP_REGIONS 7
|
||||
#define MAX_MMAP_REGIONS 6
|
||||
#if IMAGE_BL32
|
||||
# define MAX_XLAT_TABLES 5
|
||||
#else
|
||||
# define MAX_XLAT_TABLES 4
|
||||
#endif
|
||||
|
||||
#define CACHE_WRITEBACK_SHIFT 6
|
||||
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
|
||||
|
|
|
@ -104,7 +104,7 @@ static int zynqmp_pwr_domain_on(u_register_t mpidr)
|
|||
proc = pm_get_proc(cpu_id);
|
||||
|
||||
/* Send request to PMU to wake up selected APU CPU core */
|
||||
pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_NO);
|
||||
pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
|
288
plat/xilinx/zynqmp/plat_startup.c
Normal file
288
plat/xilinx/zynqmp/plat_startup.c
Normal file
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of ARM nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <mmio.h>
|
||||
#include "zynqmp_def.h"
|
||||
|
||||
/*
|
||||
* ATFHandoffParams
|
||||
* Parameter bitfield encoding
|
||||
* -----------------------------------------------------------------------------
|
||||
* Exec State 0 0 -> Aarch64, 1-> Aarch32
|
||||
* endianness 1 0 -> LE, 1 -> BE
|
||||
* secure (TZ) 2 0 -> Non secure, 1 -> secure
|
||||
* EL 3:4 00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3
|
||||
* CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3
|
||||
*/
|
||||
|
||||
#define FSBL_FLAGS_ESTATE_SHIFT 0
|
||||
#define FSBL_FLAGS_ESTATE_MASK (1 << FSBL_FLAGS_ESTATE_SHIFT)
|
||||
#define FSBL_FLAGS_ESTATE_A64 0
|
||||
#define FSBL_FLAGS_ESTATE_A32 1
|
||||
|
||||
#define FSBL_FLAGS_ENDIAN_SHIFT 1
|
||||
#define FSBL_FLAGS_ENDIAN_MASK (1 << FSBL_FLAGS_ENDIAN_SHIFT)
|
||||
#define FSBL_FLAGS_ENDIAN_LE 0
|
||||
#define FSBL_FLAGS_ENDIAN_BE 1
|
||||
|
||||
#define FSBL_FLAGS_TZ_SHIFT 2
|
||||
#define FSBL_FLAGS_TZ_MASK (1 << FSBL_FLAGS_TZ_SHIFT)
|
||||
#define FSBL_FLAGS_NON_SECURE 0
|
||||
#define FSBL_FLAGS_SECURE 1
|
||||
|
||||
#define FSBL_FLAGS_EL_SHIFT 3
|
||||
#define FSBL_FLAGS_EL_MASK (3 << FSBL_FLAGS_EL_SHIFT)
|
||||
#define FSBL_FLAGS_EL0 0
|
||||
#define FSBL_FLAGS_EL1 1
|
||||
#define FSBL_FLAGS_EL2 2
|
||||
#define FSBL_FLAGS_EL3 3
|
||||
|
||||
#define FSBL_FLAGS_CPU_SHIFT 5
|
||||
#define FSBL_FLAGS_CPU_MASK (3 << FSBL_FLAGS_CPU_SHIFT)
|
||||
#define FSBL_FLAGS_A53_0 0
|
||||
#define FSBL_FLAGS_A53_1 1
|
||||
#define FSBL_FLAGS_A53_2 2
|
||||
#define FSBL_FLAGS_A53_3 3
|
||||
|
||||
#define FSBL_MAX_PARTITIONS 8
|
||||
|
||||
/* Structure corresponding to each partition entry */
|
||||
struct xfsbl_partition {
|
||||
uint64_t entry_point;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */
|
||||
struct xfsbl_atf_handoff_params {
|
||||
uint8_t magic[4];
|
||||
uint32_t num_entries;
|
||||
struct xfsbl_partition partition[FSBL_MAX_PARTITIONS];
|
||||
};
|
||||
|
||||
/**
|
||||
* @partition: Pointer to partition struct
|
||||
*
|
||||
* Get the target CPU for @partition.
|
||||
*
|
||||
* Return: FSBL_FLAGS_A53_0, FSBL_FLAGS_A53_1, FSBL_FLAGS_A53_2 or FSBL_FLAGS_A53_3
|
||||
*/
|
||||
static int get_fsbl_cpu(const struct xfsbl_partition *partition)
|
||||
{
|
||||
uint64_t flags = partition->flags & FSBL_FLAGS_CPU_MASK;
|
||||
|
||||
return flags >> FSBL_FLAGS_CPU_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @partition: Pointer to partition struct
|
||||
*
|
||||
* Get the target exception level for @partition.
|
||||
*
|
||||
* Return: FSBL_FLAGS_EL0, FSBL_FLAGS_EL1, FSBL_FLAGS_EL2 or FSBL_FLAGS_EL3
|
||||
*/
|
||||
static int get_fsbl_el(const struct xfsbl_partition *partition)
|
||||
{
|
||||
uint64_t flags = partition->flags & FSBL_FLAGS_EL_MASK;
|
||||
|
||||
return flags >> FSBL_FLAGS_EL_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @partition: Pointer to partition struct
|
||||
*
|
||||
* Get the target security state for @partition.
|
||||
*
|
||||
* Return: FSBL_FLAGS_NON_SECURE or FSBL_FLAGS_SECURE
|
||||
*/
|
||||
static int get_fsbl_ss(const struct xfsbl_partition *partition)
|
||||
{
|
||||
uint64_t flags = partition->flags & FSBL_FLAGS_TZ_MASK;
|
||||
|
||||
return flags >> FSBL_FLAGS_TZ_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @partition: Pointer to partition struct
|
||||
*
|
||||
* Get the target endianness for @partition.
|
||||
*
|
||||
* Return: SPSR_E_LITTLE or SPSR_E_BIG
|
||||
*/
|
||||
static int get_fsbl_endian(const struct xfsbl_partition *partition)
|
||||
{
|
||||
uint64_t flags = partition->flags & FSBL_FLAGS_ENDIAN_MASK;
|
||||
|
||||
flags >>= FSBL_FLAGS_ENDIAN_SHIFT;
|
||||
|
||||
if (flags == FSBL_FLAGS_ENDIAN_BE)
|
||||
return SPSR_E_BIG;
|
||||
else
|
||||
return SPSR_E_LITTLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @partition: Pointer to partition struct
|
||||
*
|
||||
* Get the target execution state for @partition.
|
||||
*
|
||||
* Return: FSBL_FLAGS_ESTATE_A32 or FSBL_FLAGS_ESTATE_A64
|
||||
*/
|
||||
static int get_fsbl_estate(const struct xfsbl_partition *partition)
|
||||
{
|
||||
uint64_t flags = partition->flags & FSBL_FLAGS_ESTATE_MASK;
|
||||
|
||||
return flags >> FSBL_FLAGS_ESTATE_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the bl32 and bl33 image info structures
|
||||
* @bl32: BL32 image info structure
|
||||
* @bl33: BL33 image info structure
|
||||
*
|
||||
* Process the handoff paramters from the FSBL and populate the BL32 and BL33
|
||||
* image info structures accordingly.
|
||||
*/
|
||||
void fsbl_atf_handover(entry_point_info_t *bl32, entry_point_info_t *bl33)
|
||||
{
|
||||
uint64_t atf_handoff_addr;
|
||||
const struct xfsbl_atf_handoff_params *ATFHandoffParams;
|
||||
|
||||
atf_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6);
|
||||
assert((atf_handoff_addr < BL31_BASE) ||
|
||||
(atf_handoff_addr > (uint64_t)&__BL31_END__));
|
||||
if (!atf_handoff_addr) {
|
||||
ERROR("BL31: No ATF handoff structure passed\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
ATFHandoffParams = (struct xfsbl_atf_handoff_params *)atf_handoff_addr;
|
||||
if ((ATFHandoffParams->magic[0] != 'X') ||
|
||||
(ATFHandoffParams->magic[1] != 'L') ||
|
||||
(ATFHandoffParams->magic[2] != 'N') ||
|
||||
(ATFHandoffParams->magic[3] != 'X')) {
|
||||
ERROR("BL31: invalid ATF handoff structure at %lx\n",
|
||||
atf_handoff_addr);
|
||||
panic();
|
||||
}
|
||||
|
||||
VERBOSE("BL31: ATF handoff params at:0x%lx, entries:%u\n",
|
||||
atf_handoff_addr, ATFHandoffParams->num_entries);
|
||||
if (ATFHandoffParams->num_entries > FSBL_MAX_PARTITIONS) {
|
||||
ERROR("BL31: ATF handoff params: too many partitions (%u/%u)\n",
|
||||
ATFHandoffParams->num_entries, FSBL_MAX_PARTITIONS);
|
||||
panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* we loop over all passed entries but only populate two image structs
|
||||
* (bl32, bl33). I.e. the last applicable images in the handoff
|
||||
* structure will be used for the hand off
|
||||
*/
|
||||
for (size_t i = 0; i < ATFHandoffParams->num_entries; i++) {
|
||||
entry_point_info_t *image;
|
||||
int target_estate, target_secure;
|
||||
int target_cpu, target_endianness, target_el;
|
||||
|
||||
VERBOSE("BL31: %zd: entry:0x%lx, flags:0x%lx\n", i,
|
||||
ATFHandoffParams->partition[i].entry_point,
|
||||
ATFHandoffParams->partition[i].flags);
|
||||
|
||||
target_cpu = get_fsbl_cpu(&ATFHandoffParams->partition[i]);
|
||||
if (target_cpu != FSBL_FLAGS_A53_0) {
|
||||
WARN("BL31: invalid target CPU (%i)\n", target_cpu);
|
||||
continue;
|
||||
}
|
||||
|
||||
target_el = get_fsbl_el(&ATFHandoffParams->partition[i]);
|
||||
if ((target_el == FSBL_FLAGS_EL3) ||
|
||||
(target_el == FSBL_FLAGS_EL0)) {
|
||||
WARN("BL31: invalid exception level (%i)\n", target_el);
|
||||
continue;
|
||||
}
|
||||
|
||||
target_secure = get_fsbl_ss(&ATFHandoffParams->partition[i]);
|
||||
if (target_secure == FSBL_FLAGS_SECURE &&
|
||||
target_el == FSBL_FLAGS_EL2) {
|
||||
WARN("BL31: invalid security state (%i) for exception level (%i)\n",
|
||||
target_secure, target_el);
|
||||
continue;
|
||||
}
|
||||
|
||||
target_estate = get_fsbl_estate(&ATFHandoffParams->partition[i]);
|
||||
target_endianness = get_fsbl_endian(&ATFHandoffParams->partition[i]);
|
||||
|
||||
if (target_secure == FSBL_FLAGS_SECURE) {
|
||||
image = bl32;
|
||||
|
||||
if (target_estate == FSBL_FLAGS_ESTATE_A32)
|
||||
bl32->spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
|
||||
target_endianness,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
else
|
||||
bl32->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
image = bl33;
|
||||
|
||||
if (target_estate == FSBL_FLAGS_ESTATE_A32) {
|
||||
if (target_el == FSBL_FLAGS_EL2)
|
||||
target_el = MODE32_hyp;
|
||||
else
|
||||
target_el = MODE32_sys;
|
||||
|
||||
bl33->spsr = SPSR_MODE32(target_el, SPSR_T_ARM,
|
||||
target_endianness,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
if (target_el == FSBL_FLAGS_EL2)
|
||||
target_el = MODE_EL2;
|
||||
else
|
||||
target_el = MODE_EL1;
|
||||
|
||||
bl33->spsr = SPSR_64(target_el, MODE_SP_ELX,
|
||||
DISABLE_ALL_EXCEPTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
VERBOSE("Setting up %s entry point to:%lx, el:%x\n",
|
||||
target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33",
|
||||
ATFHandoffParams->partition[i].entry_point,
|
||||
target_el);
|
||||
image->pc = ATFHandoffParams->partition[i].entry_point;
|
||||
|
||||
if (target_endianness == SPSR_E_BIG)
|
||||
EP_SET_EE(image->h.attr, EP_EE_BIG);
|
||||
else
|
||||
EP_SET_EE(image->h.attr, EP_EE_LITTLE);
|
||||
}
|
||||
}
|
|
@ -28,9 +28,6 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
#include <psci.h>
|
||||
|
||||
static const unsigned char plat_power_domain_tree_desc[] = {1, 4};
|
||||
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
|
|
|
@ -31,29 +31,27 @@ PROGRAMMABLE_RESET_ADDRESS := 1
|
|||
PSCI_EXTENDED_STATE_ID := 1
|
||||
A53_DISABLE_NON_TEMPORAL_HINT := 0
|
||||
|
||||
ZYNQMP_ATF_LOCATION ?= tsram
|
||||
ifeq (${ZYNQMP_ATF_LOCATION}, tsram)
|
||||
ZYNQMP_ATF_LOCATION_ID := ZYNQMP_IN_TRUSTED_SRAM
|
||||
else ifeq (${ZYNQMP_ATF_LOCATION}, tdram)
|
||||
ZYNQMP_ATF_LOCATION_ID := ZYNQMP_IN_TRUSTED_DRAM
|
||||
else
|
||||
$(error "Unsupported ZYNQMP_ATF_LOCATION value")
|
||||
ifdef ZYNQMP_ATF_MEM_BASE
|
||||
$(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
|
||||
|
||||
ifndef ZYNQMP_ATF_MEM_SIZE
|
||||
$(error "ZYNQMP_ATF_BASE defined without ZYNQMP_ATF_SIZE")
|
||||
endif
|
||||
$(eval $(call add_define,ZYNQMP_ATF_MEM_SIZE))
|
||||
|
||||
ifdef ZYNQMP_ATF_MEM_PROGBITS_SIZE
|
||||
$(eval $(call add_define,ZYNQMP_ATF_MEM_PROGBITS_SIZE))
|
||||
endif
|
||||
endif
|
||||
|
||||
# On ZYNQMP, the TSP can execute either from Trusted SRAM or Trusted DRAM.
|
||||
# Trusted SRAM is the default.
|
||||
ZYNQMP_TSP_RAM_LOCATION ?= tsram
|
||||
ifeq (${ZYNQMP_TSP_RAM_LOCATION}, tsram)
|
||||
ZYNQMP_TSP_RAM_LOCATION_ID := ZYNQMP_IN_TRUSTED_SRAM
|
||||
else ifeq (${ZYNQMP_TSP_RAM_LOCATION}, tdram)
|
||||
ZYNQMP_TSP_RAM_LOCATION_ID := ZYNQMP_IN_TRUSTED_DRAM
|
||||
else
|
||||
$(error "Unsupported ZYNQMP_TSP_RAM_LOCATION value")
|
||||
endif
|
||||
ifdef ZYNQMP_BL32_MEM_BASE
|
||||
$(eval $(call add_define,ZYNQMP_BL32_MEM_BASE))
|
||||
|
||||
# Process flags
|
||||
$(eval $(call add_define,ZYNQMP_ATF_LOCATION_ID))
|
||||
$(eval $(call add_define,ZYNQMP_TSP_RAM_LOCATION_ID))
|
||||
ifndef ZYNQMP_BL32_MEM_SIZE
|
||||
$(error "ZYNQMP_BL32_BASE defined without ZYNQMP_BL32_SIZE")
|
||||
endif
|
||||
$(eval $(call add_define,ZYNQMP_BL32_MEM_SIZE))
|
||||
endif
|
||||
|
||||
PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
|
||||
-Iinclude/plat/arm/common/aarch64/ \
|
||||
|
@ -84,6 +82,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
|
|||
plat/xilinx/zynqmp/bl31_zynqmp_setup.c \
|
||||
plat/xilinx/zynqmp/plat_psci.c \
|
||||
plat/xilinx/zynqmp/plat_zynqmp.c \
|
||||
plat/xilinx/zynqmp/plat_startup.c \
|
||||
plat/xilinx/zynqmp/plat_topology.c \
|
||||
plat/xilinx/zynqmp/sip_svc_setup.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_svc_main.c \
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <platform.h>
|
||||
#include "pm_client.h"
|
||||
#include "pm_ipi.h"
|
||||
#include "pm_common.h"
|
||||
#include "pm_api_sys.h"
|
||||
|
||||
|
@ -390,21 +391,34 @@ enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
|
|||
unsigned int wake,
|
||||
unsigned int enable)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
PM_PACK_PAYLOAD5(payload, PM_REGISTER_NOTIFIER,
|
||||
nid, event, wake, enable);
|
||||
|
||||
return pm_ipi_send(primary_proc, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_get_op_characteristic() - PM call to get a particular operating
|
||||
* characteristic of a node
|
||||
* @nid Node ID
|
||||
* @type Operating characterstic type to be returned
|
||||
* pm_get_op_characteristic() - PM call to request operating characteristics
|
||||
* of a node
|
||||
* @nid Node id of the slave
|
||||
* @type Type of the operating characteristic
|
||||
* (power, temperature and latency)
|
||||
* @result Returns the operating characteristic for the requested node,
|
||||
* specified by the type
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
|
||||
enum pm_opchar_type type)
|
||||
enum pm_opchar_type type,
|
||||
uint32_t *result)
|
||||
{
|
||||
return PM_RET_ERROR_NOTSUPPORTED;
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PM_PACK_PAYLOAD3(payload, PM_GET_OP_CHARACTERISTIC, nid, type);
|
||||
return pm_ipi_send_sync(primary_proc, payload, result);
|
||||
}
|
||||
|
||||
/* Direct-Control API functions */
|
||||
|
|
|
@ -91,7 +91,8 @@ enum pm_ret_status pm_register_notifier(enum pm_node_id nid,
|
|||
unsigned int wake,
|
||||
unsigned int enable);
|
||||
enum pm_ret_status pm_get_op_characteristic(enum pm_node_id nid,
|
||||
enum pm_opchar_type type);
|
||||
enum pm_opchar_type type,
|
||||
uint32_t *result);
|
||||
enum pm_ret_status pm_acknowledge_cb(enum pm_node_id nid,
|
||||
enum pm_ret_status status,
|
||||
unsigned int oppoint);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
* for getting information about and changing state of the APU.
|
||||
*/
|
||||
|
||||
#include <bakery_lock.h>
|
||||
#include <gicv2.h>
|
||||
#include <bl_common.h>
|
||||
#include <mmio.h>
|
||||
|
@ -47,6 +48,7 @@
|
|||
#define OCM_BANK_3 (OCM_BANK_2 + 0x10000)
|
||||
|
||||
#define UNDEFINED_CPUID (~0)
|
||||
DEFINE_BAKERY_LOCK(pm_client_secure_lock);
|
||||
|
||||
/* Declaration of linker defined symbol */
|
||||
extern unsigned long __BL31_END__;
|
||||
|
@ -162,8 +164,12 @@ const struct pm_proc *primary_proc = &pm_procs_all[0];
|
|||
*/
|
||||
void pm_client_suspend(const struct pm_proc *proc)
|
||||
{
|
||||
bakery_lock_get(&pm_client_secure_lock);
|
||||
|
||||
/* Set powerdown request */
|
||||
mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) | proc->pwrdn_mask);
|
||||
|
||||
bakery_lock_release(&pm_client_secure_lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -177,9 +183,14 @@ void pm_client_abort_suspend(void)
|
|||
{
|
||||
/* Enable interrupts at processor level (for current cpu) */
|
||||
gicv2_cpuif_enable();
|
||||
|
||||
bakery_lock_get(&pm_client_secure_lock);
|
||||
|
||||
/* Clear powerdown request */
|
||||
mmio_write_32(APU_PWRCTL,
|
||||
mmio_read_32(APU_PWRCTL) & ~primary_proc->pwrdn_mask);
|
||||
|
||||
bakery_lock_release(&pm_client_secure_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,8 +206,12 @@ void pm_client_wakeup(const struct pm_proc *proc)
|
|||
if (cpuid == UNDEFINED_CPUID)
|
||||
return;
|
||||
|
||||
bakery_lock_get(&pm_client_secure_lock);
|
||||
|
||||
/* clear powerdown bit for affected cpu */
|
||||
uint32_t val = mmio_read_32(APU_PWRCTL);
|
||||
val &= ~(proc->pwrdn_mask);
|
||||
mmio_write_32(APU_PWRCTL, val);
|
||||
|
||||
bakery_lock_release(&pm_client_secure_lock);
|
||||
}
|
||||
|
|
|
@ -40,11 +40,6 @@
|
|||
#include "pm_common.h"
|
||||
|
||||
/* Functions to be implemented by each PU */
|
||||
enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
|
||||
uint32_t payload[PAYLOAD_ARG_CNT]);
|
||||
enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
|
||||
uint32_t payload[PAYLOAD_ARG_CNT],
|
||||
uint32_t *val);
|
||||
void pm_client_suspend(const struct pm_proc *proc);
|
||||
void pm_client_abort_suspend(void);
|
||||
void pm_client_wakeup(const struct pm_proc *proc);
|
||||
|
|
|
@ -142,6 +142,7 @@ enum pm_node_id {
|
|||
NODE_RPLL,
|
||||
NODE_IOPLL,
|
||||
NODE_DDR,
|
||||
NODE_IPI_APU,
|
||||
};
|
||||
|
||||
enum pm_request_ack {
|
||||
|
@ -171,8 +172,8 @@ enum pm_ram_state {
|
|||
|
||||
enum pm_opchar_type {
|
||||
PM_OPCHAR_TYPE_POWER = 1,
|
||||
PM_OPCHAR_TYPE_ENERGY,
|
||||
PM_OPCHAR_TYPE_TEMP,
|
||||
PM_OPCHAR_TYPE_LATENCY,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -66,8 +66,7 @@
|
|||
#define IPI_APU_ISR (IPI_BASEADDR + 0X00000010)
|
||||
#define IPI_APU_IER (IPI_BASEADDR + 0X00000018)
|
||||
#define IPI_APU_IDR (IPI_BASEADDR + 0X0000001C)
|
||||
#define IPI_APU_ISR_PMU_0_MASK 0X00010000
|
||||
#define IPI_APU_IER_PMU_0_MASK 0X00010000
|
||||
#define IPI_APU_IXR_PMU_0_MASK (1 << 16)
|
||||
|
||||
#define IPI_TRIG_OFFSET 0
|
||||
#define IPI_OBS_OFFSET 4
|
||||
|
@ -75,14 +74,14 @@
|
|||
/* Power Management IPI interrupt number */
|
||||
#define PM_INT_NUM 0
|
||||
#define IPI_PMU_PM_INT_BASE (IPI_PMU_0_TRIG + (PM_INT_NUM * 0x1000))
|
||||
#define IPI_PMU_PM_INT_MASK (IPI_APU_ISR_PMU_0_MASK << PM_INT_NUM)
|
||||
#define IPI_PMU_PM_INT_MASK (IPI_APU_IXR_PMU_0_MASK << PM_INT_NUM)
|
||||
#if (PM_INT_NUM < 0 || PM_INT_NUM > 3)
|
||||
#error PM_INT_NUM value out of range
|
||||
#endif
|
||||
|
||||
#define IPI_APU_MASK 1U
|
||||
|
||||
static bakery_lock_t pm_secure_lock;
|
||||
DEFINE_BAKERY_LOCK(pm_secure_lock);
|
||||
|
||||
const struct pm_ipi apu_ipi = {
|
||||
.mask = IPI_APU_MASK,
|
||||
|
|
|
@ -191,8 +191,12 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
|||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_GET_OP_CHARACTERISTIC:
|
||||
ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result);
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32));
|
||||
}
|
||||
|
||||
case PM_REGISTER_NOTIFIER:
|
||||
ret = pm_register_notifier(pm_arg[0], pm_arg[1], pm_arg[2],
|
||||
|
|
|
@ -32,9 +32,7 @@
|
|||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <platform_tsp.h>
|
||||
#include <xlat_tables.h>
|
||||
#include <plat_arm.h>
|
||||
#include "../zynqmp_def.h"
|
||||
#include "../zynqmp_private.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -43,24 +43,11 @@
|
|||
/*******************************************************************************
|
||||
* ZYNQMP memory map related constants
|
||||
******************************************************************************/
|
||||
|
||||
#define ZYNQMP_TRUSTED_SRAM_BASE 0xFFFC0000
|
||||
#define ZYNQMP_TRUSTED_SRAM_SIZE 0x00040000
|
||||
#define ZYNQMP_TRUSTED_SRAM_LIMIT (ZYNQMP_TRUSTED_SRAM_BASE + \
|
||||
ZYNQMP_TRUSTED_SRAM_SIZE)
|
||||
|
||||
|
||||
/* Location of trusted dram on the base zynqmp */
|
||||
#define ZYNQMP_TRUSTED_DRAM_BASE 0x30000000 /* Can't overlap TZROM area */
|
||||
#define ZYNQMP_TRUSTED_DRAM_SIZE 0x10000000
|
||||
#define ZYNQMP_TRUSTED_DRAM_LIMIT (ZYNQMP_TRUSTED_DRAM_BASE + \
|
||||
ZYNQMP_TRUSTED_DRAM_SIZE)
|
||||
|
||||
/* Aggregate of all devices in the first GB */
|
||||
#define DEVICE0_BASE 0xFF000000
|
||||
#define DEVICE0_SIZE 0x00E00000
|
||||
#define DEVICE1_BASE 0xF9000000
|
||||
#define DEVICE1_SIZE 0x01000000
|
||||
#define DEVICE1_SIZE 0x00800000
|
||||
|
||||
/* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
|
||||
#define CRF_APB_BASE 0xFD1A0000
|
||||
|
@ -76,6 +63,7 @@
|
|||
#define CRL_APB_BASE 0xFF5E0000
|
||||
#define CRL_APB_RPLL_CTRL (CRL_APB_BASE + 0x30)
|
||||
#define CRL_APB_TIMESTAMP_REF_CTRL (CRL_APB_BASE + 0x128)
|
||||
#define CRL_APB_BOOT_MODE_USER (CRL_APB_BASE + 0x200)
|
||||
#define CRL_APB_RESET_CTRL (CRL_APB_BASE + 0x218)
|
||||
|
||||
#define CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT (1 << 24)
|
||||
|
@ -84,6 +72,9 @@
|
|||
|
||||
#define CRL_APB_RESET_CTRL_SOFT_RESET (1 << 4)
|
||||
|
||||
#define CRL_APB_BOOT_MODE_MASK (0xf << 0)
|
||||
#define ZYNQMP_BOOTMODE_JTAG 0
|
||||
|
||||
/* system counter registers and bitfields */
|
||||
#define IOU_SCNTRS_BASE 0xFF260000
|
||||
#define IOU_SCNTRS_CONTROL (IOU_SCNTRS_BASE + 0)
|
||||
|
@ -107,6 +98,7 @@
|
|||
/* PMU registers and bitfields */
|
||||
#define PMU_GLOBAL_BASE 0xFFD80000
|
||||
#define PMU_GLOBAL_CNTRL (PMU_GLOBAL_BASE + 0)
|
||||
#define PMU_GLOBAL_GEN_STORAGE6 (PMU_GLOBAL_BASE + 0x48)
|
||||
#define PMU_GLOBAL_REQ_PWRUP_STATUS (PMU_GLOBAL_BASE + 0x110)
|
||||
#define PMU_GLOBAL_REQ_PWRUP_EN (PMU_GLOBAL_BASE + 0x118)
|
||||
#define PMU_GLOBAL_REQ_PWRUP_DIS (PMU_GLOBAL_BASE + 0x11c)
|
||||
|
@ -114,16 +106,6 @@
|
|||
|
||||
#define PMU_GLOBAL_CNTRL_FW_IS_PRESENT (1 << 4)
|
||||
|
||||
#define DRAM1_BASE 0x00000000ull
|
||||
#define DRAM1_SIZE 0x10000000ull
|
||||
#define DRAM1_END (DRAM1_BASE + DRAM1_SIZE - 1)
|
||||
|
||||
#define DRAM_BASE DRAM1_BASE
|
||||
#define DRAM_SIZE DRAM1_SIZE
|
||||
|
||||
/* Load address of BL33 in the ZYNQMP port */
|
||||
#define PLAT_ARM_NS_IMAGE_OFFSET (DRAM1_BASE + 0x8000000) /* DRAM + 128MB */
|
||||
|
||||
/*******************************************************************************
|
||||
* CCI-400 related constants
|
||||
******************************************************************************/
|
||||
|
|
|
@ -38,5 +38,10 @@ void zynqmp_config_setup(void);
|
|||
/* ZynqMP specific functions */
|
||||
unsigned int zynqmp_get_uart_clk(void);
|
||||
int zynqmp_is_pmu_up(void);
|
||||
unsigned int zynqmp_get_bootmode(void);
|
||||
|
||||
/* For FSBL handover */
|
||||
void fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
|
||||
entry_point_info_t *bl33_image_ep_info);
|
||||
|
||||
#endif /* __ZYNQMP_PRIVATE_H__ */
|
||||
|
|
Loading…
Add table
Reference in a new issue