Merge pull request #1605 from sivadur/integration

Add support new Xilinx Versal ACAP platform
This commit is contained in:
Antonio Niño Díaz 2018-11-12 10:56:41 +01:00 committed by GitHub
commit e07666de14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1093 additions and 0 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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.
*/
}

View File

@ -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 */