juno: Create as a trimmed copy of plat/fvp

Signed-off-by: Jon Medhurst <tixy@linaro.org>
This commit is contained in:
Jon Medhurst 2014-01-13 19:52:01 +00:00 committed by Sandrine Bailleux
parent 1c297bf015
commit b86295169e
12 changed files with 1951 additions and 0 deletions

View File

@ -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 <platform.h>
.globl platform_get_entrypoint
.globl platform_cold_boot_init
.globl plat_secondary_cold_boot_setup
.section .text, "ax"; .align 3
/* -----------------------------------------------------
* 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.
* -----------------------------------------------------
*/
plat_secondary_cold_boot_setup: ; .type plat_secondary_cold_boot_setup, %function
/* 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
* TODO: PSYSR is a common register and should be
* accessed using locks. Since its not possible
* to use locks immediately after a cold reset
* we are relying on the fact that after a cold
* reset all cpus will read the same WK field
* -----------------------------------------------------
*/
platform_get_entrypoint: ; .type platform_get_entrypoint, %function
mov x9, x30 // lr
mov x2, x0
ldr x1, =PWRC_BASE
str w2, [x1, #PSYSR_OFF]
ldr w2, [x1, #PSYSR_OFF]
ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_MASK
cbnz w2, warm_reset
mov x0, x2
b exit
warm_reset:
/* ---------------------------------------------
* A per-cpu mailbox is maintained in the tru-
* sted DRAM. Its flushed out of the caches
* after every update using normal memory so
* its safe to read it here with SO attributes
* ---------------------------------------------
*/
ldr x10, =TZDRAM_BASE + MBOX_OFF
bl platform_get_core_pos
lsl x0, x0, #CACHE_WRITEBACK_SHIFT
ldr x0, [x10, x0]
cbz x0, _panic
exit:
ret x9
_panic: b _panic
/* -----------------------------------------------------
* void platform_mem_init (void);
*
* Zero out the mailbox registers in the TZDRAM. The
* mmu is turned off right now and only the primary can
* ever execute this code. Secondaries will read the
* mailboxes using SO accesses. In short, BL31 will
* update the mailboxes after mapping the tzdram as
* normal memory. It will flush its copy after update.
* BL1 will always read the mailboxes with the MMU off
* -----------------------------------------------------
*/
platform_mem_init: ; .type platform_mem_init, %function
ldr x0, =TZDRAM_BASE + MBOX_OFF
stp xzr, xzr, [x0, #0]
stp xzr, xzr, [x0, #0x10]
stp xzr, xzr, [x0, #0x20]
stp xzr, xzr, [x0, #0x30]
ret
/* -----------------------------------------------------
* void platform_cold_boot_init (bl1_main function);
*
* Routine called only by the primary cpu after a cold
* boot to perform early platform initialization
* -----------------------------------------------------
*/
platform_cold_boot_init: ; .type platform_cold_boot_init, %function
mov x20, x0
bl platform_mem_init
bl read_mpidr
mov x19, x0
/* ---------------------------------------------
* Give ourselves a small coherent stack to
* ease the pain of initializing the MMU and
* CCI in assembler
* ---------------------------------------------
*/
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
* ---------------------------------------------
*/
mov x0, x19
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

View File

@ -0,0 +1,147 @@
/*
* 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 <string.h>
#include <assert.h>
#include <arch_helpers.h>
#include <platform.h>
#include <bl_common.h>
/* Included only for error codes */
#include <psci.h>
unsigned char platform_normal_stacks[PLATFORM_STACK_SIZE][PLATFORM_CORE_COUNT]
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_normal_stacks")));
/*******************************************************************************
* This array holds the characteristics of the differences between the three
* FVP platforms (Base, A53_A57 & Foundation). It will be populated during cold
* boot at each boot stage by the primary before enabling the MMU (to allow cci
* configuration) & used thereafter. Each BL will have its own copy to allow
* independent operation.
******************************************************************************/
static unsigned long platform_config[CONFIG_LIMIT];
/*******************************************************************************
* An internal global pointer of the level 1 translation tables which should not
* change once setup by the primary cpu during a cold boot.
*******************************************************************************/
unsigned long l1_xlation_table __aligned(PLATFORM_CACHE_LINE_SIZE)
__attribute__ ((section("tzfw_coherent_mem")));
/*******************************************************************************
* Enable the MMU assuming that the pagetables have already been created
*******************************************************************************/
void enable_mmu()
{
unsigned long mair, tcr, ttbr, sctlr;
unsigned long current_el = read_current_el();
/* Set the attributes in the right indices of the MAIR */
mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
ATTR_IWBWA_OWBWA_NTR_INDEX);
write_mair(mair);
/*
* Set TCR bits as well. Inner & outer WBWA & shareable + T0SZ = 32
*/
tcr = TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA |
TCR_RGN_INNER_WBA | TCR_T0SZ_4GB;
if (GET_EL(current_el) == MODE_EL3) {
tcr |= TCR_EL3_RES1;
/* Invalidate EL3 TLBs */
tlbialle3();
} else {
/* Invalidate EL1 TLBs */
tlbivmalle1();
}
write_tcr(tcr);
/* Set TTBR bits as well */
ttbr = (unsigned long) l1_xlation_table;
write_ttbr0(ttbr);
sctlr = read_sctlr();
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT;
sctlr |= SCTLR_A_BIT | SCTLR_C_BIT;
write_sctlr(sctlr);
return;
}
void disable_mmu(void)
{
/* Zero out the MMU related registers */
write_mair(0);
write_tcr(0);
write_ttbr0(0);
write_sctlr(0);
/* Flush the caches */
dcsw_op_all(DCCISW);
return;
}
/*******************************************************************************
* Setup the pagetables as per the platform memory map & initialize the mmu
*******************************************************************************/
void configure_mmu(meminfo *mem_layout,
unsigned long ro_start,
unsigned long ro_limit,
unsigned long coh_start,
unsigned long coh_limit)
{
assert(IS_PAGE_ALIGNED(ro_start));
assert(IS_PAGE_ALIGNED(ro_limit));
assert(IS_PAGE_ALIGNED(coh_start));
assert(IS_PAGE_ALIGNED(coh_limit));
l1_xlation_table = fill_xlation_tables(mem_layout,
ro_start,
ro_limit,
coh_start,
coh_limit);
enable_mmu();
return;
}
/* Simple routine which returns a configuration variable value */
unsigned long platform_get_cfgvar(unsigned int var_id)
{
assert(var_id < CONFIG_LIMIT);
return platform_config[var_id];
}
unsigned long plat_get_ns_image_entrypoint(void) {
return NS_IMAGE_OFFSET;
}

View File

@ -0,0 +1,48 @@
/*
* 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 <platform.h>
.globl plat_report_exception
.section .text, "ax"
/* ---------------------------------------------
* void plat_report_exception(unsigned int type)
* Function to report an unhandled exception
* with platform-specific means.
* On FVP platform, it updates the LEDs
* to indicate where we are
* ---------------------------------------------
*/
plat_report_exception:
/* Juno todo: Come up with a way of reporting errors */
ret

144
plat/juno/bl1_plat_setup.c Normal file
View File

@ -0,0 +1,144 @@
/*
* 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 <assert.h>
#include <arch_helpers.h>
#include <platform.h>
#include <bl1.h>
#include <console.h>
#include <cci400.h>
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
******************************************************************************/
extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__;
extern unsigned long __BL1_RAM_START__;
extern unsigned long __BL1_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__)
#define BL1_RAM_BASE (unsigned long)(&__BL1_RAM_START__)
#define BL1_RAM_LIMIT (unsigned long)(&__BL1_RAM_END__)
/* Data structure which holds the extents of the trusted SRAM for BL1*/
static meminfo bl1_tzram_layout;
meminfo *bl1_plat_sec_mem_layout(void)
{
return &bl1_tzram_layout;
}
/*******************************************************************************
* Perform any BL1 specific platform actions.
******************************************************************************/
void bl1_early_platform_setup(void)
{
const unsigned long bl1_ram_base = BL1_RAM_BASE;
const unsigned long bl1_ram_limit = BL1_RAM_LIMIT;
const unsigned long tzram_limit = TZRAM_BASE + TZRAM_SIZE;
/*
* Calculate how much ram is BL1 using & how much remains free.
* This also includes a rudimentary mechanism to detect whether
* the BL1 data is loaded at the top or bottom of memory.
* TODO: add support for discontigous chunks of free ram if
* needed. Might need dynamic memory allocation support
* et al.
*/
bl1_tzram_layout.total_base = TZRAM_BASE;
bl1_tzram_layout.total_size = TZRAM_SIZE;
if (bl1_ram_limit == tzram_limit) {
/* BL1 has been loaded at the top of memory. */
bl1_tzram_layout.free_base = TZRAM_BASE;
bl1_tzram_layout.free_size = bl1_ram_base - TZRAM_BASE;
} else {
/* BL1 has been loaded at the bottom of memory. */
bl1_tzram_layout.free_base = bl1_ram_limit;
bl1_tzram_layout.free_size =
tzram_limit - bl1_ram_limit;
}
/* Initialize the console */
console_init(PL011_UART0_BASE);
}
/*******************************************************************************
* Function which will evaluate how much of the trusted ram has been gobbled
* up by BL1 and return the base and size of whats available for loading BL2.
* Its called after coherency and the MMU have been turned on.
******************************************************************************/
void bl1_platform_setup(void)
{
/* 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_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)
{
unsigned long cci_setup;
/*
* Enable CCI-400 for this cluster. No need
* for locks as no other cpu is active at the
* moment
*/
cci_setup = platform_get_cfgvar(CONFIG_HAS_CCI);
if (cci_setup) {
cci_enable_coherency(read_mpidr());
}
configure_mmu(&bl1_tzram_layout,
TZROM_BASE,
TZROM_BASE + TZROM_SIZE,
BL1_COHERENT_RAM_BASE,
BL1_COHERENT_RAM_LIMIT);
}

145
plat/juno/bl2_plat_setup.c Normal file
View File

@ -0,0 +1,145 @@
/*
* 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 <assert.h>
#include <arch_helpers.h>
#include <platform.h>
#include <bl2.h>
#include <bl_common.h>
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
******************************************************************************/
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__)
/* Pointer to memory visible to both BL2 and BL31 for passing data */
extern unsigned char **bl2_el_change_mem_ptr;
/* Data structure which holds the extents of the trusted SRAM for BL2 */
static meminfo bl2_tzram_layout
__attribute__ ((aligned(PLATFORM_CACHE_LINE_SIZE),
section("tzfw_coherent_mem")));
/*******************************************************************************
* Reference to structure which holds the arguments which need to be passed
* to BL31
******************************************************************************/
static bl31_args *bl2_to_bl31_args;
meminfo *bl2_plat_sec_mem_layout(void)
{
return &bl2_tzram_layout;
}
/*******************************************************************************
* This function returns a pointer to the memory that the platform has kept
* aside to pass all the information that BL31 could need.
******************************************************************************/
bl31_args *bl2_get_bl31_args_ptr(void)
{
return bl2_to_bl31_args;
}
/*******************************************************************************
* BL1 has passed the extents of the trusted SRAM that should be visible to BL2
* in x0. This memory layout is sitting at the base of the free trusted SRAM.
* Copy it to a safe loaction before its reclaimed by later BL2 functionality.
******************************************************************************/
void bl2_early_platform_setup(meminfo *mem_layout,
void *data)
{
/* Setup the BL2 memory layout */
bl2_tzram_layout.total_base = mem_layout->total_base;
bl2_tzram_layout.total_size = mem_layout->total_size;
bl2_tzram_layout.free_base = mem_layout->free_base;
bl2_tzram_layout.free_size = mem_layout->free_size;
bl2_tzram_layout.attr = mem_layout->attr;
bl2_tzram_layout.next = 0;
return;
}
/*******************************************************************************
* Perform platform specific setup. For now just initialize the memory location
* to use for passing arguments to BL31.
******************************************************************************/
void bl2_platform_setup()
{
/* Initialise the IO layer and register platform IO devices */
io_setup();
/* Use the Trusted DRAM for passing args to BL31 */
bl2_to_bl31_args = (bl31_args *) TZDRAM_BASE;
/* Populate the extents of memory available for loading BL33 */
bl2_to_bl31_args->bl33_meminfo.total_base = DRAM_BASE;
bl2_to_bl31_args->bl33_meminfo.total_size = DRAM_SIZE;
bl2_to_bl31_args->bl33_meminfo.free_base = DRAM_BASE;
bl2_to_bl31_args->bl33_meminfo.free_size = DRAM_SIZE;
bl2_to_bl31_args->bl33_meminfo.attr = 0;
bl2_to_bl31_args->bl33_meminfo.next = 0;
}
/*******************************************************************************
* 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()
{
configure_mmu(&bl2_tzram_layout,
BL2_RO_BASE,
BL2_RO_LIMIT,
BL2_COHERENT_RAM_BASE,
BL2_COHERENT_RAM_LIMIT);
}

141
plat/juno/bl31_plat_setup.c Normal file
View File

@ -0,0 +1,141 @@
/*
* 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 <platform.h>
/*******************************************************************************
* Declarations of linker defined symbols which will help us find the layout
* of trusted SRAM
******************************************************************************/
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__)
/*******************************************************************************
* Reference to structure which holds the arguments that have been passed to
* BL31 from BL2.
******************************************************************************/
static bl31_args *bl2_to_bl31_args;
meminfo *bl31_plat_sec_mem_layout(void)
{
return &bl2_to_bl31_args->bl31_meminfo;
}
meminfo *bl31_plat_get_bl32_mem_layout(void)
{
return &bl2_to_bl31_args->bl32_meminfo;
}
/*******************************************************************************
* Return a pointer to the 'el_change_info' structure of the next image for the
* security state specified. BL33 corresponds to the non-secure image type
* while BL32 corresponds to the secure image type. A NULL pointer is returned
* if the image does not exist.
******************************************************************************/
el_change_info *bl31_get_next_image_info(uint32_t type)
{
el_change_info *next_image_info;
next_image_info = (type == NON_SECURE) ?
&bl2_to_bl31_args->bl33_image_info :
&bl2_to_bl31_args->bl32_image_info;
/* None of the images on this platform can have 0x0 as the entrypoint */
if (next_image_info->entrypoint)
return next_image_info;
else
return NULL;
}
/*******************************************************************************
* Perform any BL31 specific platform actions. Here is an opportunity to copy
* parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they
* are lost (potentially). This needs to be done before the MMU is initialized
* so that the memory layout can be used while creating page tables. On the FVP
* we know that BL2 has populated the parameters in secure DRAM. So we just use
* the reference passed in 'from_bl2' instead of copying. The 'data' parameter
* is not used since all the information is contained in 'from_bl2'. Also, BL2
* has flushed this information to memory, so we are guaranteed to pick up good
* data
******************************************************************************/
void bl31_early_platform_setup(bl31_args *from_bl2,
void *data)
{
bl2_to_bl31_args = from_bl2;
}
/*******************************************************************************
* Initialize the gic, configure the CLCD and zero out variables needed by the
* secondaries to boot up correctly.
******************************************************************************/
void bl31_platform_setup()
{
/* Initialize the gic cpu and distributor interfaces */
gic_setup();
/* 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(&bl2_to_bl31_args->bl31_meminfo,
BL31_RO_BASE,
BL31_RO_LIMIT,
BL31_COHERENT_RAM_BASE,
BL31_COHERENT_RAM_LIMIT);
}

282
plat/juno/plat_gic.c Normal file
View File

@ -0,0 +1,282 @@
/*
* 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 <stdint.h>
#include <arch_helpers.h>
#include <platform.h>
#include <gic.h>
#include <debug.h>
/*******************************************************************************
* TODO: Revisit if priorities are being set such that no non-secure interrupt
* can have a higher priority than a secure one as recommended in the GICv2 spec
******************************************************************************/
/*******************************************************************************
* This function does some minimal GICv3 configuration. The Firmware itself does
* not fully support GICv3 at this time and relies on GICv2 emulation as
* provided by GICv3. This function allows software (like Linux) in later stages
* to use full GICv3 features.
******************************************************************************/
void gicv3_cpuif_setup(void)
{
unsigned int scr_val, val;
uintptr_t base;
/*
* When CPUs come out of reset they have their GICR_WAKER.ProcessorSleep
* bit set. In order to allow interrupts to get routed to the CPU we
* need to clear this bit if set and wait for GICR_WAKER.ChildrenAsleep
* to clear (GICv3 Architecture specification 5.4.23).
* GICR_WAKER is NOT banked per CPU, compute the correct base address
* per CPU.
*/
base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr());
if (base == (uintptr_t)NULL) {
/* No re-distributor base address. This interface cannot be
* configured.
*/
panic();
}
val = gicr_read_waker(base);
val &= ~WAKER_PS;
gicr_write_waker(base, val);
dsb();
/* We need to wait for ChildrenAsleep to clear. */
val = gicr_read_waker(base);
while (val & WAKER_CA) {
val = gicr_read_waker(base);
}
/*
* We need to set SCR_EL3.NS in order to see GICv3 non-secure state.
* Restore SCR_EL3.NS again before exit.
*/
scr_val = read_scr();
write_scr(scr_val | SCR_NS_BIT);
/*
* By default EL2 and NS-EL1 software should be able to enable GICv3
* System register access without any configuration at EL3. But it turns
* out that GICC PMR as set in GICv2 mode does not affect GICv3 mode. So
* we need to set it here again. In order to do that we need to enable
* register access. We leave it enabled as it should be fine and might
* prevent problems with later software trying to access GIC System
* Registers.
*/
val = read_icc_sre_el3();
write_icc_sre_el3(val | ICC_SRE_EN | ICC_SRE_SRE);
val = read_icc_sre_el2();
write_icc_sre_el2(val | ICC_SRE_EN | ICC_SRE_SRE);
write_icc_pmr_el1(GIC_PRI_MASK);
/* Restore SCR_EL3 */
write_scr(scr_val);
}
/*******************************************************************************
* This function does some minimal GICv3 configuration when cores go
* down.
******************************************************************************/
void gicv3_cpuif_deactivate(void)
{
unsigned int val;
uintptr_t base;
/*
* When taking CPUs down we need to set GICR_WAKER.ProcessorSleep and
* wait for GICR_WAKER.ChildrenAsleep to get set.
* (GICv3 Architecture specification 5.4.23).
* GICR_WAKER is NOT banked per CPU, compute the correct base address
* per CPU.
*/
base = gicv3_get_rdist(BASE_GICR_BASE, read_mpidr());
if (base == (uintptr_t)NULL) {
/* No re-distributor base address. This interface cannot be
* configured.
*/
panic();
}
val = gicr_read_waker(base);
val |= WAKER_PS;
gicr_write_waker(base, val);
dsb();
/* We need to wait for ChildrenAsleep to set. */
val = gicr_read_waker(base);
while ((val & WAKER_CA) == 0) {
val = gicr_read_waker(base);
}
}
/*******************************************************************************
* 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;
val = gicc_read_iidr(gicc_base);
/*
* If GICv3 we need to do a bit of additional setup. We want to
* allow default GICv2 behaviour but allow the next stage to
* enable full gicv3 features.
*/
if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
gicv3_cpuif_setup();
}
val = ENABLE_GRP0 | FIQ_EN | FIQ_BYP_DIS_GRP0;
val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1;
gicc_write_pmr(gicc_base, GIC_PRI_MASK);
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);
val = gicc_read_iidr(gicc_base);
/*
* If GICv3 we need to do a bit of additional setup. Make sure the
* RDIST is put to sleep.
*/
if (((val >> GICC_IIDR_ARCH_SHIFT) & GICC_IIDR_ARCH_MASK) >= 3) {
gicv3_cpuif_deactivate();
}
}
/*******************************************************************************
* 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)
{
gicd_write_igroupr(gicd_base, 0, ~0);
gicd_clr_igroupr(gicd_base, IRQ_SEC_PHY_TIMER);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_0);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_1);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_2);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_3);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_4);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_5);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_6);
gicd_clr_igroupr(gicd_base, IRQ_SEC_SGI_7);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_ipriorityr(gicd_base, IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_isenabler(gicd_base, IRQ_SEC_PHY_TIMER);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_0);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_1);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_2);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_3);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_4);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_5);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_6);
gicd_set_isenabler(gicd_base, IRQ_SEC_SGI_7);
}
/*******************************************************************************
* 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.
******************************************************************************/
void gic_distif_setup(unsigned int gicd_base)
{
unsigned int ctr, num_ints, ctlr;
/* Disable the distributor before going further */
ctlr = gicd_read_ctlr(gicd_base);
ctlr &= ~(ENABLE_GRP0 | ENABLE_GRP1);
gicd_write_ctlr(gicd_base, ctlr);
/*
* Mark out non-secure interrupts. Calculate number of
* IGROUPR registers to consider. Will be equal to the
* number of IT_LINES
*/
num_ints = gicd_read_typer(gicd_base) & IT_LINES_NO_MASK;
num_ints++;
for (ctr = 0; ctr < num_ints; ctr++)
gicd_write_igroupr(gicd_base, ctr << IGROUPR_SHIFT, ~0);
/* Configure secure interrupts now */
gicd_clr_igroupr(gicd_base, IRQ_TZ_WDOG);
gicd_set_ipriorityr(gicd_base, IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY);
gicd_set_itargetsr(gicd_base, IRQ_TZ_WDOG,
platform_get_core_pos(read_mpidr()));
gicd_set_isenabler(gicd_base, IRQ_TZ_WDOG);
gic_pcpu_distif_setup(gicd_base);
gicd_write_ctlr(gicd_base, ctlr | ENABLE_GRP0);
}
void gic_setup(void)
{
unsigned int gicd_base, gicc_base;
gicd_base = platform_get_cfgvar(CONFIG_GICD_ADDR);
gicc_base = platform_get_cfgvar(CONFIG_GICC_ADDR);
gic_cpuif_setup(gicc_base);
gic_distif_setup(gicd_base);
}

