Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
50f7101a
Commit
50f7101a
authored
Jun 15, 2016
by
danh-arm
Committed by
GitHub
Jun 15, 2016
Browse files
Merge pull request #650 from Xilinx/zynqmp-updates
Zynqmp updates
parents
f9455cea
2ba68959
Changes
19
Hide whitespace changes
Inline
Side-by-side
common/context_mgmt.c
View file @
50f7101a
...
...
@@ -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 entr
y
point 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.
...
...
docs/plat/xilinx-zynqmp.md
View file @
50f7101a
...
...
@@ -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
...
...
plat/xilinx/zynqmp/aarch64/zynqmp_common.c
View file @
50f7101a
...
...
@@ -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
();
...
...
plat/xilinx/zynqmp/bl31_zynqmp_setup.c
View file @
50f7101a
...
...
@@ -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
);
}
...
...
plat/xilinx/zynqmp/include/platform_def.h
View file @
50f7101a
...
...
@@ -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)
...
...
plat/xilinx/zynqmp/plat_psci.c
View file @
50f7101a
...
...
@@ -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
;
}
...
...
plat/xilinx/zynqmp/plat_startup.c
0 → 100644
View file @
50f7101a
/*
* 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
);
}
}
plat/xilinx/zynqmp/plat_topology.c
View file @
50f7101a
...
...
@@ -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
)
...
...
plat/xilinx/zynqmp/platform.mk
View file @
50f7101a
...
...
@@ -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"
)
endif
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))
# 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"
)
ifdef
ZYNQMP_ATF_MEM_PROGBITS_SIZE
$(eval
$(call
add_define,ZYNQMP_ATF_MEM_PROGBITS_SIZE))
endif
endif
# Process flags
$(eval
$(call
add_define,ZYNQMP_ATF_LOCATION_ID))
$(eval
$(call
add_define,ZYNQMP_TSP_RAM_LOCATION_ID))
ifdef
ZYNQMP_BL32_MEM_BASE
$(eval
$(call
add_define,ZYNQMP_BL32_MEM_BASE))
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
\
...
...
plat/xilinx/zynqmp/pm_service/pm_api_sys.c
View file @
50f7101a
...
...
@@ -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 */
...
...
plat/xilinx/zynqmp/pm_service/pm_api_sys.h
View file @
50f7101a
...
...
@@ -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
);
...
...
plat/xilinx/zynqmp/pm_service/pm_client.c
View file @
50f7101a
...
...
@@ -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
);
}
plat/xilinx/zynqmp/pm_service/pm_client.h
View file @
50f7101a
...
...
@@ -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
);
...
...
plat/xilinx/zynqmp/pm_service/pm_defs.h
View file @
50f7101a
...
...
@@ -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
,
};
/**
...
...
plat/xilinx/zynqmp/pm_service/pm_ipi.c
View file @
50f7101a
...
...
@@ -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_I
S
R_PMU_0_MASK << PM_INT_NUM)
#define IPI_PMU_PM_INT_MASK (IPI_APU_I
X
R_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
,
...
...
plat/xilinx/zynqmp/pm_service/pm_svc_main.c
View file @
50f7101a
...
...
@@ -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
],
...
...
plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
View file @
50f7101a
...
...
@@ -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"
/*
...
...
plat/xilinx/zynqmp/zynqmp_def.h
View file @
50f7101a
...
...
@@ -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 0x0
1
000000
#define DEVICE1_SIZE 0x00
8
00000
/* 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
******************************************************************************/
...
...
plat/xilinx/zynqmp/zynqmp_private.h
View file @
50f7101a
...
...
@@ -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__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment