Merge pull request #1605 from sivadur/integration
Add support new Xilinx Versal ACAP platform
This commit is contained in:
commit
e07666de14
|
@ -0,0 +1,33 @@
|
|||
Trusted Firmware-A for Xilinx Versal
|
||||
================================
|
||||
|
||||
Trusted Firmware-A implements the EL3 firmware layer for Xilinx Versal.
|
||||
The platform only uses the runtime part of TF-A as Xilinx Versal already has a
|
||||
BootROM (BL1) and PMC FW (BL2).
|
||||
|
||||
BL31 is TF-A.
|
||||
BL32 is an optional Secure Payload.
|
||||
BL33 is the non-secure world software (U-Boot, Linux etc).
|
||||
|
||||
To build:
|
||||
```bash
|
||||
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31
|
||||
```
|
||||
|
||||
To build ATF for different platform (for now its just versal virtual "versal_virt")
|
||||
```bash
|
||||
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31
|
||||
```
|
||||
|
||||
# Xilinx Versal platform specific build options
|
||||
* `VERSAL_ATF_MEM_BASE`: Specifies the base address of the bl31 binary.
|
||||
* `VERSAL_ATF_MEM_SIZE`: Specifies the size of the memory region of the bl31 binary.
|
||||
* `VERSAL_BL32_MEM_BASE`: Specifies the base address of the bl32 binary.
|
||||
* `VERSAL_BL32_MEM_SIZE`: Specifies the size of the memory region of the bl32 binary.
|
||||
|
||||
* `VERSAL_CONSOLE`: Select the console driver. Options:
|
||||
- `pl011`, `pl011_0`: ARM pl011 UART 0
|
||||
- `pl011_1` : ARM pl011 UART 1
|
||||
|
||||
* `VERSAL_PLATFORM`: Select the platform. Options:
|
||||
- `versal_virt` : Versal Virtual platform
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <generic_delay_timer.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <xlat_tables.h>
|
||||
#include "../versal_def.h"
|
||||
#include "../versal_private.h"
|
||||
|
||||
/*
|
||||
* Table of regions to map using the MMU.
|
||||
* This doesn't include TZRAM as the 'mem_layout' argument passed to
|
||||
* configure_mmu_elx() will give the available subset of that,
|
||||
*/
|
||||
const mmap_region_t plat_versal_mmap[] = {
|
||||
MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const mmap_region_t *plat_versal_get_mmap(void)
|
||||
{
|
||||
return plat_versal_mmap;
|
||||
}
|
||||
|
||||
static void versal_print_platform_name(void)
|
||||
{
|
||||
NOTICE("ATF running on Xilinx %s\n", PLATFORM_NAME);
|
||||
}
|
||||
|
||||
void versal_config_setup(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
versal_print_platform_name();
|
||||
|
||||
mmio_write_32(VERSAL_CRL_IOU_SWITCH_CTRL,
|
||||
VERSAL_IOU_SWITCH_CTRL_CLKACT_BIT |
|
||||
(0x20 << VERSAL_IOU_SWITCH_CTRL_DIVISOR0_SHIFT));
|
||||
|
||||
/* Global timer init - Program time stamp reference clk */
|
||||
val = mmio_read_32(VERSAL_CRL_TIMESTAMP_REF_CTRL);
|
||||
val |= VERSAL_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT;
|
||||
mmio_write_32(VERSAL_CRL_TIMESTAMP_REF_CTRL, val);
|
||||
|
||||
/* Clear reset of timestamp reg */
|
||||
mmio_write_32(VERSAL_CRL_RST_TIMESTAMP_OFFSET, 0x0);
|
||||
|
||||
/* Program freq register in System counter and enable system counter. */
|
||||
mmio_write_32(VERSAL_IOU_SCNTRS_BASE_FREQ, VERSAL_CPU_CLOCK);
|
||||
mmio_write_32(VERSAL_IOU_SCNTRS_COUNTER_CONTROL_REG,
|
||||
VERSAL_IOU_SCNTRS_CONTROL_EN);
|
||||
|
||||
generic_delay_timer_init();
|
||||
}
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
{
|
||||
return VERSAL_CPU_CLOCK;
|
||||
}
|
||||
|
||||
uintptr_t plat_get_ns_image_entrypoint(void)
|
||||
{
|
||||
#ifdef PRELOADED_BL33_BASE
|
||||
return PRELOADED_BL33_BASE;
|
||||
#else
|
||||
return PLAT_VERSAL_NS_IMAGE_OFFSET;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arch.h>
|
||||
#include <asm_macros.S>
|
||||
#include <gicv3.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
.globl plat_secondary_cold_boot_setup
|
||||
.globl plat_is_my_cpu_primary
|
||||
.globl versal_calc_core_pos
|
||||
.globl platform_mem_init
|
||||
.globl plat_my_core_pos
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* void plat_secondary_cold_boot_setup (void);
|
||||
*
|
||||
* This function performs any platform specific actions
|
||||
* needed for a secondary cpu after a cold reset e.g
|
||||
* mark the cpu's presence, mechanism to place it in a
|
||||
* holding pen etc.
|
||||
* TODO: Should we read the PSYS register to make sure
|
||||
* that the request has gone through.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_secondary_cold_boot_setup
|
||||
mrs x0, mpidr_el1
|
||||
|
||||
/*
|
||||
* There is no sane reason to come out of this wfi. This
|
||||
* cpu will be powered on and reset by the cpu_on pm api
|
||||
*/
|
||||
dsb sy
|
||||
bl plat_panic_handler
|
||||
endfunc plat_secondary_cold_boot_setup
|
||||
|
||||
func plat_is_my_cpu_primary
|
||||
mov x9, x30
|
||||
bl plat_my_core_pos
|
||||
cmp x0, #VERSAL_PRIMARY_CPU
|
||||
cset x0, eq
|
||||
ret x9
|
||||
endfunc plat_is_my_cpu_primary
|
||||
|
||||
/* -----------------------------------------------------
|
||||
* unsigned int plat_my_core_pos(void)
|
||||
* This function uses the versal_calc_core_pos()
|
||||
* definition to get the index of the calling CPU.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
func plat_my_core_pos
|
||||
mrs x0, mpidr_el1
|
||||
b versal_calc_core_pos
|
||||
endfunc plat_my_core_pos
|
||||
|
||||
func versal_calc_core_pos
|
||||
and x1, x0, #MPIDR_CPU_MASK
|
||||
and x0, x0, #MPIDR_CLUSTER_MASK
|
||||
add x0, x1, x0, LSR #6
|
||||
ret
|
||||
endfunc versal_calc_core_pos
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* We don't need to carry out any memory initialization on VERSAL
|
||||
* platform. The Secure RAM is accessible straight away.
|
||||
* ---------------------------------------------------------------------
|
||||
*/
|
||||
func platform_mem_init
|
||||
ret
|
||||
endfunc platform_mem_init
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <bl_common.h>
|
||||
#include <bl31.h>
|
||||
#include <console.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
#include <platform.h>
|
||||
#include <pl011.h>
|
||||
#include <xlat_tables.h>
|
||||
#include "versal_private.h"
|
||||
|
||||
static entry_point_info_t bl32_image_ep_info;
|
||||
static entry_point_info_t bl33_image_ep_info;
|
||||
static console_pl011_t versal_runtime_console;
|
||||
|
||||
/*
|
||||
* Return a pointer to the 'entry_point_info' structure of the next image for
|
||||
* the security state specified. BL33 corresponds to the non-secure image type
|
||||
* while BL32 corresponds to the secure image type. A NULL pointer is returned
|
||||
* if the image does not exist.
|
||||
*/
|
||||
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
|
||||
{
|
||||
assert(sec_state_is_valid(type));
|
||||
|
||||
if (type == NON_SECURE)
|
||||
return &bl33_image_ep_info;
|
||||
|
||||
return &bl32_image_ep_info;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform any BL31 specific platform actions. Here is an opportunity to copy
|
||||
* parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
|
||||
* are lost (potentially). This needs to be done before the MMU is initialized
|
||||
* so that the memory layout can be used while creating page tables.
|
||||
*/
|
||||
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3)
|
||||
{
|
||||
|
||||
/* Initialize the console to provide early debug support */
|
||||
int rc = console_pl011_register(VERSAL_UART_BASE,
|
||||
VERSAL_UART_CLOCK,
|
||||
VERSAL_UART_BAUDRATE,
|
||||
&versal_runtime_console);
|
||||
if (rc == 0)
|
||||
panic();
|
||||
|
||||
console_set_scope(&versal_runtime_console.console, CONSOLE_FLAG_BOOT |
|
||||
CONSOLE_FLAG_RUNTIME);
|
||||
|
||||
/* Initialize the platform config for future decision making */
|
||||
versal_config_setup();
|
||||
/* There are no parameters from BL2 if BL31 is a reset vector */
|
||||
assert(arg0 == 0U);
|
||||
assert(arg1 == 0U);
|
||||
|
||||
/*
|
||||
* Do initial security configuration to allow DRAM/device access. On
|
||||
* Base VERSAL only DRAM security is programmable (via TrustZone), but
|
||||
* other platforms might have more programmable security devices
|
||||
* present.
|
||||
*/
|
||||
|
||||
/* 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);
|
||||
SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0);
|
||||
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
|
||||
|
||||
/* use build time defaults in JTAG boot mode */
|
||||
bl32_image_ep_info.pc = BL32_BASE;
|
||||
bl32_image_ep_info.spsr = 0;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
/* Initialize the gic cpu and distributor interfaces */
|
||||
plat_versal_gic_driver_init();
|
||||
plat_versal_gic_init();
|
||||
}
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the very early platform specific architectural setup here.
|
||||
*/
|
||||
void bl31_plat_arch_setup(void)
|
||||
{
|
||||
const mmap_region_t bl_regions[] = {
|
||||
MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
|
||||
MT_MEMORY | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
|
||||
MT_CODE | MT_SECURE),
|
||||
MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
|
||||
MT_RO_DATA | MT_SECURE),
|
||||
MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
|
||||
BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
{0}
|
||||
};
|
||||
|
||||
setup_page_tables(bl_regions, plat_versal_get_mmap());
|
||||
enable_mmu_el3(0);
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLAT_MACROS_S
|
||||
#define PLAT_MACROS_S
|
||||
|
||||
#include "../include/platform_def.h"
|
||||
#include <gic_common.h>
|
||||
#include <gicv2.h>
|
||||
#include <gicv3.h>
|
||||
|
||||
.section .rodata.gic_reg_name, "aS"
|
||||
/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
|
||||
gicc_regs:
|
||||
.asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
|
||||
|
||||
/* Applicable only to GICv3 with SRE enabled */
|
||||
icc_regs:
|
||||
.asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
|
||||
|
||||
/* Registers common to both GICv2 and GICv3 */
|
||||
gicd_pend_reg:
|
||||
.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
|
||||
newline:
|
||||
.asciz "\n"
|
||||
spacer:
|
||||
.asciz ":\t\t0x"
|
||||
|
||||
/* ---------------------------------------------
|
||||
* The below utility macro prints out relevant GIC
|
||||
* registers whenever an unhandled exception is
|
||||
* taken in BL31 on Versal platform.
|
||||
* Expects: GICD base in x16, GICC base in x17
|
||||
* Clobbers: x0 - x10, sp
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
.macro versal_print_gic_regs
|
||||
/* Check for GICv3 system register access */
|
||||
mrs x7, id_aa64pfr0_el1
|
||||
ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
|
||||
cmp x7, #1
|
||||
b.ne print_gicv2
|
||||
|
||||
/* Check for SRE enable */
|
||||
mrs x8, ICC_SRE_EL3
|
||||
tst x8, #ICC_SRE_SRE_BIT
|
||||
b.eq print_gicv2
|
||||
|
||||
/* Load the icc reg list to x6 */
|
||||
adr x6, icc_regs
|
||||
/* Load the icc regs to gp regs used by str_in_crash_buf_print */
|
||||
mrs x8, ICC_HPPIR0_EL1
|
||||
mrs x9, ICC_HPPIR1_EL1
|
||||
mrs x10, ICC_CTLR_EL3
|
||||
/* Store to the crash buf and print to console */
|
||||
bl str_in_crash_buf_print
|
||||
b print_gic_common
|
||||
|
||||
print_gicv2:
|
||||
/* Load the gicc reg list to x6 */
|
||||
adr x6, gicc_regs
|
||||
/* Load the gicc regs to gp regs used by str_in_crash_buf_print */
|
||||
ldr w8, [x17, #GICC_HPPIR]
|
||||
ldr w9, [x17, #GICC_AHPPIR]
|
||||
ldr w10, [x17, #GICC_CTLR]
|
||||
/* Store to the crash buf and print to console */
|
||||
bl str_in_crash_buf_print
|
||||
|
||||
print_gic_common:
|
||||
/* Print the GICD_ISPENDR regs */
|
||||
add x7, x16, #GICD_ISPENDR
|
||||
adr x4, gicd_pend_reg
|
||||
bl asm_print_str
|
||||
gicd_ispendr_loop:
|
||||
sub x4, x7, x16
|
||||
cmp x4, #0x280
|
||||
b.eq exit_print_gic_regs
|
||||
bl asm_print_hex
|
||||
|
||||
adr x4, spacer
|
||||
bl asm_print_str
|
||||
|
||||
ldr x4, [x7], #8
|
||||
bl asm_print_hex
|
||||
|
||||
adr x4, newline
|
||||
bl asm_print_str
|
||||
b gicd_ispendr_loop
|
||||
exit_print_gic_regs:
|
||||
.endm
|
||||
|
||||
/* ---------------------------------------------
|
||||
* The below required platform porting macro
|
||||
* prints out relevant GIC and CCI registers
|
||||
* whenever an unhandled exception is taken in
|
||||
* BL31.
|
||||
* Clobbers: x0 - x10, x16, x17, sp
|
||||
* ---------------------------------------------
|
||||
*/
|
||||
.macro plat_crash_print_regs
|
||||
mov_imm x17, PLAT_VERSAL_GICD_BASE
|
||||
mov_imm x16, PLAT_VERSAL_GICR_BASE
|
||||
versal_print_gic_regs
|
||||
.endm
|
||||
|
||||
#endif /* PLAT_MACROS_S */
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_DEF_H
|
||||
#define PLATFORM_DEF_H
|
||||
|
||||
#include <arch.h>
|
||||
#include "../versal_def.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic platform constants
|
||||
******************************************************************************/
|
||||
|
||||
/* Size of cacheable stacks */
|
||||
#define PLATFORM_STACK_SIZE 0x440
|
||||
|
||||
#define PLATFORM_CORE_COUNT 2
|
||||
#define PLAT_MAX_PWR_LVL 1
|
||||
#define PLAT_MAX_RET_STATE 1
|
||||
#define PLAT_MAX_OFF_STATE 2
|
||||
|
||||
/*******************************************************************************
|
||||
* BL31 specific defines.
|
||||
******************************************************************************/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef VERSAL_ATF_MEM_BASE
|
||||
# define BL31_BASE 0xfffea000
|
||||
# define BL31_LIMIT 0xffffffff
|
||||
#else
|
||||
# define BL31_BASE (VERSAL_ATF_MEM_BASE)
|
||||
# define BL31_LIMIT (VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_SIZE - 1)
|
||||
# ifdef VERSAL_ATF_MEM_PROGBITS_SIZE
|
||||
# define BL31_PROGBITS_LIMIT (VERSAL_ATF_MEM_BASE + VERSAL_ATF_MEM_PROGBITS_SIZE - 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* BL32 specific defines.
|
||||
******************************************************************************/
|
||||
#ifndef VERSAL_BL32_MEM_BASE
|
||||
# define BL32_BASE 0x60000000
|
||||
# define BL32_LIMIT 0x7fffffff
|
||||
#else
|
||||
# define BL32_BASE (VERSAL_BL32_MEM_BASE)
|
||||
# define BL32_LIMIT (VERSAL_BL32_MEM_BASE + VERSAL_BL32_MEM_SIZE - 1)
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* BL33 specific defines.
|
||||
******************************************************************************/
|
||||
#ifndef PRELOADED_BL33_BASE
|
||||
# define PLAT_VERSAL_NS_IMAGE_OFFSET 0x8000000
|
||||
#else
|
||||
# define PLAT_VERSAL_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 PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
|
||||
#define MAX_MMAP_REGIONS 7
|
||||
#define MAX_XLAT_TABLES 5
|
||||
|
||||
#define CACHE_WRITEBACK_SHIFT 6
|
||||
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
|
||||
|
||||
#define PLAT_VERSAL_GICD_BASE 0xF9000000
|
||||
#define PLAT_VERSAL_GICR_BASE 0xF9080000
|
||||
|
||||
/*
|
||||
* Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
|
||||
* terminology. On a GICv2 system or mode, the lists will be merged and treated
|
||||
* as Group 0 interrupts.
|
||||
*/
|
||||
#define PLAT_VERSAL_G1S_IRQS VERSAL_IRQ_SEC_PHY_TIMER
|
||||
#define PLAT_VERSAL_G0_IRQS VERSAL_IRQ_SEC_PHY_TIMER
|
||||
|
||||
#define PLAT_VERSAL_G1S_IRQ_PROPS(grp) \
|
||||
INTR_PROP_DESC(VERSAL_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
|
||||
GIC_INTR_CFG_LEVEL)
|
||||
|
||||
#define PLAT_VERSAL_G0_IRQ_PROPS(grp)
|
||||
|
||||
#endif /* PLATFORM_DEF_H */
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <psci.h>
|
||||
#include "versal_private.h"
|
||||
|
||||
static uintptr_t versal_sec_entry;
|
||||
|
||||
static int versal_nopmc_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
uint32_t r;
|
||||
unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
|
||||
|
||||
VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
|
||||
|
||||
if (cpu_id == -1)
|
||||
return PSCI_E_INTERN_FAIL;
|
||||
|
||||
/*
|
||||
* program RVBAR
|
||||
*/
|
||||
mmio_write_32(FPD_APU_RVBAR_L_0 + (cpu_id << 3), versal_sec_entry);
|
||||
mmio_write_32(FPD_APU_RVBAR_H_0 + (cpu_id << 3), versal_sec_entry >> 32);
|
||||
|
||||
/*
|
||||
* clear VINITHI
|
||||
*/
|
||||
r = mmio_read_32(FPD_APU_CONFIG_0);
|
||||
r &= ~(1 << FPD_APU_CONFIG_0_VINITHI_SHIFT << cpu_id);
|
||||
mmio_write_32(FPD_APU_CONFIG_0, r);
|
||||
|
||||
/*
|
||||
* FIXME: Add power up sequence, By default it works
|
||||
* now without the need of it as it was powered up by
|
||||
* default.
|
||||
*/
|
||||
|
||||
/*
|
||||
* clear power down request
|
||||
*/
|
||||
r = mmio_read_32(FPD_APU_PWRCTL);
|
||||
r &= ~(1 << cpu_id);
|
||||
mmio_write_32(FPD_APU_PWRCTL, r);
|
||||
|
||||
/*
|
||||
* release core reset
|
||||
*/
|
||||
r = mmio_read_32(CRF_RST_APU);
|
||||
r &= ~((CRF_RST_APU_ACPU_PWRON_RESET |
|
||||
CRF_RST_APU_ACPU_RESET) << cpu_id);
|
||||
mmio_write_32(CRF_RST_APU, r);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
void versal_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
/* Enable the gic cpu interface */
|
||||
plat_versal_gic_pcpu_init();
|
||||
|
||||
/* Program the gic per-cpu distributor or re-distributor interface */
|
||||
plat_versal_gic_cpuif_enable();
|
||||
}
|
||||
|
||||
static const struct plat_psci_ops versal_nopmc_psci_ops = {
|
||||
.pwr_domain_on = versal_nopmc_pwr_domain_on,
|
||||
.pwr_domain_on_finish = versal_pwr_domain_on_finish,
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Export the platform specific power ops.
|
||||
******************************************************************************/
|
||||
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
|
||||
const struct plat_psci_ops **psci_ops)
|
||||
{
|
||||
versal_sec_entry = sec_entrypoint;
|
||||
|
||||
*psci_ops = &versal_nopmc_psci_ops;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
static const unsigned char plat_power_domain_tree_desc[] = {1, PLATFORM_CORE_COUNT};
|
||||
|
||||
const unsigned char *plat_get_power_domain_tree_desc(void)
|
||||
{
|
||||
return plat_power_domain_tree_desc;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <platform.h>
|
||||
#include "versal_private.h"
|
||||
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
if (mpidr & MPIDR_CLUSTER_MASK)
|
||||
return -1;
|
||||
|
||||
if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
|
||||
return -1;
|
||||
|
||||
return versal_calc_core_pos(mpidr);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
override PROGRAMMABLE_RESET_ADDRESS := 1
|
||||
PSCI_EXTENDED_STATE_ID := 1
|
||||
A53_DISABLE_NON_TEMPORAL_HINT := 0
|
||||
SEPARATE_CODE_AND_RODATA := 1
|
||||
override RESET_TO_BL31 := 1
|
||||
PL011_GENERIC_UART := 1
|
||||
MULTI_CONSOLE_API := 1
|
||||
|
||||
ifdef VERSAL_ATF_MEM_BASE
|
||||
$(eval $(call add_define,VERSAL_ATF_MEM_BASE))
|
||||
|
||||
ifndef VERSAL_ATF_MEM_SIZE
|
||||
$(error "VERSAL_ATF_BASE defined without VERSAL_ATF_SIZE")
|
||||
endif
|
||||
$(eval $(call add_define,VERSAL_ATF_MEM_SIZE))
|
||||
|
||||
ifdef VERSAL_ATF_MEM_PROGBITS_SIZE
|
||||
$(eval $(call add_define,VERSAL_ATF_MEM_PROGBITS_SIZE))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef VERSAL_BL32_MEM_BASE
|
||||
$(eval $(call add_define,VERSAL_BL32_MEM_BASE))
|
||||
|
||||
ifndef VERSAL_BL32_MEM_SIZE
|
||||
$(error "VERSAL_BL32_BASE defined without VERSAL_BL32_SIZE")
|
||||
endif
|
||||
$(eval $(call add_define,VERSAL_BL32_MEM_SIZE))
|
||||
endif
|
||||
|
||||
VERSAL_PLATFORM ?= versal_virt
|
||||
$(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM}))
|
||||
|
||||
VERSAL_CONSOLE ?= pl011
|
||||
$(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE}))
|
||||
|
||||
PLAT_INCLUDES := -Iplat/xilinx/versal/include/
|
||||
|
||||
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
|
||||
lib/xlat_tables/aarch64/xlat_tables.c \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
drivers/arm/gic/common/gic_common.c \
|
||||
drivers/arm/gic/v3/gicv3_main.c \
|
||||
drivers/arm/gic/v3/gicv3_helpers.c \
|
||||
drivers/arm/pl011/aarch64/pl011_console.S \
|
||||
plat/common/plat_gicv3.c \
|
||||
plat/xilinx/versal/aarch64/versal_helpers.S \
|
||||
plat/xilinx/versal/aarch64/versal_common.c
|
||||
|
||||
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
|
||||
lib/cpus/aarch64/cortex_a72.S \
|
||||
plat/common/plat_psci_common.c \
|
||||
plat/xilinx/versal/bl31_versal_setup.c \
|
||||
plat/xilinx/versal/plat_psci.c \
|
||||
plat/xilinx/versal/plat_versal.c \
|
||||
plat/xilinx/versal/plat_topology.c \
|
||||
plat/xilinx/versal/sip_svc_setup.c \
|
||||
plat/xilinx/versal/versal_gicv3.c
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* Top level SMC handler for SiP calls. Dispatch PM calls to PM SMC handler. */
|
||||
|
||||
#include <debug.h>
|
||||
#include <runtime_svc.h>
|
||||
#include <uuid.h>
|
||||
|
||||
/* SMC function IDs for SiP Service queries */
|
||||
#define VERSAL_SIP_SVC_CALL_COUNT 0x8200ff00
|
||||
#define VERSAL_SIP_SVC_UID 0x8200ff01
|
||||
#define VERSAL_SIP_SVC_VERSION 0x8200ff03
|
||||
|
||||
/* SiP Service Calls version numbers */
|
||||
#define SIP_SVC_VERSION_MAJOR 0
|
||||
#define SIP_SVC_VERSION_MINOR 1
|
||||
|
||||
/* These macros are used to identify PM calls from the SMC function ID */
|
||||
#define PM_FID_MASK 0xf000u
|
||||
#define PM_FID_VALUE 0u
|
||||
#define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE)
|
||||
|
||||
/* SiP Service UUID */
|
||||
DEFINE_SVC_UUID2(versal_sip_uuid,
|
||||
0x2ab9e4ec, 0x93b9, 0x11e7, 0xa0, 0x19,
|
||||
0xdf, 0xe0, 0xdb, 0xad, 0x0a, 0xe0);
|
||||
|
||||
/**
|
||||
* sip_svc_setup() - Setup SiP Service
|
||||
*
|
||||
* Invokes PM setup
|
||||
*/
|
||||
static int32_t sip_svc_setup(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sip_svc_smc_handler() - Top-level SiP Service SMC handler
|
||||
*
|
||||
* Handler for all SiP SMC calls. Handles standard SIP requests
|
||||
* and calls PM SMC handler if the call is for a PM-API function.
|
||||
*/
|
||||
uintptr_t sip_svc_smc_handler(uint32_t smc_fid,
|
||||
u_register_t x1,
|
||||
u_register_t x2,
|
||||
u_register_t x3,
|
||||
u_register_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
u_register_t flags)
|
||||
{
|
||||
/* Let PM SMC handler deal with PM-related requests */
|
||||
switch (smc_fid) {
|
||||
case VERSAL_SIP_SVC_CALL_COUNT:
|
||||
/* PM functions + default functions */
|
||||
SMC_RET1(handle, 2);
|
||||
|
||||
case VERSAL_SIP_SVC_UID:
|
||||
SMC_UUID_RET(handle, versal_sip_uuid);
|
||||
|
||||
case VERSAL_SIP_SVC_VERSION:
|
||||
SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
|
||||
|
||||
default:
|
||||
WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register PM Service Calls as runtime service */
|
||||
DECLARE_RT_SVC(
|
||||
sip_svc,
|
||||
OEN_SIP_START,
|
||||
OEN_SIP_END,
|
||||
SMC_TYPE_FAST,
|
||||
sip_svc_setup,
|
||||
sip_svc_smc_handler);
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef VERSAL_DEF_H
|
||||
#define VERSAL_DEF_H
|
||||
|
||||
#include <common_def.h>
|
||||
|
||||
/* List all consoles */
|
||||
#define VERSAL_CONSOLE_ID_pl011 1
|
||||
#define VERSAL_CONSOLE_ID_pl011_0 1
|
||||
#define VERSAL_CONSOLE_ID_pl011_1 2
|
||||
#define VERSAL_CONSOLE_ID_dcc 3
|
||||
|
||||
#define VERSAL_CONSOLE_IS(con) (VERSAL_CONSOLE_ID_ ## con == VERSAL_CONSOLE)
|
||||
|
||||
/* List all supported platforms */
|
||||
#define VERSAL_PLATFORM_ID_versal_virt 1
|
||||
|
||||
#define VERSAL_PLATFORM_IS(con) (VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM)
|
||||
|
||||
/* Firmware Image Package */
|
||||
#define VERSAL_PRIMARY_CPU 0
|
||||
|
||||
/*******************************************************************************
|
||||
* memory map related constants
|
||||
******************************************************************************/
|
||||
#define DEVICE0_BASE 0xFF000000
|
||||
#define DEVICE0_SIZE 0x00E00000
|
||||
#define DEVICE1_BASE 0xF9000000
|
||||
#define DEVICE1_SIZE 0x00800000
|
||||
|
||||
/* CRL */
|
||||
#define VERSAL_CRL 0xFF5E0000
|
||||
#define VERSAL_CRL_IOU_SWITCH_CTRL (VERSAL_CRL + 0x114)
|
||||
#define VERSAL_CRL_TIMESTAMP_REF_CTRL (VERSAL_CRL + 0x14C)
|
||||
#define VERSAL_CRL_RST_TIMESTAMP_OFFSET (VERSAL_CRL + 0x348)
|
||||
|
||||
#define VERSAL_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT (1 << 25)
|
||||
#define VERSAL_IOU_SWITCH_CTRL_CLKACT_BIT (1 << 25)
|
||||
#define VERSAL_IOU_SWITCH_CTRL_DIVISOR0_SHIFT 8
|
||||
|
||||
/* IOU SCNTRS */
|
||||
#define VERSAL_IOU_SCNTRS 0xFF140000
|
||||
#define VERSAL_IOU_SCNTRS_COUNTER_CONTROL_REG (VERSAL_IOU_SCNTRS + 0x0)
|
||||
#define VERSAL_IOU_SCNTRS_BASE_FREQ (VERSAL_IOU_SCNTRS + 0x20)
|
||||
|
||||
#define VERSAL_IOU_SCNTRS_CONTROL_EN 1
|
||||
|
||||
/*******************************************************************************
|
||||
* IRQ constants
|
||||
******************************************************************************/
|
||||
#define VERSAL_IRQ_SEC_PHY_TIMER 29
|
||||
|
||||
/*******************************************************************************
|
||||
* UART related constants
|
||||
******************************************************************************/
|
||||
#define VERSAL_UART0_BASE 0xFF000000
|
||||
#define VERSAL_UART1_BASE 0xFF010000
|
||||
|
||||
#if VERSAL_CONSOLE_IS(pl011)
|
||||
# define VERSAL_UART_BASE VERSAL_UART0_BASE
|
||||
#elif VERSAL_CONSOLE_IS(pl011_1)
|
||||
# define VERSAL_UART_BASE VERSAL_UART1_BASE
|
||||
#else
|
||||
# error "invalid VERSAL_CONSOLE"
|
||||
#endif
|
||||
|
||||
#define PLAT_VERSAL_CRASH_UART_BASE VERSAL_UART_BASE
|
||||
#define PLAT_VERSAL_CRASH_UART_CLK_IN_HZ VERSAL_UART_CLOCK
|
||||
#define VERSAL_CONSOLE_BAUDRATE VERSAL_UART_BAUDRATE
|
||||
|
||||
/*******************************************************************************
|
||||
* Platform related constants
|
||||
******************************************************************************/
|
||||
#if VERSAL_PLATFORM_IS(versal_virt)
|
||||
# define PLATFORM_NAME "Versal Virt"
|
||||
# define VERSAL_UART_CLOCK 25000000
|
||||
# define VERSAL_UART_BAUDRATE 115200
|
||||
# define VERSAL_CPU_CLOCK 62500000
|
||||
#endif
|
||||
|
||||
/* Access control register defines */
|
||||
#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
|
||||
#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
|
||||
|
||||
/* For cpu reset APU space here too 0xFE5F1000 CRF_APB*/
|
||||
#define CRF_BASE 0xFD1A0000
|
||||
#define CRF_SIZE 0x00600000
|
||||
|
||||
/* CRF registers and bitfields */
|
||||
#define CRF_RST_APU (CRF_BASE + 0X00000300)
|
||||
|
||||
#define CRF_RST_APU_ACPU_RESET (1 << 0)
|
||||
#define CRF_RST_APU_ACPU_PWRON_RESET (1 << 10)
|
||||
|
||||
/* APU registers and bitfields */
|
||||
#define FPD_APU_BASE 0xFD5C0000
|
||||
#define FPD_APU_CONFIG_0 (FPD_APU_BASE + 0x20)
|
||||
#define FPD_APU_RVBAR_L_0 (FPD_APU_BASE + 0x40)
|
||||
#define FPD_APU_RVBAR_H_0 (FPD_APU_BASE + 0x44)
|
||||
#define FPD_APU_PWRCTL (FPD_APU_BASE + 0x90)
|
||||
|
||||
#define FPD_APU_CONFIG_0_VINITHI_SHIFT 8
|
||||
|
||||
#endif /* VERSAL_DEF_H */
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <gicv3.h>
|
||||
#include <interrupt_props.h>
|
||||
#include <platform.h>
|
||||
#include <platform_def.h>
|
||||
#include <utils.h>
|
||||
#include "versal_private.h"
|
||||
|
||||
/******************************************************************************
|
||||
* The following functions are defined as weak to allow a platform to override
|
||||
* the way the GICv3 driver is initialised and used.
|
||||
*****************************************************************************/
|
||||
#pragma weak plat_versal_gic_driver_init
|
||||
#pragma weak plat_versal_gic_init
|
||||
#pragma weak plat_versal_gic_cpuif_enable
|
||||
#pragma weak plat_versal_gic_cpuif_disable
|
||||
#pragma weak plat_versal_gic_pcpu_init
|
||||
#pragma weak plat_versal_gic_redistif_on
|
||||
#pragma weak plat_versal_gic_redistif_off
|
||||
|
||||
/* The GICv3 driver only needs to be initialized in EL3 */
|
||||
static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
|
||||
|
||||
static const interrupt_prop_t versal_interrupt_props[] = {
|
||||
PLAT_VERSAL_G1S_IRQ_PROPS(INTR_GROUP1S),
|
||||
PLAT_VERSAL_G0_IRQ_PROPS(INTR_GROUP0)
|
||||
};
|
||||
|
||||
/*
|
||||
* We save and restore the GICv3 context on system suspend. Allocate the
|
||||
* data in the designated EL3 Secure carve-out memory.
|
||||
*/
|
||||
static gicv3_redist_ctx_t rdist_ctx __section("versal_el3_tzc_dram");
|
||||
static gicv3_dist_ctx_t dist_ctx __section("versal_el3_tzc_dram");
|
||||
|
||||
/*
|
||||
* MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
|
||||
* to core position.
|
||||
*
|
||||
* Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
|
||||
* values read from GICR_TYPER don't have an MT field. To reuse the same
|
||||
* translation used for CPUs, we insert MT bit read from the PE's MPIDR into
|
||||
* that read from GICR_TYPER.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
* - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
|
||||
* - No CPUs implemented in the system use affinity level 3.
|
||||
*/
|
||||
static unsigned int versal_gicv3_mpidr_hash(u_register_t mpidr)
|
||||
{
|
||||
mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
|
||||
return versal_calc_core_pos(mpidr);
|
||||
}
|
||||
|
||||
static const gicv3_driver_data_t versal_gic_data __unused = {
|
||||
.gicd_base = PLAT_VERSAL_GICD_BASE,
|
||||
.gicr_base = PLAT_VERSAL_GICR_BASE,
|
||||
.interrupt_props = versal_interrupt_props,
|
||||
.interrupt_props_num = ARRAY_SIZE(versal_interrupt_props),
|
||||
.rdistif_num = PLATFORM_CORE_COUNT,
|
||||
.rdistif_base_addrs = rdistif_base_addrs,
|
||||
.mpidr_to_core_pos = versal_gicv3_mpidr_hash
|
||||
};
|
||||
|
||||
void __init plat_versal_gic_driver_init(void)
|
||||
{
|
||||
/*
|
||||
* The GICv3 driver is initialized in EL3 and does not need
|
||||
* to be initialized again in SEL1. This is because the S-EL1
|
||||
* can use GIC system registers to manage interrupts and does
|
||||
* not need GIC interface base addresses to be configured.
|
||||
*/
|
||||
#if IMAGE_BL31
|
||||
gicv3_driver_init(&versal_gic_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Versal common helper to initialize the GIC. Only invoked by BL31
|
||||
*****************************************************************************/
|
||||
void __init plat_versal_gic_init(void)
|
||||
{
|
||||
gicv3_distif_init();
|
||||
gicv3_rdistif_init(plat_my_core_pos());
|
||||
gicv3_cpuif_enable(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Versal common helper to enable the GIC CPU interface
|
||||
*****************************************************************************/
|
||||
void plat_versal_gic_cpuif_enable(void)
|
||||
{
|
||||
gicv3_cpuif_enable(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Versal common helper to disable the GIC CPU interface
|
||||
*****************************************************************************/
|
||||
void plat_versal_gic_cpuif_disable(void)
|
||||
{
|
||||
gicv3_cpuif_disable(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Versal common helper to initialize the per-cpu redistributor interface in
|
||||
* GICv3
|
||||
*****************************************************************************/
|
||||
void plat_versal_gic_pcpu_init(void)
|
||||
{
|
||||
gicv3_rdistif_init(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Versal common helpers to power GIC redistributor interface
|
||||
*****************************************************************************/
|
||||
void plat_versal_gic_redistif_on(void)
|
||||
{
|
||||
gicv3_rdistif_on(plat_my_core_pos());
|
||||
}
|
||||
|
||||
void plat_versal_gic_redistif_off(void)
|
||||
{
|
||||
gicv3_rdistif_off(plat_my_core_pos());
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Versal common helper to save & restore the GICv3 on resume from system
|
||||
* suspend
|
||||
*****************************************************************************/
|
||||
void plat_versal_gic_save(void)
|
||||
{
|
||||
/*
|
||||
* If an ITS is available, save its context before
|
||||
* the Redistributor using:
|
||||
* gicv3_its_save_disable(gits_base, &its_ctx[i])
|
||||
* Additionnaly, an implementation-defined sequence may
|
||||
* be required to save the whole ITS state.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Save the GIC Redistributors and ITS contexts before the
|
||||
* Distributor context. As we only handle SYSTEM SUSPEND API,
|
||||
* we only need to save the context of the CPU that is issuing
|
||||
* the SYSTEM SUSPEND call, i.e. the current CPU.
|
||||
*/
|
||||
gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
|
||||
|
||||
/* Save the GIC Distributor context */
|
||||
gicv3_distif_save(&dist_ctx);
|
||||
|
||||
/*
|
||||
* From here, all the components of the GIC can be safely powered down
|
||||
* as long as there is an alternate way to handle wakeup interrupt
|
||||
* sources.
|
||||
*/
|
||||
}
|
||||
|
||||
void plat_versal_gic_resume(void)
|
||||
{
|
||||
/* Restore the GIC Distributor context */
|
||||
gicv3_distif_init_restore(&dist_ctx);
|
||||
|
||||
/*
|
||||
* Restore the GIC Redistributor and ITS contexts after the
|
||||
* Distributor context. As we only handle SYSTEM SUSPEND API,
|
||||
* we only need to restore the context of the CPU that issued
|
||||
* the SYSTEM SUSPEND call.
|
||||
*/
|
||||
gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
|
||||
|
||||
/*
|
||||
* If an ITS is available, restore its context after
|
||||
* the Redistributor using:
|
||||
* gicv3_its_restore(gits_base, &its_ctx[i])
|
||||
* An implementation-defined sequence may be required to
|
||||
* restore the whole ITS state. The ITS must also be
|
||||
* re-enabled after this sequence has been executed.
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef VERSAL_PRIVATE_H
|
||||
#define VERSAL_PRIVATE_H
|
||||
|
||||
#include <xlat_tables.h>
|
||||
|
||||
void versal_config_setup(void);
|
||||
|
||||
const mmap_region_t *plat_versal_get_mmap(void);
|
||||
|
||||
void plat_versal_gic_driver_init(void);
|
||||
void plat_versal_gic_init(void);
|
||||
void plat_versal_gic_cpuif_enable(void);
|
||||
void plat_versal_gic_cpuif_disable(void);
|
||||
void plat_versal_gic_pcpu_init(void);
|
||||
|
||||
unsigned int versal_calc_core_pos(u_register_t mpidr);
|
||||
|
||||
#endif /* VERSAL_PRIVATE_H */
|
Loading…
Reference in New Issue