207
plat/juno/plat_io_storage.c Normal file
View File

@ -0,0 +1,207 @@
/*
* 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 "io_semihosting.h"
#include "semihosting.h" /* For FOPEN_MODE_... */
#include "io_fip.h"
#include "io_memmap.h"
#include "debug.h"
/* IO devices */
static struct io_plat_data io_data;
static struct io_dev_connector *sh_dev_con;
static void *const sh_dev_spec;
static void *const sh_init_params;
static io_dev_handle sh_dev_handle;
static struct io_dev_connector *fip_dev_con;
static void *const fip_dev_spec;
static io_dev_handle fip_dev_handle;
static struct io_dev_connector *memmap_dev_con;
static void *const memmap_dev_spec;
static void *const memmap_init_params;
static io_dev_handle memmap_dev_handle;
static io_block_spec fip_block_spec = {
.offset = FLASH0_BASE,
.length = FLASH0_SIZE
};
static io_file_spec bl2_file_spec = {
.path = BL2_IMAGE_NAME,
.mode = FOPEN_MODE_R
};
static io_file_spec bl31_file_spec = {
.path = BL31_IMAGE_NAME,
.mode = FOPEN_MODE_R
};
static io_file_spec bl33_file_spec = {
.path = BL33_IMAGE_NAME,
.mode = FOPEN_MODE_R
};
static int open_fip(void* spec);
static int open_memmap(void* spec);
typedef struct {
char * image_name;
io_dev_handle* dev_handle;
void* image_spec;
int (*check)(void* spec);
} plat_io_policy;
static plat_io_policy policies[] = {
{ FIP_IMAGE_NAME, &memmap_dev_handle, &fip_block_spec, open_memmap },
{ BL2_IMAGE_NAME, &fip_dev_handle, &bl2_file_spec, open_fip },
{ BL31_IMAGE_NAME, &fip_dev_handle, &bl31_file_spec, open_fip },
{ BL33_IMAGE_NAME, &fip_dev_handle, &bl33_file_spec, open_fip },
{0,0,0}
};
static int open_fip(void *spec)
{
int result = IO_FAIL;
/* See if a Firmware Image Package is available */
result = io_dev_init(fip_dev_handle, (void *)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(void *spec)
{
int result = IO_FAIL;
io_handle 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;
}
static int open_semihosting(void *spec)
{
int result = IO_FAIL;
io_handle local_image_handle;
/* See if the file exists on semi-hosting.*/
result = io_dev_init(sh_dev_handle, sh_init_params);
if (result == IO_SUCCESS) {
result = io_open(sh_dev_handle, spec, &local_image_handle);
if (result == IO_SUCCESS) {
INFO("Using Semi-hosting 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_sh(&sh_dev_con);
assert(io_result == IO_SUCCESS);
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(sh_dev_con, sh_dev_spec, &sh_dev_handle);
assert(io_result == IO_SUCCESS);
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, io_dev_handle *dev_handle,
void **image_spec)
{
int result = IO_FAIL;
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) {
*(io_file_spec**)image_spec = policy->image_spec;
*dev_handle=*(policy->dev_handle);
break;
} else {
result = open_semihosting(policy->image_spec);
if (result == IO_SUCCESS) {
*dev_handle = sh_dev_handle;
*(io_file_spec **)image_spec = policy->image_spec;
}
}
}
policy++;
}
} else {
result = IO_FAIL;
}
return result;
}

48
plat/juno/plat_pm.c Normal file
View File

@ -0,0 +1,48 @@
/*
* 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 <stdint.h>
#include <psci.h>
/*******************************************************************************
* Export the platform handlers to enable psci to invoke them
******************************************************************************/
static plat_pm_ops pm_ops = {
0
};
/*******************************************************************************
* Export the platform specific power ops & initialize the fvp power controller
******************************************************************************/
int platform_setup_pm(plat_pm_ops **plat_ops)
{
*plat_ops = &pm_ops;
return 0;
}

241
plat/juno/plat_topology.c Normal file
View File

@ -0,0 +1,241 @@
/*
* 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 <string.h>
#include <assert.h>
#include <platform.h>
#include <fvp_pwrc.h>
/* TODO: Reusing psci error codes & state information. Get our own! */
#include <psci.h>
/* We treat '255' as an invalid affinity instance */
#define AFFINST_INVAL 0xff
/*******************************************************************************
* We support 3 flavours of the FVP: Foundation, Base AEM & Base Cortex. Each
* flavour has a different topology. The common bit is that there can be a max.
* of 2 clusters (affinity 1) and 4 cpus (affinity 0) per cluster. So we define
* a tree like data structure which caters to these maximum bounds. It simply
* marks the absent affinity level instances as PSCI_AFF_ABSENT e.g. there is no
* cluster 1 on the Foundation FVP. The 'data' field is currently unused.
******************************************************************************/
typedef struct {
unsigned char sibling;
unsigned char child;
unsigned char state;
unsigned int data;
} affinity_info;
/*******************************************************************************
* The following two data structures store the topology tree for the fvp. There
* is a separate array for each affinity level i.e. cpus and clusters. The child
* and sibling references allow traversal inside and in between the two arrays.
******************************************************************************/
static affinity_info fvp_aff1_topology_map[PLATFORM_CLUSTER_COUNT];
static affinity_info fvp_aff0_topology_map[PLATFORM_CORE_COUNT];
/* Simple global variable to safeguard us from stupidity */
static unsigned int topology_setup_done;
/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform to allow the former to detect the platform
* topology. psci queries the platform to determine how many affinity instances
* are present at a particular level for a given mpidr e.g. consider a dual
* cluster platform where each cluster has 4 cpus. A call to this function with
* (0, 0x100) will return the number of cpus implemented under cluster 1 i.e. 4.
* Similarly a call with (1, 0x100) will return 2 i.e. the number of clusters.
* This is 'cause we are effectively asking how many affinity level 1 instances
* are implemented under affinity level 2 instance 0.
******************************************************************************/
unsigned int plat_get_aff_count(unsigned int aff_lvl,
unsigned long mpidr)
{
unsigned int aff_count = 1, ctr;
unsigned char parent_aff_id;
assert(topology_setup_done == 1);
switch (aff_lvl) {
case 3:
case 2:
/*
* Assert if the parent affinity instance is not 0.
* This also takes care of level 3 in an obfuscated way
*/
parent_aff_id = (mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK;
assert(parent_aff_id == 0);
/*
* Report that we implement a single instance of
* affinity levels 2 & 3 which are AFF_ABSENT
*/
break;
case 1:
/* Assert if the parent affinity instance is not 0. */
parent_aff_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
assert(parent_aff_id == 0);
/* Fetch the starting index in the aff1 array */
for (ctr = 0;
fvp_aff1_topology_map[ctr].sibling != AFFINST_INVAL;
ctr = fvp_aff1_topology_map[ctr].sibling) {
aff_count++;
}
break;
case 0:
/* Assert if the cluster id is anything apart from 0 or 1 */
parent_aff_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
assert(parent_aff_id < PLATFORM_CLUSTER_COUNT);
/* Fetch the starting index in the aff0 array */
for (ctr = fvp_aff1_topology_map[parent_aff_id].child;
fvp_aff0_topology_map[ctr].sibling != AFFINST_INVAL;
ctr = fvp_aff0_topology_map[ctr].sibling) {
aff_count++;
}
break;
default:
assert(0);
}
return aff_count;
}
/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform to allow the former to detect the state of a
* affinity instance in the platform topology. psci queries the platform to
* determine whether an affinity instance is present or absent. This caters for
* topologies where an intermediate affinity level instance is missing e.g.
* consider a platform which implements a single cluster with 4 cpus and there
* is another cpu sitting directly on the interconnect along with the cluster.
* The mpidrs of the cluster would range from 0x0-0x3. The mpidr of the single
* cpu would be 0x100 to highlight that it does not belong to cluster 0. Cluster
* 1 is however missing but needs to be accounted to reach this single cpu in
* the topology tree. Hence it will be marked as PSCI_AFF_ABSENT. This is not
* applicable to the FVP but depicted as an example.
******************************************************************************/
unsigned int plat_get_aff_state(unsigned int aff_lvl,
unsigned long mpidr)
{
unsigned int aff_state = PSCI_AFF_ABSENT, idx;
idx = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
assert(topology_setup_done == 1);
switch (aff_lvl) {
case 3:
case 2:
/* Report affinity levels 2 & 3 as absent */
break;
case 1:
aff_state = fvp_aff1_topology_map[idx].state;
break;
case 0:
/*
* First get start index of the aff0 in its array & then add
* to it the affinity id that we want the state of
*/
idx = fvp_aff1_topology_map[idx].child;
idx += (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
aff_state = fvp_aff0_topology_map[idx].state;
break;
default:
assert(0);
}
return aff_state;
}
/*******************************************************************************
* Handy optimization to prevent the psci implementation from traversing through
* affinity levels which are not present while detecting the platform topology.
******************************************************************************/
int plat_get_max_afflvl()
{
return MPIDR_AFFLVL1;
}
/*******************************************************************************
* This function populates the FVP specific topology information depending upon
* the FVP flavour its running on. We construct all the mpidrs we can handle
* and rely on the PWRC.PSYSR to flag absent cpus when their status is queried.
******************************************************************************/
int plat_setup_topology()
{
unsigned char aff0, aff1, aff_state, aff0_offset = 0;
unsigned long mpidr;
topology_setup_done = 0;
for (aff1 = 0; aff1 < PLATFORM_CLUSTER_COUNT; aff1++) {
fvp_aff1_topology_map[aff1].child = aff0_offset;
fvp_aff1_topology_map[aff1].sibling = aff1 + 1;
for (aff0 = 0; aff0 < PLATFORM_MAX_CPUS_PER_CLUSTER; aff0++) {
mpidr = aff1 << MPIDR_AFF1_SHIFT;
mpidr |= aff0 << MPIDR_AFF0_SHIFT;
if (fvp_pwrc_read_psysr(mpidr) != PSYSR_INVALID) {
/*
* Presence of even a single aff0 indicates
* presence of parent aff1 on the FVP.
*/
aff_state = PSCI_AFF_PRESENT;
fvp_aff1_topology_map[aff1].state =
PSCI_AFF_PRESENT;
} else {
aff_state = PSCI_AFF_ABSENT;
}
fvp_aff0_topology_map[aff0_offset].child = AFFINST_INVAL;
fvp_aff0_topology_map[aff0_offset].state = aff_state;
fvp_aff0_topology_map[aff0_offset].sibling =
aff0_offset + 1;
/* Increment the absolute number of aff0s traversed */
aff0_offset++;
}
/* Tie-off the last aff0 sibling to -1 to avoid overflow */
fvp_aff0_topology_map[aff0_offset - 1].sibling = AFFINST_INVAL;
}
/* Tie-off the last aff1 sibling to AFFINST_INVAL to avoid overflow */
fvp_aff1_topology_map[aff1 - 1].sibling = AFFINST_INVAL;
topology_setup_done = 1;
return 0;
}

287
plat/juno/platform.h Normal file
View File

@ -0,0 +1,287 @@
/*
* 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.
*/
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#include <arch.h>
#include <mmio.h>
#include <psci.h>
#include <bl_common.h>
#include "io_storage.h"
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
/*******************************************************************************
* Generic platform constants
******************************************************************************/
#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 BL31 */
#define BL31_IMAGE_NAME "bl31.bin"
/* Secure Payload BL32 (Trusted OS) */
#define BL32_IMAGE_NAME "bl32.bin"
/* Non-Trusted Firmware BL33 and its load address */
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
#define NS_IMAGE_OFFSET (DRAM_BASE + 0x8000000) /* DRAM + 128MB */
/* Firmware Image Package */
#define FIP_IMAGE_NAME "fip.bin"
#define PLATFORM_CACHE_LINE_SIZE 64
#define PLATFORM_CLUSTER_COUNT 2ull
#define PLATFORM_CLUSTER0_CORE_COUNT 4
#define PLATFORM_CLUSTER1_CORE_COUNT 4
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
PLATFORM_CLUSTER0_CORE_COUNT)
#define PLATFORM_MAX_CPUS_PER_CLUSTER 4
#define PRIMARY_CPU 0x0
#define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
#define TZROM_BASE 0x00000000
#define TZROM_SIZE 0x04000000
#define TZRAM_BASE 0x04000000
#define TZRAM_SIZE 0x40000
#define FLASH0_BASE 0x08000000
#define FLASH0_SIZE TZROM_SIZE
#define FLASH1_BASE 0x0c000000
#define FLASH1_SIZE 0x04000000
#define PSRAM_BASE 0x14000000
#define PSRAM_SIZE 0x04000000
#define VRAM_BASE 0x18000000
#define VRAM_SIZE 0x02000000
/* Aggregate of all devices in the first GB */
#define DEVICE0_BASE 0x1a000000
#define DEVICE0_SIZE 0x12200000
#define DEVICE1_BASE 0x2f000000
#define DEVICE1_SIZE 0x200000
#define NSRAM_BASE 0x2e000000
#define NSRAM_SIZE 0x10000
/* Location of trusted dram on the base fvp */
#define TZDRAM_BASE 0x06000000
#define TZDRAM_SIZE 0x02000000
#define MBOX_OFF 0x1000
#define AFFMAP_OFF 0x1200
#define DRAM_BASE 0x80000000ull
#define DRAM_SIZE 0x80000000ull
#define PCIE_EXP_BASE 0x40000000
#define TZRNG_BASE 0x7fe60000
#define TZNVCTR_BASE 0x7fe70000
#define TZROOTKEY_BASE 0x7fe80000
/* Memory mapped Generic timer interfaces */
#define SYS_CNTCTL_BASE 0x2a430000
/* Counter timer module offsets */
#define CNTNSAR 0x4
#define CNTNSAR_NS_SHIFT(x) x
#define CNTACR_BASE(x) (0x40 + (x << 2))
#define CNTACR_RPCT_SHIFT 0x0
#define CNTACR_RVCT_SHIFT 0x1
#define CNTACR_RFRQ_SHIFT 0x2
#define CNTACR_RVOFF_SHIFT 0x3
#define CNTACR_RWVT_SHIFT 0x4
#define CNTACR_RWPT_SHIFT 0x5
/*******************************************************************************
* BL2 specific defines.
******************************************************************************/
#define BL2_BASE 0x0402D000
/*******************************************************************************
* BL31 specific defines.
******************************************************************************/
#define BL31_BASE 0x0400C000
/*******************************************************************************
* Platform specific page table and MMU setup constants
******************************************************************************/
#define EL3_ADDR_SPACE_SIZE (1ull << 32)
#define EL3_NUM_PAGETABLES 2
#define EL3_TROM_PAGETABLE 0
#define EL3_TRAM_PAGETABLE 1
#define ADDR_SPACE_SIZE (1ull << 32)
#define NUM_L2_PAGETABLES 2
#define GB1_L2_PAGETABLE 0
#define GB2_L2_PAGETABLE 1
#define NUM_L3_PAGETABLES 2
#define TZRAM_PAGETABLE 0
#define NSRAM_PAGETABLE 1
/*******************************************************************************
* CCI-400 related constants
******************************************************************************/
#define CCI400_BASE 0x2c090000
#define CCI400_SL_IFACE_CLUSTER0 3
#define CCI400_SL_IFACE_CLUSTER1 4
#define CCI400_SL_IFACE_INDEX(mpidr) (mpidr & MPIDR_CLUSTER_MASK ? \
CCI400_SL_IFACE_CLUSTER1 : \
CCI400_SL_IFACE_CLUSTER0)
/*******************************************************************************
* GIC-400 & interrupt handling related constants
******************************************************************************/
/* VE compatible GIC memory map */
#define VE_GICD_BASE 0x2c001000
#define VE_GICC_BASE 0x2c002000
#define VE_GICH_BASE 0x2c004000
#define VE_GICV_BASE 0x2c006000
/* Base FVP compatible GIC memory map */
#define BASE_GICD_BASE 0x2f000000
#define BASE_GICR_BASE 0x2f100000
#define BASE_GICC_BASE 0x2c000000
#define BASE_GICH_BASE 0x2c010000
#define BASE_GICV_BASE 0x2c02f000
#define IRQ_TZ_WDOG 56
#define IRQ_SEC_PHY_TIMER 29
#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
******************************************************************************/
#define PL011_UART0_BASE 0x1c090000
#define PL011_UART1_BASE 0x1c0a0000
#define PL011_UART2_BASE 0x1c0b0000
#define PL011_UART3_BASE 0x1c0c0000
#define PL011_BASE PL011_UART0_BASE
/*******************************************************************************
* 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)
#ifndef __ASSEMBLY__
typedef volatile struct {
unsigned long value
__attribute__((__aligned__(CACHE_WRITEBACK_GRANULE)));
} mailbox;
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
extern unsigned long *bl1_normal_ram_base;
extern unsigned long *bl1_normal_ram_len;
extern unsigned long *bl1_normal_ram_limit;
extern unsigned long *bl1_normal_ram_zi_base;
extern unsigned long *bl1_normal_ram_zi_len;
extern unsigned long *bl1_coherent_ram_base;
extern unsigned long *bl1_coherent_ram_len;
extern unsigned long *bl1_coherent_ram_limit;
extern unsigned long *bl1_coherent_ram_zi_base;
extern unsigned long *bl1_coherent_ram_zi_len;
extern unsigned long warm_boot_entrypoint;
extern void bl1_plat_arch_setup(void);
extern void bl2_plat_arch_setup(void);
extern void bl31_plat_arch_setup(void);
extern int platform_setup_pm(plat_pm_ops **);
extern unsigned int platform_get_core_pos(unsigned long mpidr);
extern void disable_mmu(void);
extern void enable_mmu(void);
extern void configure_mmu(meminfo *,
unsigned long,
unsigned long,
unsigned long,
unsigned long);
extern void plat_report_exception(unsigned long);
extern unsigned long plat_get_ns_image_entrypoint(void);
extern unsigned long platform_get_stack(unsigned long mpidr);
/* Declarations for fvp_gic.c */
extern void gic_cpuif_deactivate(unsigned int);
extern void gic_cpuif_setup(unsigned int);
extern void gic_pcpu_distif_setup(unsigned int);
extern void gic_setup(void);
/* Declarations for fvp_topology.c */
extern int plat_setup_topology(void);
extern int plat_get_max_afflvl(void);
extern unsigned int plat_get_aff_count(unsigned int, unsigned long);
extern unsigned int plat_get_aff_state(unsigned int, unsigned long);
/* Declarations for plat_io_storage.c */
extern void io_setup(void);
extern int plat_get_image_source(const char *image_name,
io_dev_handle *dev_handle, void **image_spec);
#endif /*__ASSEMBLY__*/
#endif /* __PLATFORM_H__ */

87
plat/juno/platform.mk Normal file
View File

@ -0,0 +1,87 @@
#
# 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 := -Idrivers/arm/interconnect/cci-400 \
-Idrivers/arm/peripherals/pl011 \
-Idrivers/power
PLAT_BL1_C_VPATH := drivers/arm/interconnect/cci-400 \
drivers/arm/peripherals/pl011 \
lib/semihosting \
lib/stdlib \
drivers/io
PLAT_BL1_S_VPATH := lib/semihosting/${ARCH}
PLAT_BL2_C_VPATH := drivers/arm/interconnect/cci-400 \
drivers/arm/peripherals/pl011 \
lib/stdlib \
lib/semihosting \
drivers/io
PLAT_BL2_S_VPATH := lib/semihosting/${ARCH}
PLAT_BL31_C_VPATH := drivers/arm/interconnect/cci-400 \
drivers/arm/peripherals/pl011 \
lib/semihosting \
lib/stdlib \
drivers/power \
drivers/io
PLAT_BL31_S_VPATH := lib/semihosting/${ARCH}
PLAT_BL_COMMON_SOURCES := semihosting_call.S \
mmio.c \
pl011.c \
semihosting.c \
sysreg_helpers.S \
plat_io_storage.c \
io_semihosting.c \
io_fip.c \
io_memmap.c
BL1_SOURCES += bl1_plat_setup.c \
bl1_plat_helpers.S \
plat_helpers.S \
plat_common.c \
cci400.c
BL2_SOURCES += bl2_plat_setup.c \
plat_common.c
BL31_SOURCES += bl31_plat_setup.c \
plat_helpers.S \
plat_common.c \
plat_pm.c \
plat_topology.c \
plat_gic.c \
cci400.c \
gic_v2.c \
gic_v3.c