Add initial support for Juno platform
Change-Id: Ib3d92df3af53820cfbb2977582ed0d7abf6ef893
This commit is contained in:
parent
c1efc4c066
commit
cd45dd98ff
|
@ -43,13 +43,20 @@ func cpu_reset_handler
|
||||||
lsr x0, x0, #MIDR_PN_SHIFT
|
lsr x0, x0, #MIDR_PN_SHIFT
|
||||||
and x0, x0, #MIDR_PN_MASK
|
and x0, x0, #MIDR_PN_MASK
|
||||||
cmp x0, #MIDR_PN_A57
|
cmp x0, #MIDR_PN_A57
|
||||||
b.eq smp_setup_begin
|
b.eq a57_setup_begin
|
||||||
cmp x0, #MIDR_PN_A53
|
cmp x0, #MIDR_PN_A53
|
||||||
b.ne smp_setup_end
|
b.eq smp_setup_begin
|
||||||
|
b smp_setup_end
|
||||||
|
|
||||||
|
a57_setup_begin:
|
||||||
|
mov x0, #0x082
|
||||||
|
msr s3_1_c11_c0_2, x0
|
||||||
|
|
||||||
smp_setup_begin:
|
smp_setup_begin:
|
||||||
mrs x0, CPUECTLR_EL1
|
mrs x0, CPUECTLR_EL1
|
||||||
orr x0, x0, #CPUECTLR_SMP_BIT
|
orr x0, x0, #CPUECTLR_SMP_BIT
|
||||||
msr CPUECTLR_EL1, x0
|
msr CPUECTLR_EL1, x0
|
||||||
isb
|
isb
|
||||||
|
|
||||||
smp_setup_end:
|
smp_setup_end:
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <asm_macros.S>
|
||||||
|
#include "../juno_def.h"
|
||||||
|
|
||||||
|
.globl platform_get_entrypoint
|
||||||
|
.globl platform_cold_boot_init
|
||||||
|
.globl plat_secondary_cold_boot_setup
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------
|
||||||
|
* 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.
|
||||||
|
* -----------------------------------------------------
|
||||||
|
*/
|
||||||
|
func plat_secondary_cold_boot_setup
|
||||||
|
/* Juno todo: Implement secondary CPU cold boot setup on Juno */
|
||||||
|
cb_panic:
|
||||||
|
b cb_panic
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------
|
||||||
|
* void platform_get_entrypoint (unsigned int mpid);
|
||||||
|
*
|
||||||
|
* Main job of this routine is to distinguish between
|
||||||
|
* a cold and warm boot.
|
||||||
|
* On a cold boot the secondaries first wait for the
|
||||||
|
* platform to be initialized after which they are
|
||||||
|
* hotplugged in. The primary proceeds to perform the
|
||||||
|
* platform initialization.
|
||||||
|
* On a warm boot, each cpu jumps to the address in its
|
||||||
|
* mailbox.
|
||||||
|
*
|
||||||
|
* TODO: Not a good idea to save lr in a temp reg
|
||||||
|
* -----------------------------------------------------
|
||||||
|
*/
|
||||||
|
func platform_get_entrypoint
|
||||||
|
mov x9, x30 // lr
|
||||||
|
bl platform_get_core_pos
|
||||||
|
ldr x1, =TRUSTED_MAILBOXES_BASE
|
||||||
|
lsl x0, x0, #TRUSTED_MAILBOX_SHIFT
|
||||||
|
ldr x0, [x1, x0]
|
||||||
|
ret x9
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------
|
||||||
|
* void platform_cold_boot_init (bl1_main function);
|
||||||
|
*
|
||||||
|
* Routine called only by the primary cpu after a cold
|
||||||
|
* boot to perform early platform initialization
|
||||||
|
* -----------------------------------------------------
|
||||||
|
*/
|
||||||
|
func platform_cold_boot_init
|
||||||
|
mov x20, x0
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Give ourselves a small coherent stack to
|
||||||
|
* ease the pain of initializing the MMU and
|
||||||
|
* CCI in assembler
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
bl platform_set_coherent_stack
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Architectural init. can be generic e.g.
|
||||||
|
* enabling stack alignment and platform spec-
|
||||||
|
* ific e.g. MMU & page table setup as per the
|
||||||
|
* platform memory map. Perform the latter here
|
||||||
|
* and the former in bl1_main.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
bl bl1_early_platform_setup
|
||||||
|
bl bl1_plat_arch_setup
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Give ourselves a stack allocated in Normal
|
||||||
|
* -IS-WBWA memory
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
mrs x0, mpidr_el1
|
||||||
|
bl platform_set_stack
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* Jump to the main function. Returning from it
|
||||||
|
* is a terminal error.
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
blr x20
|
||||||
|
|
||||||
|
cb_init_panic:
|
||||||
|
b cb_init_panic
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <mmio.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <xlat_tables.h>
|
||||||
|
#include "../juno_def.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of regions to map using the MMU.
|
||||||
|
* This doesn't include Trusted RAM as the 'mem_layout' argument passed to
|
||||||
|
* configure_mmu_elx() will give the available subset of that,
|
||||||
|
*/
|
||||||
|
static const mmap_region_t juno_mmap[] = {
|
||||||
|
{ TZROM_BASE, TZROM_BASE, TZROM_SIZE, MT_MEMORY | MT_RO | MT_SECURE },
|
||||||
|
{ MHU_SECURE_BASE, MHU_SECURE_BASE, MHU_SECURE_SIZE, (MHU_PAYLOAD_CACHED ? MT_MEMORY : MT_DEVICE) | MT_RW | MT_SECURE },
|
||||||
|
{ FLASH_BASE, FLASH_BASE, FLASH_SIZE, MT_MEMORY | MT_RO | MT_SECURE },
|
||||||
|
{ EMMC_BASE, EMMC_BASE, EMMC_SIZE, MT_MEMORY | MT_RO | MT_SECURE },
|
||||||
|
{ PSRAM_BASE, PSRAM_BASE, PSRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE }, /* Used for 'TZDRAM' */
|
||||||
|
{ IOFPGA_BASE, IOFPGA_BASE, IOFPGA_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
|
||||||
|
{ DEVICE0_BASE, DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
|
||||||
|
{ DEVICE1_BASE, DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE },
|
||||||
|
{ DRAM_BASE, DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS },
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Macro generating the code for the function setting up the pagetables as per
|
||||||
|
* the platform memory map & initialize the mmu, for the given exception level
|
||||||
|
******************************************************************************/
|
||||||
|
#define DEFINE_CONFIGURE_MMU_EL(_el) \
|
||||||
|
void configure_mmu_el##_el(unsigned long total_base, \
|
||||||
|
unsigned long total_size, \
|
||||||
|
unsigned long ro_start, \
|
||||||
|
unsigned long ro_limit, \
|
||||||
|
unsigned long coh_start, \
|
||||||
|
unsigned long coh_limit) \
|
||||||
|
{ \
|
||||||
|
mmap_add_region(total_base, total_base, \
|
||||||
|
total_size, \
|
||||||
|
MT_MEMORY | MT_RW | MT_SECURE); \
|
||||||
|
mmap_add_region(ro_start, ro_start, \
|
||||||
|
ro_limit - ro_start, \
|
||||||
|
MT_MEMORY | MT_RO | MT_SECURE); \
|
||||||
|
mmap_add_region(coh_start, coh_start, \
|
||||||
|
coh_limit - coh_start, \
|
||||||
|
MT_DEVICE | MT_RW | MT_SECURE); \
|
||||||
|
mmap_add(juno_mmap); \
|
||||||
|
init_xlat_tables(); \
|
||||||
|
\
|
||||||
|
enable_mmu_el##_el(0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define EL1 and EL3 variants of the function initialising the MMU */
|
||||||
|
DEFINE_CONFIGURE_MMU_EL(1)
|
||||||
|
DEFINE_CONFIGURE_MMU_EL(3)
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long plat_get_ns_image_entrypoint(void)
|
||||||
|
{
|
||||||
|
return NS_IMAGE_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t plat_get_syscnt_freq(void)
|
||||||
|
{
|
||||||
|
uint64_t counter_base_frequency;
|
||||||
|
|
||||||
|
/* Read the frequency from Frequency modes table */
|
||||||
|
counter_base_frequency = mmio_read_32(SYS_CNTCTL_BASE + CNTFID_OFF);
|
||||||
|
|
||||||
|
/* The first entry of the frequency modes table must not be 0 */
|
||||||
|
if (counter_base_frequency == 0)
|
||||||
|
panic();
|
||||||
|
|
||||||
|
return counter_base_frequency;
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <asm_macros.S>
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include "../juno_def.h"
|
||||||
|
|
||||||
|
.globl plat_crash_console_init
|
||||||
|
.globl plat_crash_console_putc
|
||||||
|
.globl plat_report_exception
|
||||||
|
.globl platform_get_core_pos
|
||||||
|
.globl platform_is_primary_cpu
|
||||||
|
.globl platform_mem_init
|
||||||
|
|
||||||
|
/* Define a crash console for the plaform */
|
||||||
|
#define JUNO_CRASH_CONSOLE_BASE PL011_UART0_BASE
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* int plat_crash_console_init(void)
|
||||||
|
* Function to initialize the crash console
|
||||||
|
* without a C Runtime to print crash report.
|
||||||
|
* Clobber list : x0, x1, x2
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
func plat_crash_console_init
|
||||||
|
mov_imm x0, JUNO_CRASH_CONSOLE_BASE
|
||||||
|
mov_imm x1, PL011_UART0_CLK_IN_HZ
|
||||||
|
mov_imm x2, PL011_BAUDRATE
|
||||||
|
b console_core_init
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* int plat_crash_console_putc(int c)
|
||||||
|
* Function to print a character on the crash
|
||||||
|
* console without a C Runtime.
|
||||||
|
* Clobber list : x1, x2
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
func plat_crash_console_putc
|
||||||
|
mov_imm x1, JUNO_CRASH_CONSOLE_BASE
|
||||||
|
b console_core_putc
|
||||||
|
|
||||||
|
/* ---------------------------------------------
|
||||||
|
* void plat_report_exception(unsigned int type)
|
||||||
|
* Function to report an unhandled exception
|
||||||
|
* with platform-specific means.
|
||||||
|
* On Juno platform, it updates the LEDs
|
||||||
|
* to indicate where we are
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
func plat_report_exception
|
||||||
|
mrs x1, CurrentEl
|
||||||
|
lsr x1, x1, #MODE_EL_SHIFT
|
||||||
|
lsl x1, x1, #SYS_LED_EL_SHIFT
|
||||||
|
lsl x0, x0, #SYS_LED_EC_SHIFT
|
||||||
|
mov x2, #(SECURE << SYS_LED_SS_SHIFT)
|
||||||
|
orr x0, x0, x2
|
||||||
|
orr x0, x0, x1
|
||||||
|
mov x1, #VE_SYSREGS_BASE
|
||||||
|
add x1, x1, #V2M_SYS_LED
|
||||||
|
str w0, [x1]
|
||||||
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 0 to 3 for the A53s and 4 or 5 for the A57s
|
||||||
|
*/
|
||||||
|
func platform_get_core_pos
|
||||||
|
and x1, x0, #MPIDR_CPU_MASK
|
||||||
|
and x0, x0, #MPIDR_CLUSTER_MASK
|
||||||
|
eor x0, x0, #(1 << MPIDR_AFFINITY_BITS) // swap A53/A57 order
|
||||||
|
add x0, x1, x0, LSR #6
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------
|
||||||
|
* unsigned int platform_is_primary_cpu(unsigned long mpid);
|
||||||
|
*
|
||||||
|
* Given the mpidr say whether this cpu is the primary
|
||||||
|
* cpu (applicable only after a cold boot)
|
||||||
|
* -----------------------------------------------------
|
||||||
|
*/
|
||||||
|
func platform_is_primary_cpu
|
||||||
|
/* Juno todo: allow configuration of primary CPU using SCC */
|
||||||
|
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
|
||||||
|
cmp x0, #JUNO_PRIMARY_CPU
|
||||||
|
cset x0, eq
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/* -----------------------------------------------------
|
||||||
|
* void platform_mem_init(void);
|
||||||
|
*
|
||||||
|
* We don't need to carry out any memory initialization
|
||||||
|
* on Juno. The Secure RAM is accessible straight away.
|
||||||
|
* -----------------------------------------------------
|
||||||
|
*/
|
||||||
|
func platform_mem_init
|
||||||
|
ret
|
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <cci400.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <mmio.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <tzc400.h>
|
||||||
|
#include "../../bl1/bl1_private.h"
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "juno_private.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Declarations of linker defined symbols which will help us find the layout
|
||||||
|
* of trusted RAM
|
||||||
|
******************************************************************************/
|
||||||
|
extern unsigned long __COHERENT_RAM_START__;
|
||||||
|
extern unsigned long __COHERENT_RAM_END__;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next 2 constants identify the extents of the coherent memory region.
|
||||||
|
* These addresses are used by the MMU setup code and therefore they must be
|
||||||
|
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||||
|
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
|
||||||
|
* page-aligned addresses.
|
||||||
|
*/
|
||||||
|
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
|
||||||
|
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||||
|
|
||||||
|
/* Data structure which holds the extents of the trusted RAM for BL1 */
|
||||||
|
static meminfo_t bl1_tzram_layout;
|
||||||
|
|
||||||
|
meminfo_t *bl1_plat_sec_mem_layout(void)
|
||||||
|
{
|
||||||
|
return &bl1_tzram_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Perform any BL1 specific platform actions.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl1_early_platform_setup(void)
|
||||||
|
{
|
||||||
|
const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
|
||||||
|
|
||||||
|
/* Initialize the console to provide early debug support */
|
||||||
|
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
|
||||||
|
|
||||||
|
/* Allow BL1 to see the whole Trusted RAM */
|
||||||
|
bl1_tzram_layout.total_base = TZRAM_BASE;
|
||||||
|
bl1_tzram_layout.total_size = TZRAM_SIZE;
|
||||||
|
|
||||||
|
/* Calculate how much RAM BL1 is using and how much remains free */
|
||||||
|
bl1_tzram_layout.free_base = TZRAM_BASE;
|
||||||
|
bl1_tzram_layout.free_size = TZRAM_SIZE;
|
||||||
|
reserve_mem(&bl1_tzram_layout.free_base,
|
||||||
|
&bl1_tzram_layout.free_size,
|
||||||
|
BL1_RAM_BASE,
|
||||||
|
bl1_size);
|
||||||
|
|
||||||
|
INFO("BL1: 0x%lx - 0x%lx [size = %u]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
|
||||||
|
bl1_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Address of slave 'n' security setting in the NIC-400 address region
|
||||||
|
* control
|
||||||
|
* TODO: Ideally this macro should be moved in a "nic-400.h" header file but
|
||||||
|
* it would be the only thing in there so it's not worth it at the moment.
|
||||||
|
*/
|
||||||
|
#define NIC400_ADDR_CTRL_SECURITY_REG(n) (0x8 + (n) * 4)
|
||||||
|
|
||||||
|
static void init_nic400(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* NIC-400 Access Control Initialization
|
||||||
|
*
|
||||||
|
* Define access privileges by setting each corresponding bit to:
|
||||||
|
* 0 = Secure access only
|
||||||
|
* 1 = Non-secure access allowed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow non-secure access to some SOC regions, excluding UART1, which
|
||||||
|
* remains secure.
|
||||||
|
* Note: This is the NIC-400 device on the SOC
|
||||||
|
*/
|
||||||
|
mmio_write_32(SOC_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_EHCI), ~0);
|
||||||
|
mmio_write_32(SOC_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_TLX_MASTER), ~0);
|
||||||
|
mmio_write_32(SOC_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_USB_OHCI), ~0);
|
||||||
|
mmio_write_32(SOC_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_PL354_SMC), ~0);
|
||||||
|
mmio_write_32(SOC_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_APB4_BRIDGE), ~0);
|
||||||
|
mmio_write_32(SOC_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(SOC_NIC400_BOOTSEC_BRIDGE),
|
||||||
|
~SOC_NIC400_BOOTSEC_BRIDGE_UART1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allow non-secure access to some CSS regions.
|
||||||
|
* Note: This is the NIC-400 device on the CSS
|
||||||
|
*/
|
||||||
|
mmio_write_32(CSS_NIC400_BASE +
|
||||||
|
NIC400_ADDR_CTRL_SECURITY_REG(CSS_NIC400_SLAVE_BOOTSECURE),
|
||||||
|
~0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void init_tzc400(void)
|
||||||
|
{
|
||||||
|
/* Enable all filter units available */
|
||||||
|
mmio_write_32(TZC400_BASE + GATE_KEEPER_OFF, 0x0000000f);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Secure read and write are enabled for region 0, and the background
|
||||||
|
* region (region 0) is enabled for all four filter units
|
||||||
|
*/
|
||||||
|
mmio_write_32(TZC400_BASE + REGION_ATTRIBUTES_OFF, 0xc0000000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable Non-secure read/write accesses for the Soc Devices from the
|
||||||
|
* Non-Secure World
|
||||||
|
*/
|
||||||
|
mmio_write_32(TZC400_BASE + REGION_ID_ACCESS_OFF,
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD0) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_HDLCD1) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_USB) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_DMA330) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_THINLINKS) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_AP) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_GPU) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_SCP) |
|
||||||
|
TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CORESIGHT)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PCIE_SECURE_REG 0x3000
|
||||||
|
#define PCIE_SEC_ACCESS_MASK ((1 << 0) | (1 << 1)) /* REG and MEM access bits */
|
||||||
|
|
||||||
|
static void init_pcie(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* PCIE Root Complex Security settings to enable non-secure
|
||||||
|
* access to config registers.
|
||||||
|
*/
|
||||||
|
mmio_write_32(PCIE_CONTROL_BASE + PCIE_SECURE_REG, PCIE_SEC_ACCESS_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Function which will perform any remaining platform-specific setup that can
|
||||||
|
* occur after the MMU and data cache have been enabled.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl1_platform_setup(void)
|
||||||
|
{
|
||||||
|
init_nic400();
|
||||||
|
init_tzc400();
|
||||||
|
init_pcie();
|
||||||
|
|
||||||
|
/* Initialise the IO layer and register platform IO devices */
|
||||||
|
io_setup();
|
||||||
|
|
||||||
|
/* Enable and initialize the System level generic timer */
|
||||||
|
mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Perform the very early platform specific architecture setup here. At the
|
||||||
|
* moment this only does basic initialization. Later architectural setup
|
||||||
|
* (bl1_arch_setup()) does not do anything platform specific.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl1_plat_arch_setup(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Enable CCI-400 for this cluster. No need
|
||||||
|
* for locks as no other cpu is active at the
|
||||||
|
* moment
|
||||||
|
*/
|
||||||
|
cci_enable_coherency(read_mpidr());
|
||||||
|
|
||||||
|
configure_mmu_el3(bl1_tzram_layout.total_base,
|
||||||
|
bl1_tzram_layout.total_size,
|
||||||
|
TZROM_BASE,
|
||||||
|
TZROM_BASE + TZROM_SIZE,
|
||||||
|
BL1_COHERENT_RAM_BASE,
|
||||||
|
BL1_COHERENT_RAM_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Before calling this function BL2 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL2 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
******************************************************************************/
|
||||||
|
void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
|
||||||
|
entry_point_info_t *bl2_ep)
|
||||||
|
{
|
||||||
|
SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
|
||||||
|
bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
|
||||||
|
}
|
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "juno_private.h"
|
||||||
|
#include "scp_bootloader.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Declarations of linker defined symbols which will help us find the layout
|
||||||
|
* of trusted RAM
|
||||||
|
******************************************************************************/
|
||||||
|
extern unsigned long __RO_START__;
|
||||||
|
extern unsigned long __RO_END__;
|
||||||
|
|
||||||
|
extern unsigned long __COHERENT_RAM_START__;
|
||||||
|
extern unsigned long __COHERENT_RAM_END__;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next 2 constants identify the extents of the code & RO data region.
|
||||||
|
* These addresses are used by the MMU setup code and therefore they must be
|
||||||
|
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||||
|
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
|
||||||
|
*/
|
||||||
|
#define BL2_RO_BASE (unsigned long)(&__RO_START__)
|
||||||
|
#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next 2 constants identify the extents of the coherent memory region.
|
||||||
|
* These addresses are used by the MMU setup code and therefore they must be
|
||||||
|
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||||
|
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
|
||||||
|
* page-aligned addresses.
|
||||||
|
*/
|
||||||
|
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
|
||||||
|
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||||
|
|
||||||
|
/* Data structure which holds the extents of the trusted RAM for BL2 */
|
||||||
|
static meminfo_t bl2_tzram_layout
|
||||||
|
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
|
||||||
|
section("tzfw_coherent_mem")));
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Structure which holds the arguments which need to be passed to BL3-1
|
||||||
|
******************************************************************************/
|
||||||
|
static bl2_to_bl31_params_mem_t bl31_params_mem;
|
||||||
|
|
||||||
|
meminfo_t *bl2_plat_sec_mem_layout(void)
|
||||||
|
{
|
||||||
|
return &bl2_tzram_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function assigns a pointer to the memory that the platform has kept
|
||||||
|
* aside to pass platform specific and trusted firmware related information
|
||||||
|
* to BL31. This memory is allocated by allocating memory to
|
||||||
|
* bl2_to_bl31_params_mem_t structure which is a superset of all the
|
||||||
|
* structure whose information is passed to BL31
|
||||||
|
* NOTE: This function should be called only once and should be done
|
||||||
|
* before generating params to BL31
|
||||||
|
******************************************************************************/
|
||||||
|
bl31_params_t *bl2_plat_get_bl31_params(void)
|
||||||
|
{
|
||||||
|
bl31_params_t *bl2_to_bl31_params;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the memory for all the arguments that needs to
|
||||||
|
* be passed to BL3-1
|
||||||
|
*/
|
||||||
|
memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
|
||||||
|
|
||||||
|
/* Assign memory for TF related information */
|
||||||
|
bl2_to_bl31_params = &bl31_params_mem.bl31_params;
|
||||||
|
SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
|
||||||
|
|
||||||
|
/* Fill BL3-1 related information */
|
||||||
|
bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
|
||||||
|
SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
|
||||||
|
VERSION_1, 0);
|
||||||
|
|
||||||
|
/* Fill BL3-2 related information if it exists */
|
||||||
|
#if BL32_BASE
|
||||||
|
bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
|
||||||
|
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
|
||||||
|
VERSION_1, 0);
|
||||||
|
bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
|
||||||
|
SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
|
||||||
|
VERSION_1, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Fill BL3-3 related information */
|
||||||
|
bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
|
||||||
|
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
|
||||||
|
PARAM_EP, VERSION_1, 0);
|
||||||
|
/* UEFI expects to receive the primary CPU MPID (through x0) */
|
||||||
|
bl2_to_bl31_params->bl33_ep_info->args.arg0 = JUNO_PRIMARY_CPU;
|
||||||
|
|
||||||
|
bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
|
||||||
|
SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
|
||||||
|
VERSION_1, 0);
|
||||||
|
|
||||||
|
return bl2_to_bl31_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function returns a pointer to the shared memory that the platform
|
||||||
|
* has kept to point to entry point information of BL31 to BL2
|
||||||
|
******************************************************************************/
|
||||||
|
struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
bl31_params_mem.bl31_ep_info.args.arg1 = JUNO_BL31_PLAT_PARAM_VAL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return &bl31_params_mem.bl31_ep_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* BL1 has passed the extents of the trusted RAM that should be visible to BL2
|
||||||
|
* in x0. This memory layout is sitting at the base of the free trusted RAM.
|
||||||
|
* Copy it to a safe loaction before its reclaimed by later BL2 functionality.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_early_platform_setup(meminfo_t *mem_layout)
|
||||||
|
{
|
||||||
|
/* Initialize the console to provide early debug support */
|
||||||
|
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
|
||||||
|
|
||||||
|
/* Setup the BL2 memory layout */
|
||||||
|
bl2_tzram_layout = *mem_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Perform platform specific setup, i.e. initialize the IO layer, load BL3-0
|
||||||
|
* image and initialise the memory location to use for passing arguments to
|
||||||
|
* BL3-1.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_platform_setup(void)
|
||||||
|
{
|
||||||
|
/* Initialise the IO layer and register platform IO devices */
|
||||||
|
io_setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush the TF params and the TF plat params */
|
||||||
|
void bl2_plat_flush_bl31_params(void)
|
||||||
|
{
|
||||||
|
flush_dcache_range((unsigned long)&bl31_params_mem,
|
||||||
|
sizeof(bl2_to_bl31_params_mem_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Perform the very early platform specific architectural setup here. At the
|
||||||
|
* moment this is only intializes the mmu in a quick and dirty way.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_arch_setup(void)
|
||||||
|
{
|
||||||
|
configure_mmu_el1(bl2_tzram_layout.total_base,
|
||||||
|
bl2_tzram_layout.total_size,
|
||||||
|
BL2_RO_BASE,
|
||||||
|
BL2_RO_LIMIT,
|
||||||
|
BL2_COHERENT_RAM_BASE,
|
||||||
|
BL2_COHERENT_RAM_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Populate the extents of memory available for loading BL3-0, i.e. anywhere
|
||||||
|
* in trusted RAM as long as it doesn't overwrite BL2.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_get_bl30_meminfo(meminfo_t *bl30_meminfo)
|
||||||
|
{
|
||||||
|
*bl30_meminfo = bl2_tzram_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Transfer BL3-0 from Trusted RAM using the SCP Download protocol.
|
||||||
|
* Return 0 on success, -1 otherwise.
|
||||||
|
******************************************************************************/
|
||||||
|
int bl2_plat_handle_bl30(image_info_t *bl30_image_info)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = scp_bootloader_transfer((void *)bl30_image_info->image_base,
|
||||||
|
bl30_image_info->image_size);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
INFO("BL2: BL3-0 transferred to SCP\n\r");
|
||||||
|
else
|
||||||
|
ERROR("BL2: BL3-0 transfer failure\n\r");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Before calling this function BL31 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL31 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
|
||||||
|
entry_point_info_t *bl31_ep_info)
|
||||||
|
{
|
||||||
|
SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
|
||||||
|
bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
|
||||||
|
DISABLE_ALL_EXCEPTIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Before calling this function BL32 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL32 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
|
||||||
|
entry_point_info_t *bl32_ep_info)
|
||||||
|
{
|
||||||
|
SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
|
||||||
|
/*
|
||||||
|
* The Secure Payload Dispatcher service is responsible for
|
||||||
|
* setting the SPSR prior to entry into the BL32 image.
|
||||||
|
*/
|
||||||
|
bl32_ep_info->spsr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Before calling this function BL33 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL33 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_set_bl33_ep_info(image_info_t *image,
|
||||||
|
entry_point_info_t *bl33_ep_info)
|
||||||
|
{
|
||||||
|
unsigned long el_status;
|
||||||
|
unsigned int mode;
|
||||||
|
|
||||||
|
/* Figure out what mode we enter the non-secure world in */
|
||||||
|
el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
|
||||||
|
el_status &= ID_AA64PFR0_ELX_MASK;
|
||||||
|
|
||||||
|
if (el_status)
|
||||||
|
mode = MODE_EL2;
|
||||||
|
else
|
||||||
|
mode = MODE_EL1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Consider the possibility of specifying the SPSR in
|
||||||
|
* the FIP ToC and allowing the platform to have a say as
|
||||||
|
* well.
|
||||||
|
*/
|
||||||
|
bl33_ep_info->spsr = SPSR_64(mode, MODE_SP_ELX,
|
||||||
|
DISABLE_ALL_EXCEPTIONS);
|
||||||
|
SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Populate the extents of memory available for loading BL3-2
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Populate the extents of memory available for loading BL3-2.
|
||||||
|
*/
|
||||||
|
bl32_meminfo->total_base = BL32_BASE;
|
||||||
|
bl32_meminfo->free_base = BL32_BASE;
|
||||||
|
bl32_meminfo->total_size =
|
||||||
|
(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
|
||||||
|
bl32_meminfo->free_size =
|
||||||
|
(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Populate the extents of memory available for loading BL3-3
|
||||||
|
******************************************************************************/
|
||||||
|
void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
|
||||||
|
{
|
||||||
|
bl33_meminfo->total_base = DRAM_BASE;
|
||||||
|
bl33_meminfo->total_size = DRAM_SIZE;
|
||||||
|
bl33_meminfo->free_base = DRAM_BASE;
|
||||||
|
bl33_meminfo->free_size = DRAM_SIZE;
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <bl31.h>
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <console.h>
|
||||||
|
#include <mmio.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "juno_private.h"
|
||||||
|
#include "mhu.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Declarations of linker defined symbols which will help us find the layout
|
||||||
|
* of trusted RAM
|
||||||
|
******************************************************************************/
|
||||||
|
extern unsigned long __RO_START__;
|
||||||
|
extern unsigned long __RO_END__;
|
||||||
|
|
||||||
|
extern unsigned long __COHERENT_RAM_START__;
|
||||||
|
extern unsigned long __COHERENT_RAM_END__;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next 2 constants identify the extents of the code & RO data region.
|
||||||
|
* These addresses are used by the MMU setup code and therefore they must be
|
||||||
|
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||||
|
* __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
|
||||||
|
*/
|
||||||
|
#define BL31_RO_BASE (unsigned long)(&__RO_START__)
|
||||||
|
#define BL31_RO_LIMIT (unsigned long)(&__RO_END__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next 2 constants identify the extents of the coherent memory region.
|
||||||
|
* These addresses are used by the MMU setup code and therefore they must be
|
||||||
|
* page-aligned. It is the responsibility of the linker script to ensure that
|
||||||
|
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
|
||||||
|
* refer to page-aligned addresses.
|
||||||
|
*/
|
||||||
|
#define BL31_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
|
||||||
|
#define BL31_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Placeholder variables for copying the arguments that have been passed to
|
||||||
|
* BL3-1 from BL2.
|
||||||
|
******************************************************************************/
|
||||||
|
static entry_point_info_t bl32_ep_info;
|
||||||
|
static entry_point_info_t bl33_ep_info;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Return a pointer to the 'entry_point_info' structure of the next image for
|
||||||
|
* the security state specified. BL3-3 corresponds to the non-secure image type
|
||||||
|
* while BL3-2 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)
|
||||||
|
{
|
||||||
|
entry_point_info_t *next_image_info;
|
||||||
|
|
||||||
|
next_image_info = (type == NON_SECURE) ? &bl33_ep_info : &bl32_ep_info;
|
||||||
|
|
||||||
|
/* None of the images on this platform can have 0x0 as the entrypoint */
|
||||||
|
if (next_image_info->pc)
|
||||||
|
return next_image_info;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Perform any BL3-1 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. Also, BL2
|
||||||
|
* has flushed this information to memory, so we are guaranteed to pick up good
|
||||||
|
* data
|
||||||
|
******************************************************************************/
|
||||||
|
void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
||||||
|
void *plat_params_from_bl2)
|
||||||
|
{
|
||||||
|
/* Initialize the console to provide early debug support */
|
||||||
|
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check params passed from BL2 should not be NULL,
|
||||||
|
*/
|
||||||
|
assert(from_bl2 != NULL);
|
||||||
|
assert(from_bl2->h.type == PARAM_BL31);
|
||||||
|
assert(from_bl2->h.version >= VERSION_1);
|
||||||
|
/*
|
||||||
|
* In debug builds, we pass a special value in 'plat_params_from_bl2'
|
||||||
|
* to verify platform parameters from BL2 to BL3-1.
|
||||||
|
* In release builds, it's not used.
|
||||||
|
*/
|
||||||
|
assert(((unsigned long long)plat_params_from_bl2) ==
|
||||||
|
JUNO_BL31_PLAT_PARAM_VAL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy BL3-2 and BL3-3 entry point information.
|
||||||
|
* They are stored in Secure RAM, in BL2's address space.
|
||||||
|
*/
|
||||||
|
bl32_ep_info = *from_bl2->bl32_ep_info;
|
||||||
|
bl33_ep_info = *from_bl2->bl33_ep_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Initialize the MHU and the GIC.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl31_platform_setup(void)
|
||||||
|
{
|
||||||
|
unsigned int reg_val;
|
||||||
|
|
||||||
|
mhu_secure_init();
|
||||||
|
|
||||||
|
/* Initialize the gic cpu and distributor interfaces */
|
||||||
|
gic_setup();
|
||||||
|
|
||||||
|
/* Enable and initialize the System level generic timer */
|
||||||
|
mmio_write_32(SYS_CNTCTL_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);
|
||||||
|
|
||||||
|
/* Allow access to the System counter timer module */
|
||||||
|
reg_val = (1 << CNTACR_RPCT_SHIFT) | (1 << CNTACR_RVCT_SHIFT);
|
||||||
|
reg_val |= (1 << CNTACR_RFRQ_SHIFT) | (1 << CNTACR_RVOFF_SHIFT);
|
||||||
|
reg_val |= (1 << CNTACR_RWVT_SHIFT) | (1 << CNTACR_RWPT_SHIFT);
|
||||||
|
mmio_write_32(SYS_TIMCTL_BASE + CNTACR_BASE(1), reg_val);
|
||||||
|
|
||||||
|
reg_val = (1 << CNTNSAR_NS_SHIFT(1));
|
||||||
|
mmio_write_32(SYS_TIMCTL_BASE + CNTNSAR, reg_val);
|
||||||
|
|
||||||
|
/* Topologies are best known to the platform. */
|
||||||
|
plat_setup_topology();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Perform the very early platform specific architectural setup here. At the
|
||||||
|
* moment this is only intializes the mmu in a quick and dirty way.
|
||||||
|
******************************************************************************/
|
||||||
|
void bl31_plat_arch_setup()
|
||||||
|
{
|
||||||
|
configure_mmu_el3(BL31_RO_BASE,
|
||||||
|
BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE,
|
||||||
|
BL31_RO_BASE,
|
||||||
|
BL31_RO_LIMIT,
|
||||||
|
BL31_COHERENT_RAM_BASE,
|
||||||
|
BL31_COHERENT_RAM_LIMIT);
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cci400.h>
|
||||||
|
#include <gic_v2.h>
|
||||||
|
#include "platform_def.h"
|
||||||
|
#include "../juno_def.h"
|
||||||
|
|
||||||
|
.section .rodata.gic_reg_name, "aS"
|
||||||
|
gic_regs:
|
||||||
|
.asciz "gic_hppir", "gic_ahppir", "gic_ctlr", ""
|
||||||
|
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 macro prints out relevant GIC
|
||||||
|
* registers whenever an unhandled exception is
|
||||||
|
* taken in BL3-1.
|
||||||
|
* Clobbers: x0 - x10, x16, sp
|
||||||
|
* ---------------------------------------------
|
||||||
|
*/
|
||||||
|
.macro plat_print_gic_regs
|
||||||
|
ldr x16, =GICC_BASE
|
||||||
|
/* Load the gic reg list to x6 */
|
||||||
|
adr x6, gic_regs
|
||||||
|
/* Load the gic regs to gp regs used by str_in_crash_buf_print */
|
||||||
|
ldr w8, [x16, #GICC_HPPIR]
|
||||||
|
ldr w9, [x16, #GICC_AHPPIR]
|
||||||
|
ldr w10, [x16, #GICC_CTLR]
|
||||||
|
/* Store to the crash buf and print to console */
|
||||||
|
bl str_in_crash_buf_print
|
||||||
|
|
||||||
|
/* Print the GICD_ISPENDR regs */
|
||||||
|
add x7, x16, #GICD_ISPENDR
|
||||||
|
adr x4, gicd_pend_reg
|
||||||
|
bl asm_print_str
|
||||||
|
2:
|
||||||
|
sub x4, x7, x16
|
||||||
|
cmp x4, #0x280
|
||||||
|
b.eq 1f
|
||||||
|
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 2b
|
||||||
|
1:
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.section .rodata.cci_reg_name, "aS"
|
||||||
|
cci_iface_regs:
|
||||||
|
.asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , ""
|
||||||
|
|
||||||
|
/* ------------------------------------------------
|
||||||
|
* The below macro prints out relevant interconnect
|
||||||
|
* registers whenever an unhandled exception is
|
||||||
|
* taken in BL3-1.
|
||||||
|
* Clobbers: x0 - x9, sp
|
||||||
|
* ------------------------------------------------
|
||||||
|
*/
|
||||||
|
.macro plat_print_interconnect_regs
|
||||||
|
adr x6, cci_iface_regs
|
||||||
|
/* Store in x7 the base address of the first interface */
|
||||||
|
mov_imm x7, (CCI400_BASE + SLAVE_IFACE3_OFFSET)
|
||||||
|
ldr w8, [x7, #SNOOP_CTRL_REG]
|
||||||
|
/* Store in x7 the base address of the second interface */
|
||||||
|
mov_imm x7, (CCI400_BASE + SLAVE_IFACE4_OFFSET)
|
||||||
|
ldr w9, [x7, #SNOOP_CTRL_REG]
|
||||||
|
/* Store to the crash buf and print to console */
|
||||||
|
bl str_in_crash_buf_print
|
||||||
|
.endm
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PLATFORM_DEF_H__
|
||||||
|
#define __PLATFORM_DEF_H__
|
||||||
|
|
||||||
|
#include <arch.h>
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Platform binary types for linking
|
||||||
|
******************************************************************************/
|
||||||
|
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
|
||||||
|
#define PLATFORM_LINKER_ARCH aarch64
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Generic platform constants
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* Size of cacheable stacks */
|
||||||
|
#define PLATFORM_STACK_SIZE 0x800
|
||||||
|
|
||||||
|
#define FIRMWARE_WELCOME_STR "Booting trusted firmware boot loader stage 1\n\r"
|
||||||
|
|
||||||
|
/* Trusted Boot Firmware BL2 */
|
||||||
|
#define BL2_IMAGE_NAME "bl2.bin"
|
||||||
|
|
||||||
|
/* EL3 Runtime Firmware BL3-1 */
|
||||||
|
#define BL31_IMAGE_NAME "bl31.bin"
|
||||||
|
|
||||||
|
/* SCP Firmware BL3-0 */
|
||||||
|
#define BL30_IMAGE_NAME "bl30.bin"
|
||||||
|
|
||||||
|
/* Secure Payload BL3-2 (Trusted OS) */
|
||||||
|
#define BL32_IMAGE_NAME "bl32.bin"
|
||||||
|
|
||||||
|
/* Non-Trusted Firmware BL3-3 */
|
||||||
|
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
|
||||||
|
|
||||||
|
/* Firmware Image Package */
|
||||||
|
#define FIP_IMAGE_NAME "fip.bin"
|
||||||
|
|
||||||
|
#define PLATFORM_CACHE_LINE_SIZE 64
|
||||||
|
#define PLATFORM_CLUSTER_COUNT 2
|
||||||
|
#define PLATFORM_CORE_COUNT 6
|
||||||
|
#define PLATFORM_NUM_AFFS (PLATFORM_CLUSTER_COUNT + \
|
||||||
|
PLATFORM_CORE_COUNT)
|
||||||
|
#define MAX_IO_DEVICES 3
|
||||||
|
#define MAX_IO_HANDLES 4
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Platform memory map related constants
|
||||||
|
******************************************************************************/
|
||||||
|
#define FLASH_BASE 0x08000000
|
||||||
|
#define FLASH_SIZE 0x04000000
|
||||||
|
|
||||||
|
/* Bypass offset from start of NOR flash */
|
||||||
|
#define BL1_ROM_BYPASS_OFFSET 0x03EC0000
|
||||||
|
|
||||||
|
#ifndef TZROM_BASE
|
||||||
|
/* Use the bypass address */
|
||||||
|
#define TZROM_BASE FLASH_BASE + BL1_ROM_BYPASS_OFFSET
|
||||||
|
#endif
|
||||||
|
#define TZROM_SIZE 0x00010000
|
||||||
|
|
||||||
|
#define TZRAM_BASE 0x04001000
|
||||||
|
#define TZRAM_SIZE 0x0003F000
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* BL1 specific defines.
|
||||||
|
* BL1 RW data is relocated from ROM to RAM at runtime so we need 2 base
|
||||||
|
* addresses.
|
||||||
|
******************************************************************************/
|
||||||
|
#define BL1_RO_BASE TZROM_BASE
|
||||||
|
#define BL1_RO_LIMIT (TZROM_BASE + TZROM_SIZE)
|
||||||
|
#define BL1_RW_BASE TZRAM_BASE
|
||||||
|
#define BL1_RW_LIMIT BL31_BASE
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* BL2 specific defines.
|
||||||
|
******************************************************************************/
|
||||||
|
#define BL2_BASE (TZRAM_BASE + TZRAM_SIZE - 0xd000)
|
||||||
|
#define BL2_LIMIT (TZRAM_BASE + TZRAM_SIZE)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Load address of BL3-0 in the Juno port
|
||||||
|
* BL3-0 is loaded to the same place as BL3-1. Once BL3-0 is transferred to the
|
||||||
|
* SCP, it is discarded and BL3-1 is loaded over the top.
|
||||||
|
******************************************************************************/
|
||||||
|
#define BL30_BASE BL31_BASE
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* BL3-1 specific defines.
|
||||||
|
******************************************************************************/
|
||||||
|
#define BL31_BASE (TZRAM_BASE + 0x8000)
|
||||||
|
#define BL31_LIMIT BL32_BASE
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* BL3-2 specific defines.
|
||||||
|
******************************************************************************/
|
||||||
|
#define TSP_SEC_MEM_BASE TZRAM_BASE
|
||||||
|
#define TSP_SEC_MEM_SIZE TZRAM_SIZE
|
||||||
|
#define BL32_BASE (TZRAM_BASE + TZRAM_SIZE - 0x1d000)
|
||||||
|
#define BL32_LIMIT BL2_BASE
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Load address of BL3-3 in the Juno port
|
||||||
|
******************************************************************************/
|
||||||
|
#define NS_IMAGE_OFFSET 0xE0000000
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Platform specific page table and MMU setup constants
|
||||||
|
******************************************************************************/
|
||||||
|
#define ADDR_SPACE_SIZE (1ull << 32)
|
||||||
|
#define MAX_XLAT_TABLES 2
|
||||||
|
#define MAX_MMAP_REGIONS 16
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* ID of the secure physical generic timer interrupt.
|
||||||
|
******************************************************************************/
|
||||||
|
#define IRQ_SEC_PHY_TIMER 29
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CCI-400 related constants
|
||||||
|
******************************************************************************/
|
||||||
|
#define CCI400_BASE 0x2c090000
|
||||||
|
#define CCI400_SL_IFACE_CLUSTER0 4
|
||||||
|
#define CCI400_SL_IFACE_CLUSTER1 3
|
||||||
|
#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \
|
||||||
|
CCI400_SL_IFACE_CLUSTER1 : \
|
||||||
|
CCI400_SL_IFACE_CLUSTER0)
|
||||||
|
/*******************************************************************************
|
||||||
|
* Declarations and constants to access the mailboxes safely. Each mailbox is
|
||||||
|
* aligned on the biggest cache line size in the platform. This is known only
|
||||||
|
* to the platform as it might have a combination of integrated and external
|
||||||
|
* caches. Such alignment ensures that two maiboxes do not sit on the same cache
|
||||||
|
* line at any cache level. They could belong to different cpus/clusters &
|
||||||
|
* get written while being protected by different locks causing corruption of
|
||||||
|
* a valid mailbox address.
|
||||||
|
******************************************************************************/
|
||||||
|
#define CACHE_WRITEBACK_SHIFT 6
|
||||||
|
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
|
||||||
|
|
||||||
|
#endif /* __PLATFORM_DEF_H__ */
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __JUNO_DEF_H__
|
||||||
|
#define __JUNO_DEF_H__
|
||||||
|
|
||||||
|
/* Special value used to verify platform parameters from BL2 to BL3-1 */
|
||||||
|
#define JUNO_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
|
||||||
|
|
||||||
|
#define JUNO_PRIMARY_CPU 0x100
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Juno memory map related constants
|
||||||
|
******************************************************************************/
|
||||||
|
#define MHU_SECURE_BASE 0x04000000
|
||||||
|
#define MHU_SECURE_SIZE 0x00001000
|
||||||
|
|
||||||
|
#define MHU_PAYLOAD_CACHED 0
|
||||||
|
|
||||||
|
#define TRUSTED_MAILBOXES_BASE MHU_SECURE_BASE
|
||||||
|
#define TRUSTED_MAILBOX_SHIFT 4
|
||||||
|
|
||||||
|
#define EMMC_BASE 0x0c000000
|
||||||
|
#define EMMC_SIZE 0x04000000
|
||||||
|
|
||||||
|
#define PSRAM_BASE 0x14000000
|
||||||
|
#define PSRAM_SIZE 0x02000000
|
||||||
|
|
||||||
|
#define IOFPGA_BASE 0x1c000000
|
||||||
|
#define IOFPGA_SIZE 0x03000000
|
||||||
|
|
||||||
|
#define NSROM_BASE 0x1f000000
|
||||||
|
#define NSROM_SIZE 0x00001000
|
||||||
|
|
||||||
|
/* Following covers Columbus Peripherals excluding NSROM and NSRAM */
|
||||||
|
#define DEVICE0_BASE 0x20000000
|
||||||
|
#define DEVICE0_SIZE 0x0e000000
|
||||||
|
#define MHU_BASE 0x2b1f0000
|
||||||
|
|
||||||
|
#define NSRAM_BASE 0x2e000000
|
||||||
|
#define NSRAM_SIZE 0x00008000
|
||||||
|
|
||||||
|
/* Following covers Juno Peripherals and PCIe expansion area */
|
||||||
|
#define DEVICE1_BASE 0x40000000
|
||||||
|
#define DEVICE1_SIZE 0x40000000
|
||||||
|
#define PCIE_CONTROL_BASE 0x7ff20000
|
||||||
|
|
||||||
|
#define DRAM_BASE 0x80000000
|
||||||
|
#define DRAM_SIZE 0x80000000
|
||||||
|
|
||||||
|
/* Memory mapped Generic timer interfaces */
|
||||||
|
#define SYS_CNTCTL_BASE 0x2a430000
|
||||||
|
#define SYS_CNTREAD_BASE 0x2a800000
|
||||||
|
#define SYS_TIMCTL_BASE 0x2a810000
|
||||||
|
|
||||||
|
/* V2M motherboard system registers & offsets */
|
||||||
|
#define VE_SYSREGS_BASE 0x1c010000
|
||||||
|
#define V2M_SYS_LED 0x8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* V2M sysled bit definitions. The values written to this
|
||||||
|
* register are defined in arch.h & runtime_svc.h. Only
|
||||||
|
* used by the primary cpu to diagnose any cold boot issues.
|
||||||
|
*
|
||||||
|
* SYS_LED[0] - Security state (S=0/NS=1)
|
||||||
|
* SYS_LED[2:1] - Exception Level (EL3-EL0)
|
||||||
|
* SYS_LED[7:3] - Exception Class (Sync/Async & origin)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define SYS_LED_SS_SHIFT 0x0
|
||||||
|
#define SYS_LED_EL_SHIFT 0x1
|
||||||
|
#define SYS_LED_EC_SHIFT 0x3
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* GIC-400 & interrupt handling related constants
|
||||||
|
******************************************************************************/
|
||||||
|
#define GICD_BASE 0x2c010000
|
||||||
|
#define GICC_BASE 0x2c02f000
|
||||||
|
#define GICH_BASE 0x2c04f000
|
||||||
|
#define GICV_BASE 0x2c06f000
|
||||||
|
|
||||||
|
#define IRQ_MHU 69
|
||||||
|
#define IRQ_GPU_SMMU_0 71
|
||||||
|
#define IRQ_GPU_SMMU_1 73
|
||||||
|
#define IRQ_ETR_SMMU 75
|
||||||
|
#define IRQ_TZC400 80
|
||||||
|
#define IRQ_TZ_WDOG 86
|
||||||
|
|
||||||
|
#define IRQ_SEC_SGI_0 8
|
||||||
|
#define IRQ_SEC_SGI_1 9
|
||||||
|
#define IRQ_SEC_SGI_2 10
|
||||||
|
#define IRQ_SEC_SGI_3 11
|
||||||
|
#define IRQ_SEC_SGI_4 12
|
||||||
|
#define IRQ_SEC_SGI_5 13
|
||||||
|
#define IRQ_SEC_SGI_6 14
|
||||||
|
#define IRQ_SEC_SGI_7 15
|
||||||
|
#define IRQ_SEC_SGI_8 16
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* PL011 related constants
|
||||||
|
******************************************************************************/
|
||||||
|
/* FPGA UART0 */
|
||||||
|
#define PL011_UART0_BASE 0x1c090000
|
||||||
|
/* FPGA UART1 */
|
||||||
|
#define PL011_UART1_BASE 0x1c0a0000
|
||||||
|
/* SoC UART0 */
|
||||||
|
#define PL011_UART2_BASE 0x7ff80000
|
||||||
|
/* SoC UART1 */
|
||||||
|
#define PL011_UART3_BASE 0x7ff70000
|
||||||
|
|
||||||
|
#define PL011_BAUDRATE 115200
|
||||||
|
|
||||||
|
#define PL011_UART0_CLK_IN_HZ 24000000
|
||||||
|
#define PL011_UART1_CLK_IN_HZ 24000000
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* NIC-400 related constants
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* CSS NIC-400 Global Programmers View (GPV) */
|
||||||
|
#define CSS_NIC400_BASE 0x2a000000
|
||||||
|
|
||||||
|
/* The slave_bootsecure controls access to GPU, DMC and CS. */
|
||||||
|
#define CSS_NIC400_SLAVE_BOOTSECURE 8
|
||||||
|
|
||||||
|
/* SoC NIC-400 Global Programmers View (GPV) */
|
||||||
|
#define SOC_NIC400_BASE 0x7fd00000
|
||||||
|
|
||||||
|
#define SOC_NIC400_USB_EHCI 0
|
||||||
|
#define SOC_NIC400_TLX_MASTER 1
|
||||||
|
#define SOC_NIC400_USB_OHCI 2
|
||||||
|
#define SOC_NIC400_PL354_SMC 3
|
||||||
|
/*
|
||||||
|
* The apb4_bridge controls access to:
|
||||||
|
* - the PCIe configuration registers
|
||||||
|
* - the MMU units for USB, HDLCD and DMA
|
||||||
|
*/
|
||||||
|
#define SOC_NIC400_APB4_BRIDGE 4
|
||||||
|
/*
|
||||||
|
* The bootsec_bridge controls access to a bunch of peripherals, e.g. the UARTs.
|
||||||
|
*/
|
||||||
|
#define SOC_NIC400_BOOTSEC_BRIDGE 5
|
||||||
|
#define SOC_NIC400_BOOTSEC_BRIDGE_UART1 (1 << 12)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* TZC-400 related constants
|
||||||
|
******************************************************************************/
|
||||||
|
#define TZC400_BASE 0x2a4a0000
|
||||||
|
|
||||||
|
#define TZC400_NSAID_CCI400 0 /* Note: Same as default NSAID!! */
|
||||||
|
#define TZC400_NSAID_PCIE 1
|
||||||
|
#define TZC400_NSAID_HDLCD0 2
|
||||||
|
#define TZC400_NSAID_HDLCD1 3
|
||||||
|
#define TZC400_NSAID_USB 4
|
||||||
|
#define TZC400_NSAID_DMA330 5
|
||||||
|
#define TZC400_NSAID_THINLINKS 6
|
||||||
|
#define TZC400_NSAID_AP 9
|
||||||
|
#define TZC400_NSAID_GPU 10
|
||||||
|
#define TZC400_NSAID_SCP 11
|
||||||
|
#define TZC400_NSAID_CORESIGHT 12
|
||||||
|
|
||||||
|
#endif /* __JUNO_DEF_H__ */
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __JUNO_PRIVATE_H__
|
||||||
|
#define __JUNO_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Forward declarations
|
||||||
|
******************************************************************************/
|
||||||
|
struct plat_pm_ops;
|
||||||
|
struct meminfo;
|
||||||
|
struct bl31_params;
|
||||||
|
struct image_info;
|
||||||
|
struct entry_point_info;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This structure represents the superset of information that is passed to
|
||||||
|
* BL3-1 e.g. while passing control to it from BL2 which is bl31_params
|
||||||
|
* and other platform specific params
|
||||||
|
******************************************************************************/
|
||||||
|
typedef struct bl2_to_bl31_params_mem {
|
||||||
|
struct bl31_params bl31_params;
|
||||||
|
struct image_info bl31_image_info;
|
||||||
|
struct image_info bl32_image_info;
|
||||||
|
struct image_info bl33_image_info;
|
||||||
|
struct entry_point_info bl33_ep_info;
|
||||||
|
struct entry_point_info bl32_ep_info;
|
||||||
|
struct entry_point_info bl31_ep_info;
|
||||||
|
} bl2_to_bl31_params_mem_t;
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Function and variable prototypes
|
||||||
|
******************************************************************************/
|
||||||
|
void bl1_plat_arch_setup(void);
|
||||||
|
void bl2_plat_arch_setup(void);
|
||||||
|
void bl31_plat_arch_setup(void);
|
||||||
|
int platform_setup_pm(const struct plat_pm_ops **plat_ops);
|
||||||
|
unsigned int platform_get_core_pos(unsigned long mpidr);
|
||||||
|
void configure_mmu_el1(unsigned long total_base,
|
||||||
|
unsigned long total_size,
|
||||||
|
unsigned long ro_start,
|
||||||
|
unsigned long ro_limit,
|
||||||
|
unsigned long coh_start,
|
||||||
|
unsigned long coh_limit);
|
||||||
|
void configure_mmu_el3(unsigned long total_base,
|
||||||
|
unsigned long total_size,
|
||||||
|
unsigned long ro_start,
|
||||||
|
unsigned long ro_limit,
|
||||||
|
unsigned long coh_start,
|
||||||
|
unsigned long coh_limit);
|
||||||
|
void plat_report_exception(unsigned long type);
|
||||||
|
unsigned long plat_get_ns_image_entrypoint(void);
|
||||||
|
unsigned long platform_get_stack(unsigned long mpidr);
|
||||||
|
uint64_t plat_get_syscnt_freq(void);
|
||||||
|
|
||||||
|
/* Declarations for plat_gic.c */
|
||||||
|
uint32_t ic_get_pending_interrupt_id(void);
|
||||||
|
uint32_t ic_get_pending_interrupt_type(void);
|
||||||
|
uint32_t ic_acknowledge_interrupt(void);
|
||||||
|
uint32_t ic_get_interrupt_type(uint32_t id);
|
||||||
|
void ic_end_of_interrupt(uint32_t id);
|
||||||
|
void gic_cpuif_deactivate(unsigned int gicc_base);
|
||||||
|
void gic_cpuif_setup(unsigned int gicc_base);
|
||||||
|
void gic_pcpu_distif_setup(unsigned int gicd_base);
|
||||||
|
void gic_setup(void);
|
||||||
|
uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state);
|
||||||
|
|
||||||
|
/* Declarations for plat_topology.c */
|
||||||
|
int plat_setup_topology(void);
|
||||||
|
int plat_get_max_afflvl(void);
|
||||||
|
unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr);
|
||||||
|
unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr);
|
||||||
|
|
||||||
|
/* Declarations for plat_io_storage.c */
|
||||||
|
void io_setup(void);
|
||||||
|
int plat_get_image_source(const char *image_name,
|
||||||
|
uintptr_t *dev_handle,
|
||||||
|
uintptr_t *image_spec);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Before calling this function BL2 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL2 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
*/
|
||||||
|
void bl1_plat_set_bl2_ep_info(struct image_info *image,
|
||||||
|
struct entry_point_info *ep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Before calling this function BL3-1 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL3-1 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
*/
|
||||||
|
void bl2_plat_set_bl31_ep_info(struct image_info *image,
|
||||||
|
struct entry_point_info *ep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Before calling this function BL3-2 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL3-2 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
*/
|
||||||
|
void bl2_plat_set_bl32_ep_info(struct image_info *image,
|
||||||
|
struct entry_point_info *ep);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Before calling this function BL3-3 is loaded in memory and its entrypoint
|
||||||
|
* is set by load_image. This is a placeholder for the platform to change
|
||||||
|
* the entrypoint of BL3-3 and set SPSR and security state.
|
||||||
|
* On Juno we are only setting the security state, entrypoint
|
||||||
|
*/
|
||||||
|
void bl2_plat_set_bl33_ep_info(struct image_info *image,
|
||||||
|
struct entry_point_info *ep);
|
||||||
|
|
||||||
|
/* Gets the memory layout for BL3-2 */
|
||||||
|
void bl2_plat_get_bl32_meminfo(struct meminfo *mem_info);
|
||||||
|
|
||||||
|
/* Gets the memory layout for BL3-3 */
|
||||||
|
void bl2_plat_get_bl33_meminfo(struct meminfo *mem_info);
|
||||||
|
|
||||||
|
#endif /* __JUNO_PRIVATE_H__ */
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <bakery_lock.h>
|
||||||
|
#include <mmio.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "mhu.h"
|
||||||
|
|
||||||
|
/* SCP MHU secure channel registers */
|
||||||
|
#define SCP_INTR_S_STAT 0x200
|
||||||
|
#define SCP_INTR_S_SET 0x208
|
||||||
|
#define SCP_INTR_S_CLEAR 0x210
|
||||||
|
|
||||||
|
/* CPU MHU secure channel registers */
|
||||||
|
#define CPU_INTR_S_STAT 0x300
|
||||||
|
#define CPU_INTR_S_SET 0x308
|
||||||
|
#define CPU_INTR_S_CLEAR 0x310
|
||||||
|
|
||||||
|
|
||||||
|
static bakery_lock_t mhu_secure_lock __attribute__ ((section("tzfw_coherent_mem")));
|
||||||
|
|
||||||
|
|
||||||
|
void mhu_secure_message_start(void)
|
||||||
|
{
|
||||||
|
bakery_lock_get(&mhu_secure_lock);
|
||||||
|
|
||||||
|
/* Make sure any previous command has finished */
|
||||||
|
while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mhu_secure_message_send(uint32_t command)
|
||||||
|
{
|
||||||
|
/* Send command to SCP and wait for it to pick it up */
|
||||||
|
mmio_write_32(MHU_BASE + CPU_INTR_S_SET, command);
|
||||||
|
while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) != 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mhu_secure_message_wait(void)
|
||||||
|
{
|
||||||
|
/* Wait for response from SCP */
|
||||||
|
uint32_t response;
|
||||||
|
while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT)))
|
||||||
|
;
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mhu_secure_message_end(void)
|
||||||
|
{
|
||||||
|
/* Clear any response we got by writing all ones to the CLEAR register */
|
||||||
|
mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 0xffffffffu);
|
||||||
|
|
||||||
|
bakery_lock_release(&mhu_secure_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mhu_secure_init(void)
|
||||||
|
{
|
||||||
|
bakery_lock_init(&mhu_secure_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the CPU's INTR register to make sure we don't see a stale
|
||||||
|
* or garbage value and think it's a message we've already sent.
|
||||||
|
*/
|
||||||
|
mmio_write_32(MHU_BASE + CPU_INTR_S_CLEAR, 0xffffffffu);
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MHU_H__
|
||||||
|
#define __MHU_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void mhu_secure_message_start(void);
|
||||||
|
extern void mhu_secure_message_send(uint32_t command);
|
||||||
|
extern uint32_t mhu_secure_message_wait(void);
|
||||||
|
extern void mhu_secure_message_end(void);
|
||||||
|
|
||||||
|
extern void mhu_secure_init(void);
|
||||||
|
|
||||||
|
#endif /* __MHU_H__ */
|
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <bl_common.h>
|
||||||
|
#include <gic_v2.h>
|
||||||
|
#include <interrupt_mgmt.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "juno_private.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Value used to initialise Non-Secure irq priorities four at a time */
|
||||||
|
#define DEFAULT_NS_PRIORITY_X4 \
|
||||||
|
(GIC_HIGHEST_NS_PRIORITY | \
|
||||||
|
(GIC_HIGHEST_NS_PRIORITY << 8) | \
|
||||||
|
(GIC_HIGHEST_NS_PRIORITY << 16) | \
|
||||||
|
(GIC_HIGHEST_NS_PRIORITY << 24))
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Enable secure interrupts and use FIQs to route them. Disable legacy bypass
|
||||||
|
* and set the priority mask register to allow all interrupts to trickle in.
|
||||||
|
******************************************************************************/
|
||||||
|
void gic_cpuif_setup(unsigned int gicc_base)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
gicc_write_pmr(gicc_base, GIC_PRI_MASK);
|
||||||
|
|
||||||
|
val = ENABLE_GRP0 | FIQ_EN;
|
||||||
|
val |= FIQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP0;
|
||||||
|
val |= FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
|
||||||
|
gicc_write_ctlr(gicc_base, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Place the cpu interface in a state where it can never make a cpu exit wfi as
|
||||||
|
* as result of an asserted interrupt. This is critical for powering down a cpu
|
||||||
|
******************************************************************************/
|
||||||
|
void gic_cpuif_deactivate(unsigned int gicc_base)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
/* Disable secure, non-secure interrupts and disable their bypass */
|
||||||
|
val = gicc_read_ctlr(gicc_base);
|
||||||
|
val &= ~(ENABLE_GRP0 | ENABLE_GRP1);
|
||||||
|
val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0;
|
||||||
|
val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1;
|
||||||
|
gicc_write_ctlr(gicc_base, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gic_set_secure(unsigned int gicd_base, unsigned id)
|
||||||
|
{
|
||||||
|
/* Set interrupt as Group 0 */
|
||||||
|
gicd_clr_igroupr(gicd_base, id);
|
||||||
|
|
||||||
|
/* Set priority to max */
|
||||||
|
gicd_set_ipriorityr(gicd_base, id, GIC_HIGHEST_SEC_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Per cpu gic distributor setup which will be done by all cpus after a cold
|
||||||
|
* boot/hotplug. This marks out the secure interrupts & enables them.
|
||||||
|
******************************************************************************/
|
||||||
|
void gic_pcpu_distif_setup(unsigned int gicd_base)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Mark all 32 PPI interrupts as Group 1 (non-secure) */
|
||||||
|
mmio_write_32(gicd_base + GICD_IGROUPR, 0xffffffffu);
|
||||||
|
|
||||||
|
/* Setup PPI priorities doing four at a time */
|
||||||
|
for (i = 0; i < 32; i += 4)
|
||||||
|
mmio_write_32(gicd_base + GICD_IPRIORITYR + i, DEFAULT_NS_PRIORITY_X4);
|
||||||
|
|
||||||
|
/* Configure those PPIs we want as secure, and enable them. */
|
||||||
|
static const char sec_irq[] = {
|
||||||
|
IRQ_SEC_PHY_TIMER,
|
||||||
|
IRQ_SEC_SGI_0,
|
||||||
|
IRQ_SEC_SGI_1,
|
||||||
|
IRQ_SEC_SGI_2,
|
||||||
|
IRQ_SEC_SGI_3,
|
||||||
|
IRQ_SEC_SGI_4,
|
||||||
|
IRQ_SEC_SGI_5,
|
||||||
|
IRQ_SEC_SGI_6,
|
||||||
|
IRQ_SEC_SGI_7
|
||||||
|
};
|
||||||
|
for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++) {
|
||||||
|
gic_set_secure(gicd_base, sec_irq[i]);
|
||||||
|
gicd_set_isenabler(gicd_base, sec_irq[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global gic distributor setup which will be done by the primary cpu after a
|
||||||
|
* cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It
|
||||||
|
* then enables the secure GIC distributor interface.
|
||||||
|
******************************************************************************/
|
||||||
|
static void gic_distif_setup(unsigned int gicd_base)
|
||||||
|
{
|
||||||
|
unsigned int i, ctlr;
|
||||||
|
const unsigned int ITLinesNumber =
|
||||||
|
gicd_read_typer(gicd_base) & IT_LINES_NO_MASK;
|
||||||
|
|
||||||
|
/* Disable the distributor before going further */
|
||||||
|
ctlr = gicd_read_ctlr(gicd_base);
|
||||||
|
ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
|
||||||
|
gicd_write_ctlr(gicd_base, ctlr);
|
||||||
|
|
||||||
|
/* Mark all lines of SPIs as Group 1 (non-secure) */
|
||||||
|
for (i = 0; i < ITLinesNumber; i++)
|
||||||
|
mmio_write_32(gicd_base + GICD_IGROUPR + 4 + i * 4, 0xffffffffu);
|
||||||
|
|
||||||
|
/* Setup SPI priorities doing four at a time */
|
||||||
|
for (i = 0; i < ITLinesNumber * 32; i += 4)
|
||||||
|
mmio_write_32(gicd_base + GICD_IPRIORITYR + 32 + i, DEFAULT_NS_PRIORITY_X4);
|
||||||
|
|
||||||
|
/* Configure the SPIs we want as secure */
|
||||||
|
static const char sec_irq[] = {
|
||||||
|
IRQ_MHU,
|
||||||
|
IRQ_GPU_SMMU_0,
|
||||||
|
IRQ_GPU_SMMU_1,
|
||||||
|
IRQ_ETR_SMMU,
|
||||||
|
IRQ_TZC400,
|
||||||
|
IRQ_TZ_WDOG
|
||||||
|
};
|
||||||
|
for (i = 0; i < sizeof(sec_irq) / sizeof(sec_irq[0]); i++)
|
||||||
|
gic_set_secure(gicd_base, sec_irq[i]);
|
||||||
|
|
||||||
|
/* Route watchdog interrupt to this CPU and enable it. */
|
||||||
|
gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG,
|
||||||
|
platform_get_core_pos(read_mpidr()));
|
||||||
|
gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG);
|
||||||
|
|
||||||
|
/* Now setup the PPIs */
|
||||||
|
gic_pcpu_distif_setup(gicd_base);
|
||||||
|
|
||||||
|
/* Enable Group 0 (secure) interrupts */
|
||||||
|
gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_setup(void)
|
||||||
|
{
|
||||||
|
gic_cpuif_setup(GICC_BASE);
|
||||||
|
gic_distif_setup(GICD_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* An ARM processor signals interrupt exceptions through the IRQ and FIQ pins.
|
||||||
|
* The interrupt controller knows which pin/line it uses to signal a type of
|
||||||
|
* interrupt. The platform knows which interrupt controller type is being used
|
||||||
|
* in a particular security state e.g. with an ARM GIC, normal world could use
|
||||||
|
* the GICv2 features while the secure world could use GICv3 features and vice
|
||||||
|
* versa.
|
||||||
|
* This function is exported by the platform to let the interrupt management
|
||||||
|
* framework determine for a type of interrupt and security state, which line
|
||||||
|
* should be used in the SCR_EL3 to control its routing to EL3. The interrupt
|
||||||
|
* line is represented as the bit position of the IRQ or FIQ bit in the SCR_EL3.
|
||||||
|
******************************************************************************/
|
||||||
|
uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
|
||||||
|
{
|
||||||
|
assert(type == INTR_TYPE_S_EL1 ||
|
||||||
|
type == INTR_TYPE_EL3 ||
|
||||||
|
type == INTR_TYPE_NS);
|
||||||
|
|
||||||
|
assert(sec_state_is_valid(security_state));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We ignore the security state parameter because Juno is GICv2 only
|
||||||
|
* so both normal and secure worlds are using ARM GICv2.
|
||||||
|
*/
|
||||||
|
return gicv2_interrupt_type_to_line(GICC_BASE, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function returns the type of the highest priority pending interrupt at
|
||||||
|
* the GIC cpu interface. INTR_TYPE_INVAL is returned when there is no
|
||||||
|
* interrupt pending.
|
||||||
|
******************************************************************************/
|
||||||
|
uint32_t plat_ic_get_pending_interrupt_type(void)
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
id = gicc_read_hppir(GICC_BASE);
|
||||||
|
|
||||||
|
/* Assume that all secure interrupts are S-EL1 interrupts */
|
||||||
|
if (id < 1022)
|
||||||
|
return INTR_TYPE_S_EL1;
|
||||||
|
|
||||||
|
if (id == GIC_SPURIOUS_INTERRUPT)
|
||||||
|
return INTR_TYPE_INVAL;
|
||||||
|
|
||||||
|
return INTR_TYPE_NS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function returns the id of the highest priority pending interrupt at
|
||||||
|
* the GIC cpu interface. INTR_ID_UNAVAILABLE is returned when there is no
|
||||||
|
* interrupt pending.
|
||||||
|
******************************************************************************/
|
||||||
|
uint32_t plat_ic_get_pending_interrupt_id(void)
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
id = gicc_read_hppir(GICC_BASE);
|
||||||
|
|
||||||
|
if (id < 1022)
|
||||||
|
return id;
|
||||||
|
|
||||||
|
if (id == 1023)
|
||||||
|
return INTR_ID_UNAVAILABLE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find out which non-secure interrupt it is under the assumption that
|
||||||
|
* the GICC_CTLR.AckCtl bit is 0.
|
||||||
|
*/
|
||||||
|
return gicc_read_ahppir(GICC_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This functions reads the GIC cpu interface Interrupt Acknowledge register
|
||||||
|
* to start handling the pending interrupt. It returns the contents of the IAR.
|
||||||
|
******************************************************************************/
|
||||||
|
uint32_t plat_ic_acknowledge_interrupt(void)
|
||||||
|
{
|
||||||
|
return gicc_read_IAR(GICC_BASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This functions writes the GIC cpu interface End Of Interrupt register with
|
||||||
|
* the passed value to finish handling the active interrupt
|
||||||
|
******************************************************************************/
|
||||||
|
void plat_ic_end_of_interrupt(uint32_t id)
|
||||||
|
{
|
||||||
|
gicc_write_EOIR(GICC_BASE, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function returns the type of the interrupt id depending upon the group
|
||||||
|
* this interrupt has been configured under by the interrupt controller i.e.
|
||||||
|
* group0 or group1.
|
||||||
|
******************************************************************************/
|
||||||
|
uint32_t plat_ic_get_interrupt_type(uint32_t id)
|
||||||
|
{
|
||||||
|
uint32_t group;
|
||||||
|
|
||||||
|
group = gicd_get_igroupr(GICD_BASE, id);
|
||||||
|
|
||||||
|
/* Assume that all secure interrupts are S-EL1 interrupts */
|
||||||
|
if (group == GRP0)
|
||||||
|
return INTR_TYPE_S_EL1;
|
||||||
|
else
|
||||||
|
return INTR_TYPE_NS;
|
||||||
|
}
|
|
@ -0,0 +1,202 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <io_storage.h>
|
||||||
|
#include <io_driver.h>
|
||||||
|
#include <semihosting.h> /* For FOPEN_MODE_... */
|
||||||
|
#include <io_fip.h>
|
||||||
|
#include <io_memmap.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
|
||||||
|
/* IO devices */
|
||||||
|
static io_plat_data_t io_data;
|
||||||
|
static const io_dev_connector_t *fip_dev_con;
|
||||||
|
static uintptr_t fip_dev_spec;
|
||||||
|
static uintptr_t fip_dev_handle;
|
||||||
|
static const io_dev_connector_t *memmap_dev_con;
|
||||||
|
static uintptr_t memmap_dev_spec;
|
||||||
|
static uintptr_t memmap_init_params;
|
||||||
|
static uintptr_t memmap_dev_handle;
|
||||||
|
|
||||||
|
static const io_block_spec_t fip_block_spec = {
|
||||||
|
.offset = FLASH_BASE,
|
||||||
|
.length = FLASH_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const io_file_spec_t bl2_file_spec = {
|
||||||
|
.path = BL2_IMAGE_NAME,
|
||||||
|
.mode = FOPEN_MODE_RB
|
||||||
|
};
|
||||||
|
|
||||||
|
static const io_file_spec_t bl30_file_spec = {
|
||||||
|
.path = BL30_IMAGE_NAME,
|
||||||
|
.mode = FOPEN_MODE_RB
|
||||||
|
};
|
||||||
|
|
||||||
|
static const io_file_spec_t bl31_file_spec = {
|
||||||
|
.path = BL31_IMAGE_NAME,
|
||||||
|
.mode = FOPEN_MODE_RB
|
||||||
|
};
|
||||||
|
|
||||||
|
static const io_file_spec_t bl33_file_spec = {
|
||||||
|
.path = BL33_IMAGE_NAME,
|
||||||
|
.mode = FOPEN_MODE_RB
|
||||||
|
};
|
||||||
|
|
||||||
|
static int open_fip(const uintptr_t spec);
|
||||||
|
static int open_memmap(const uintptr_t spec);
|
||||||
|
|
||||||
|
struct plat_io_policy {
|
||||||
|
const char *image_name;
|
||||||
|
uintptr_t *dev_handle;
|
||||||
|
uintptr_t image_spec;
|
||||||
|
int (*check)(const uintptr_t spec);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct plat_io_policy policies[] = {
|
||||||
|
{
|
||||||
|
FIP_IMAGE_NAME,
|
||||||
|
&memmap_dev_handle,
|
||||||
|
(uintptr_t)&fip_block_spec,
|
||||||
|
open_memmap
|
||||||
|
}, {
|
||||||
|
BL2_IMAGE_NAME,
|
||||||
|
&fip_dev_handle,
|
||||||
|
(uintptr_t)&bl2_file_spec,
|
||||||
|
open_fip
|
||||||
|
}, {
|
||||||
|
BL30_IMAGE_NAME,
|
||||||
|
&fip_dev_handle,
|
||||||
|
(uintptr_t)&bl30_file_spec,
|
||||||
|
open_fip
|
||||||
|
}, {
|
||||||
|
BL31_IMAGE_NAME,
|
||||||
|
&fip_dev_handle,
|
||||||
|
(uintptr_t)&bl31_file_spec,
|
||||||
|
open_fip
|
||||||
|
}, {
|
||||||
|
BL33_IMAGE_NAME,
|
||||||
|
&fip_dev_handle,
|
||||||
|
(uintptr_t)&bl33_file_spec,
|
||||||
|
open_fip
|
||||||
|
}, {
|
||||||
|
0, 0, 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int open_fip(const uintptr_t spec)
|
||||||
|
{
|
||||||
|
int result = IO_FAIL;
|
||||||
|
|
||||||
|
/* See if a Firmware Image Package is available */
|
||||||
|
result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_NAME);
|
||||||
|
if (result == IO_SUCCESS) {
|
||||||
|
INFO("Using FIP\n");
|
||||||
|
/*TODO: Check image defined in spec is present in FIP. */
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int open_memmap(const uintptr_t spec)
|
||||||
|
{
|
||||||
|
int result = IO_FAIL;
|
||||||
|
uintptr_t local_image_handle;
|
||||||
|
|
||||||
|
result = io_dev_init(memmap_dev_handle, memmap_init_params);
|
||||||
|
if (result == IO_SUCCESS) {
|
||||||
|
result = io_open(memmap_dev_handle, spec, &local_image_handle);
|
||||||
|
if (result == IO_SUCCESS) {
|
||||||
|
/* INFO("Using Memmap IO\n"); */
|
||||||
|
io_close(local_image_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void io_setup(void)
|
||||||
|
{
|
||||||
|
int io_result = IO_FAIL;
|
||||||
|
|
||||||
|
/* Initialise the IO layer */
|
||||||
|
io_init(&io_data);
|
||||||
|
|
||||||
|
/* Register the IO devices on this platform */
|
||||||
|
io_result = register_io_dev_fip(&fip_dev_con);
|
||||||
|
assert(io_result == IO_SUCCESS);
|
||||||
|
|
||||||
|
io_result = register_io_dev_memmap(&memmap_dev_con);
|
||||||
|
assert(io_result == IO_SUCCESS);
|
||||||
|
|
||||||
|
/* Open connections to devices and cache the handles */
|
||||||
|
io_result = io_dev_open(fip_dev_con, fip_dev_spec, &fip_dev_handle);
|
||||||
|
assert(io_result == IO_SUCCESS);
|
||||||
|
|
||||||
|
io_result = io_dev_open(memmap_dev_con, memmap_dev_spec,
|
||||||
|
&memmap_dev_handle);
|
||||||
|
assert(io_result == IO_SUCCESS);
|
||||||
|
|
||||||
|
/* Ignore improbable errors in release builds */
|
||||||
|
(void)io_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return an IO device handle and specification which can be used to access
|
||||||
|
* an image. Use this to enforce platform load policy */
|
||||||
|
int plat_get_image_source(const char *image_name, uintptr_t *dev_handle,
|
||||||
|
uintptr_t *image_spec)
|
||||||
|
{
|
||||||
|
int result = IO_FAIL;
|
||||||
|
const struct plat_io_policy *policy;
|
||||||
|
|
||||||
|
if ((image_name != NULL) && (dev_handle != NULL) &&
|
||||||
|
(image_spec != NULL)) {
|
||||||
|
policy = policies;
|
||||||
|
while (policy->image_name != NULL) {
|
||||||
|
if (strcmp(policy->image_name, image_name) == 0) {
|
||||||
|
result = policy->check(policy->image_spec);
|
||||||
|
if (result == IO_SUCCESS) {
|
||||||
|
*image_spec = policy->image_spec;
|
||||||
|
*dev_handle = *(policy->dev_handle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
policy++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = IO_FAIL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <cci400.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <psci.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "juno_private.h"
|
||||||
|
#include "scpi.h"
|
||||||
|
|
||||||
|
int pm_on(unsigned long mpidr,
|
||||||
|
unsigned long sec_entrypoint,
|
||||||
|
unsigned long ns_entrypoint,
|
||||||
|
unsigned int afflvl,
|
||||||
|
unsigned int state)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* SCP takes care of powering up higher affinity levels so we
|
||||||
|
* only need to care about level 0
|
||||||
|
*/
|
||||||
|
if (afflvl != MPIDR_AFFLVL0)
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup mailbox with address for CPU entrypoint when it next powers up
|
||||||
|
*/
|
||||||
|
unsigned long *mbox = (unsigned long *)(unsigned long)(
|
||||||
|
TRUSTED_MAILBOXES_BASE +
|
||||||
|
(platform_get_core_pos(mpidr) << TRUSTED_MAILBOX_SHIFT)
|
||||||
|
);
|
||||||
|
*mbox = sec_entrypoint;
|
||||||
|
flush_dcache_range((unsigned long)mbox, sizeof(*mbox));
|
||||||
|
|
||||||
|
scpi_set_css_power_state(mpidr, scpi_power_on, scpi_power_on,
|
||||||
|
scpi_power_on);
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pm_on_finish(unsigned long mpidr, unsigned int afflvl, unsigned int state)
|
||||||
|
{
|
||||||
|
switch (afflvl) {
|
||||||
|
|
||||||
|
case MPIDR_AFFLVL1:
|
||||||
|
/* Enable coherency if this cluster was off */
|
||||||
|
if (state == PSCI_STATE_OFF)
|
||||||
|
cci_enable_coherency(mpidr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPIDR_AFFLVL0:
|
||||||
|
/*
|
||||||
|
* Ignore the state passed for a cpu. It could only have
|
||||||
|
* been off if we are here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Turn on intra-cluster coherency. */
|
||||||
|
write_cpuectlr(read_cpuectlr() | CPUECTLR_SMP_BIT);
|
||||||
|
|
||||||
|
/* Enable the gic cpu interface */
|
||||||
|
gic_cpuif_setup(GICC_BASE);
|
||||||
|
/* Juno todo: Is this setup only needed after a cold boot? */
|
||||||
|
gic_pcpu_distif_setup(GICD_BASE);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Handler called when an affinity instance is about to be turned off. The
|
||||||
|
* level and mpidr determine the affinity instance. The 'state' arg. allows the
|
||||||
|
* platform to decide whether the cluster is being turned off and take apt
|
||||||
|
* actions.
|
||||||
|
*
|
||||||
|
* CAUTION: There is no guarantee that caches will remain turned on across calls
|
||||||
|
* to this function as each affinity level is dealt with. So do not write & read
|
||||||
|
* global variables across calls. It will be wise to do flush a write to the
|
||||||
|
* global to prevent unpredictable results.
|
||||||
|
******************************************************************************/
|
||||||
|
int pm_off(unsigned long mpidr, unsigned int afflvl, unsigned int state)
|
||||||
|
{
|
||||||
|
/* We're only interested in power off states */
|
||||||
|
if (state != PSCI_STATE_OFF)
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
|
||||||
|
switch (afflvl) {
|
||||||
|
case MPIDR_AFFLVL1:
|
||||||
|
/* Cluster is to be turned off, so disable coherency */
|
||||||
|
cci_disable_coherency(mpidr);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPIDR_AFFLVL0:
|
||||||
|
/* Turn off intra-cluster coherency */
|
||||||
|
write_cpuectlr(read_cpuectlr() & ~CPUECTLR_SMP_BIT);
|
||||||
|
|
||||||
|
/* Prevent interrupts from spuriously waking up this cpu */
|
||||||
|
gic_cpuif_deactivate(GICC_BASE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ask SCP to power down CPU.
|
||||||
|
*
|
||||||
|
* Note, we also ask for cluster power down as well because we
|
||||||
|
* know the SCP will only actually do that if this is the last
|
||||||
|
* CPU going down, and also, that final power down won't happen
|
||||||
|
* until this CPU executes the WFI instruction after the PSCI
|
||||||
|
* framework has done it's thing.
|
||||||
|
*/
|
||||||
|
scpi_set_css_power_state(mpidr, scpi_power_off, scpi_power_off,
|
||||||
|
scpi_power_retention);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Export the platform handlers to enable psci to invoke them
|
||||||
|
******************************************************************************/
|
||||||
|
static const plat_pm_ops_t pm_ops = {
|
||||||
|
.affinst_on = pm_on,
|
||||||
|
.affinst_on_finish = pm_on_finish,
|
||||||
|
.affinst_off = pm_off
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Export the platform specific power ops & initialize the fvp power controller
|
||||||
|
******************************************************************************/
|
||||||
|
int platform_setup_pm(const plat_pm_ops_t **plat_ops)
|
||||||
|
{
|
||||||
|
*plat_ops = &pm_ops;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <platform_def.h>
|
||||||
|
#include <psci.h>
|
||||||
|
|
||||||
|
unsigned int plat_get_aff_count(unsigned int aff_lvl, unsigned long mpidr)
|
||||||
|
{
|
||||||
|
/* Report 1 (absent) instance at levels higher that the cluster level */
|
||||||
|
if (aff_lvl > MPIDR_AFFLVL1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (aff_lvl == MPIDR_AFFLVL1)
|
||||||
|
return 2; /* We have two clusters */
|
||||||
|
|
||||||
|
return mpidr & 0x100 ? 4 : 2; /* 4 cpus in cluster 1, 2 in cluster 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int plat_get_aff_state(unsigned int aff_lvl, unsigned long mpidr)
|
||||||
|
{
|
||||||
|
return aff_lvl <= MPIDR_AFFLVL1 ? PSCI_AFF_PRESENT : PSCI_AFF_ABSENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plat_get_max_afflvl()
|
||||||
|
{
|
||||||
|
return MPIDR_AFFLVL1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int plat_setup_topology()
|
||||||
|
{
|
||||||
|
/* Juno todo: Make topology configurable via SCC */
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
# Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
# to endorse or promote products derived from this software without specific
|
||||||
|
# prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
|
||||||
|
PLAT_INCLUDES := -Iplat/juno/include/
|
||||||
|
|
||||||
|
PLAT_BL_COMMON_SOURCES := drivers/arm/pl011/pl011_console.S \
|
||||||
|
drivers/io/io_fip.c \
|
||||||
|
drivers/io/io_memmap.c \
|
||||||
|
lib/aarch64/xlat_tables.c \
|
||||||
|
plat/common/aarch64/plat_common.c \
|
||||||
|
plat/juno/plat_io_storage.c
|
||||||
|
|
||||||
|
BL1_SOURCES += drivers/arm/cci400/cci400.c \
|
||||||
|
plat/common/aarch64/platform_up_stack.S \
|
||||||
|
plat/juno/bl1_plat_setup.c \
|
||||||
|
plat/juno/aarch64/bl1_plat_helpers.S \
|
||||||
|
plat/juno/aarch64/plat_helpers.S \
|
||||||
|
plat/juno/aarch64/juno_common.c
|
||||||
|
|
||||||
|
BL2_SOURCES += lib/locks/bakery/bakery_lock.c \
|
||||||
|
plat/common/aarch64/platform_up_stack.S \
|
||||||
|
plat/juno/bl2_plat_setup.c \
|
||||||
|
plat/juno/mhu.c \
|
||||||
|
plat/juno/aarch64/plat_helpers.S \
|
||||||
|
plat/juno/aarch64/juno_common.c \
|
||||||
|
plat/juno/scp_bootloader.c \
|
||||||
|
plat/juno/scpi.c
|
||||||
|
|
||||||
|
BL31_SOURCES += drivers/arm/cci400/cci400.c \
|
||||||
|
drivers/arm/gic/gic_v2.c \
|
||||||
|
plat/common/aarch64/platform_mp_stack.S \
|
||||||
|
plat/juno/bl31_plat_setup.c \
|
||||||
|
plat/juno/mhu.c \
|
||||||
|
plat/juno/aarch64/plat_helpers.S \
|
||||||
|
plat/juno/aarch64/juno_common.c \
|
||||||
|
plat/juno/plat_pm.c \
|
||||||
|
plat/juno/plat_topology.c \
|
||||||
|
plat/juno/plat_gic.c \
|
||||||
|
plat/juno/scpi.c
|
||||||
|
|
||||||
|
ifneq (${RESET_TO_BL31},0)
|
||||||
|
$(error "Using BL3-1 as the reset vector is not supported on Juno. \
|
||||||
|
Please set RESET_TO_BL31 to 0.")
|
||||||
|
endif
|
||||||
|
|
||||||
|
NEED_BL30 := yes
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "mhu.h"
|
||||||
|
#include "scp_bootloader.h"
|
||||||
|
#include "scpi.h"
|
||||||
|
|
||||||
|
/* Boot commands sent from AP -> SCP */
|
||||||
|
#define BOOT_CMD_START 0x01
|
||||||
|
#define BOOT_CMD_DATA 0x02
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t image_size;
|
||||||
|
} cmd_start_payload;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t sequence_num;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t size;
|
||||||
|
} cmd_data_payload;
|
||||||
|
|
||||||
|
#define BOOT_DATA_MAX_SIZE 0x1000
|
||||||
|
|
||||||
|
/* Boot commands sent from SCP -> AP */
|
||||||
|
#define BOOT_CMD_ACK 0x03
|
||||||
|
#define BOOT_CMD_NACK 0x04
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t sequence_num;
|
||||||
|
} cmd_ack_payload;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unlike the runtime protocol, the boot protocol uses the same memory region
|
||||||
|
* for both AP -> SCP and SCP -> AP transfers; define the address of this...
|
||||||
|
*/
|
||||||
|
static void * const cmd_payload = (void *)(MHU_SECURE_BASE + 0x0080);
|
||||||
|
|
||||||
|
static void *scp_boot_message_start(void)
|
||||||
|
{
|
||||||
|
mhu_secure_message_start();
|
||||||
|
|
||||||
|
return cmd_payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scp_boot_message_send(unsigned command, size_t size)
|
||||||
|
{
|
||||||
|
/* Make sure payload can be seen by SCP */
|
||||||
|
if (MHU_PAYLOAD_CACHED)
|
||||||
|
flush_dcache_range((unsigned long)cmd_payload, size);
|
||||||
|
|
||||||
|
/* Send command to SCP */
|
||||||
|
mhu_secure_message_send(command | (size << 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t scp_boot_message_wait(size_t size)
|
||||||
|
{
|
||||||
|
uint32_t response = mhu_secure_message_wait();
|
||||||
|
|
||||||
|
/* Make sure we see the reply from the SCP and not any stale data */
|
||||||
|
if (MHU_PAYLOAD_CACHED)
|
||||||
|
inv_dcache_range((unsigned long)cmd_payload, size);
|
||||||
|
|
||||||
|
return response & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scp_boot_message_end(void)
|
||||||
|
{
|
||||||
|
mhu_secure_message_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transfer_block(uint32_t sequence_num, uint32_t offset, uint32_t size)
|
||||||
|
{
|
||||||
|
cmd_data_payload *cmd_data = scp_boot_message_start();
|
||||||
|
cmd_data->sequence_num = sequence_num;
|
||||||
|
cmd_data->offset = offset;
|
||||||
|
cmd_data->size = size;
|
||||||
|
|
||||||
|
scp_boot_message_send(BOOT_CMD_DATA, sizeof(*cmd_data));
|
||||||
|
|
||||||
|
cmd_ack_payload *cmd_ack = cmd_payload;
|
||||||
|
int ok = scp_boot_message_wait(sizeof(*cmd_ack)) == BOOT_CMD_ACK
|
||||||
|
&& cmd_ack->sequence_num == sequence_num;
|
||||||
|
|
||||||
|
scp_boot_message_end();
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scp_bootloader_transfer(void *image, unsigned int image_size)
|
||||||
|
{
|
||||||
|
uintptr_t offset = (uintptr_t)image - MHU_SECURE_BASE;
|
||||||
|
uintptr_t end = offset + image_size;
|
||||||
|
uint32_t response;
|
||||||
|
|
||||||
|
mhu_secure_init();
|
||||||
|
|
||||||
|
/* Initiate communications with SCP */
|
||||||
|
do {
|
||||||
|
cmd_start_payload *cmd_start = scp_boot_message_start();
|
||||||
|
cmd_start->image_size = image_size;
|
||||||
|
|
||||||
|
scp_boot_message_send(BOOT_CMD_START, sizeof(*cmd_start));
|
||||||
|
|
||||||
|
response = scp_boot_message_wait(0);
|
||||||
|
|
||||||
|
scp_boot_message_end();
|
||||||
|
} while (response != BOOT_CMD_ACK);
|
||||||
|
|
||||||
|
/* Transfer image to SCP a block at a time */
|
||||||
|
uint32_t sequence_num = 1;
|
||||||
|
size_t size;
|
||||||
|
while ((size = end - offset) != 0) {
|
||||||
|
if (size > BOOT_DATA_MAX_SIZE)
|
||||||
|
size = BOOT_DATA_MAX_SIZE;
|
||||||
|
while (!transfer_block(sequence_num, offset, size))
|
||||||
|
; /* Retry forever */
|
||||||
|
offset += size;
|
||||||
|
sequence_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for SCP to signal it's ready */
|
||||||
|
return scpi_wait_ready();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SCP_BOOTLOADER_H__
|
||||||
|
#define __SCP_BOOTLOADER_H__
|
||||||
|
|
||||||
|
int scp_bootloader_transfer(void *image, unsigned int image_size);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <arch_helpers.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include "juno_def.h"
|
||||||
|
#include "mhu.h"
|
||||||
|
#include "scpi.h"
|
||||||
|
|
||||||
|
#define MHU_SECURE_SCP_TO_AP_PAYLOAD (MHU_SECURE_BASE+0x0080)
|
||||||
|
#define MHU_SECURE_AP_TO_SCP_PAYLOAD (MHU_SECURE_BASE+0x0280)
|
||||||
|
|
||||||
|
#define SIZE_SHIFT 20 /* Bit position for size value in MHU header */
|
||||||
|
#define SIZE_MASK 0x1ff /* Mask to extract size value in MHU header*/
|
||||||
|
|
||||||
|
|
||||||
|
void *scpi_secure_message_start(void)
|
||||||
|
{
|
||||||
|
mhu_secure_message_start();
|
||||||
|
|
||||||
|
/* Return address of payload area. */
|
||||||
|
return (void *)MHU_SECURE_AP_TO_SCP_PAYLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scpi_secure_message_send(unsigned command, size_t size)
|
||||||
|
{
|
||||||
|
/* Make sure payload can be seen by SCP */
|
||||||
|
if (MHU_PAYLOAD_CACHED)
|
||||||
|
flush_dcache_range(MHU_SECURE_AP_TO_SCP_PAYLOAD, size);
|
||||||
|
|
||||||
|
mhu_secure_message_send(command | (size << SIZE_SHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned scpi_secure_message_receive(void **message_out, size_t *size_out)
|
||||||
|
{
|
||||||
|
uint32_t response = mhu_secure_message_wait();
|
||||||
|
|
||||||
|
/* Get size of payload */
|
||||||
|
size_t size = (response >> SIZE_SHIFT) & SIZE_MASK;
|
||||||
|
|
||||||
|
/* Clear size from response */
|
||||||
|
response &= ~(SIZE_MASK << SIZE_SHIFT);
|
||||||
|
|
||||||
|
/* Make sure we don't read stale data */
|
||||||
|
if (MHU_PAYLOAD_CACHED)
|
||||||
|
inv_dcache_range(MHU_SECURE_SCP_TO_AP_PAYLOAD, size);
|
||||||
|
|
||||||
|
if (size_out)
|
||||||
|
*size_out = size;
|
||||||
|
|
||||||
|
if (message_out)
|
||||||
|
*message_out = (void *)MHU_SECURE_SCP_TO_AP_PAYLOAD;
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scpi_secure_message_end(void)
|
||||||
|
{
|
||||||
|
mhu_secure_message_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scpi_secure_send32(unsigned command, uint32_t message)
|
||||||
|
{
|
||||||
|
*(__typeof__(message) *)scpi_secure_message_start() = message;
|
||||||
|
scpi_secure_message_send(command, sizeof(message));
|
||||||
|
scpi_secure_message_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int scpi_wait_ready(void)
|
||||||
|
{
|
||||||
|
/* Get a message from the SCP */
|
||||||
|
scpi_secure_message_start();
|
||||||
|
size_t size;
|
||||||
|
unsigned command = scpi_secure_message_receive(NULL, &size);
|
||||||
|
scpi_secure_message_end();
|
||||||
|
|
||||||
|
/* We are expecting 'SCP Ready', produce correct error if it's not */
|
||||||
|
spci_status response = SCP_OK;
|
||||||
|
if (command != SCPI_CMD_SCP_READY)
|
||||||
|
response = SCP_E_SUPPORT;
|
||||||
|
else if (size != 0)
|
||||||
|
response = SCP_E_SIZE;
|
||||||
|
|
||||||
|
/* Send our response back to SCP */
|
||||||
|
scpi_secure_send32(command, response);
|
||||||
|
|
||||||
|
return response == SCP_OK ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scpi_set_css_power_state(unsigned mpidr, scpi_power_state cpu_state,
|
||||||
|
scpi_power_state cluster_state, scpi_power_state css_state)
|
||||||
|
{
|
||||||
|
uint32_t state = mpidr & 0x0f; /* CPU ID */
|
||||||
|
state |= (mpidr & 0xf00) >> 4; /* Cluster ID */
|
||||||
|
state |= cpu_state << 8;
|
||||||
|
state |= cluster_state << 12;
|
||||||
|
state |= css_state << 16;
|
||||||
|
scpi_secure_send32(SCPI_CMD_SET_CSS_POWER_STATE, state);
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific
|
||||||
|
* prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SCPI_H__
|
||||||
|
#define __SCPI_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void *scpi_secure_message_start(void);
|
||||||
|
extern void scpi_secure_message_send(unsigned command, size_t size);
|
||||||
|
extern unsigned scpi_secure_message_receive(void **message_out, size_t *size_out);
|
||||||
|
extern void scpi_secure_message_end(void);
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SCP_OK = 0, /* Success */
|
||||||
|
SCP_E_PARAM, /* Invalid parameter(s) */
|
||||||
|
SCP_E_ALIGN, /* Invalid alignment */
|
||||||
|
SCP_E_SIZE, /* Invalid size */
|
||||||
|
SCP_E_HANDLER, /* Invalid handler or callback */
|
||||||
|
SCP_E_ACCESS, /* Invalid access or permission denied */
|
||||||
|
SCP_E_RANGE, /* Value out of range */
|
||||||
|
SCP_E_TIMEOUT, /* Time out has ocurred */
|
||||||
|
SCP_E_NOMEM, /* Invalid memory area or pointer */
|
||||||
|
SCP_E_PWRSTATE, /* Invalid power state */
|
||||||
|
SCP_E_SUPPORT, /* Feature not supported or disabled */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef uint32_t spci_status;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCPI_CMD_SCP_READY = 0x01,
|
||||||
|
SCPI_CMD_SET_CSS_POWER_STATE = 0x04,
|
||||||
|
} spci_command;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
scpi_power_on = 0,
|
||||||
|
scpi_power_retention = 1,
|
||||||
|
scpi_power_off = 3,
|
||||||
|
} scpi_power_state;
|
||||||
|
|
||||||
|
extern int scpi_wait_ready(void);
|
||||||
|
extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state cpu_state,
|
||||||
|
scpi_power_state cluster_state, scpi_power_state css_state);
|
||||||
|
|
||||||
|
#endif /* __SCPI_H__ */
|
Loading…
Reference in New Issue