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
e07666de
Unverified
Commit
e07666de
authored
Nov 12, 2018
by
Antonio Niño Díaz
Committed by
GitHub
Nov 12, 2018
Browse files
Merge pull request #1605 from sivadur/integration
Add support new Xilinx Versal ACAP platform
parents
9d068f66
f91c3cb1
Changes
14
Hide whitespace changes
Inline
Side-by-side
docs/plat/xilinx-versal.md
0 → 100644
View file @
e07666de
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
plat/xilinx/versal/aarch64/versal_common.c
0 → 100644
View file @
e07666de
/*
* 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
}
plat/xilinx/versal/aarch64/versal_helpers.S
0 → 100644
View file @
e07666de
/*
*
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
plat/xilinx/versal/bl31_versal_setup.c
0 → 100644
View file @
e07666de
/*
* 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
);
}
plat/xilinx/versal/include/plat_macros.S
0 → 100644
View file @
e07666de
/*
*
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 */
plat/xilinx/versal/include/platform_def.h
0 → 100644
View file @
e07666de
/*
* 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 */
plat/xilinx/versal/plat_psci.c
0 → 100644
View file @
e07666de
/*
* 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
;
}
plat/xilinx/versal/plat_topology.c
0 → 100644
View file @
e07666de
/*
* 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
;
}
plat/xilinx/versal/plat_versal.c
0 → 100644
View file @
e07666de
/*
* 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
);
}
plat/xilinx/versal/platform.mk
0 → 100644
View file @
e07666de
# 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
plat/xilinx/versal/sip_svc_setup.c
0 → 100644
View file @
e07666de
/*
* 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
);
plat/xilinx/versal/versal_def.h
0 → 100644
View file @
e07666de
/*
* 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 */
plat/xilinx/versal/versal_gicv3.c
0 → 100644
View file @
e07666de
/*
* 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.
*/
}
plat/xilinx/versal/versal_private.h
0 → 100644
View file @
e07666de
/*
* 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 */
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