Commit f8b0b22a authored by Dan Handley's avatar Dan Handley
Browse files

Migrate Juno port to use common code

Major update to the Juno platform port to use the common platform code
in (include/)plat/arm/* and (include/)plat/common/*. This mainly
consists of removing duplicated code but also introduces some small
behavioural changes where there was unnecessary variation between the
FVP and Juno ports. See earlier commit titled `Add common ARM and CSS
platform code` for details.

Also move the ARM SoC specific security setup (i.e. NIC-400 and PCIe
initialization) from BL1 to `plat_arm_security_setup()` in BL2,
where the other security setup is done.

Change-Id: Ic9fe01bae8ed382bfb04fc5839a4cfff332eb124
parent 3fc4124c
/*
* 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();
}
/*
* 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
/*
* 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 */
scpi_status_t 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_t cpu_state,
scpi_power_state_t cluster_state, scpi_power_state_t 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);
}
uint32_t scpi_sys_power_state(scpi_system_state_t system_state)
{
uint32_t *response;
size_t size;
uint8_t state = system_state & 0xff;
/* Send the command */
*(__typeof__(state) *)scpi_secure_message_start() = state;
scpi_secure_message_send(SCPI_CMD_SYS_POWER_STATE, sizeof(state));
scpi_secure_message_receive((void *)&response, &size);
scpi_secure_message_end();
return *response;
}
/*
* 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 scpi_status_t;
typedef enum {
SCPI_CMD_SCP_READY = 0x01,
SCPI_CMD_SET_CSS_POWER_STATE = 0x04,
SCPI_CMD_SYS_POWER_STATE = 0x08
} scpi_command_t;
typedef enum {
scpi_power_on = 0,
scpi_power_retention = 1,
scpi_power_off = 3,
} scpi_power_state_t;
typedef enum {
scpi_system_shutdown = 0,
scpi_system_reboot = 1,
scpi_system_reset = 2
} scpi_system_state_t;
extern int scpi_wait_ready(void);
extern void scpi_set_css_power_state(unsigned mpidr, scpi_power_state_t cpu_state,
scpi_power_state_t cluster_state, scpi_power_state_t css_state);
uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
#endif /* __SCPI_H__ */
#
# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2014-2015, 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:
......@@ -28,10 +28,4 @@
# POSSIBILITY OF SUCH DAMAGE.
#
# TSP source files specific to Juno platform
BL32_SOURCES += drivers/arm/gic/arm_gic.c \
drivers/arm/gic/gic_v2.c \
plat/common/aarch64/platform_mp_stack.S \
plat/juno/aarch64/juno_common.c \
plat/juno/aarch64/plat_helpers.S \
plat/juno/tsp/tsp_plat_setup.c
include plat/arm/common/tsp/arm_tsp.mk
/*
* 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 <bl_common.h>
#include <console.h>
#include <platform_tsp.h>
#include "../juno_def.h"
#include "../juno_private.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 __BL32_END__;
#if USE_COHERENT_MEM
extern unsigned long __COHERENT_RAM_START__;
extern unsigned long __COHERENT_RAM_END__;
#endif
/*
* The next 3 constants identify the extents of the code, RO data region and the
* limit of the BL3-2 image. 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__, __RO_END__ & __BL32_END__ linker symbols
* refer to page-aligned addresses.
*/
#define BL32_RO_BASE (unsigned long)(&__RO_START__)
#define BL32_RO_LIMIT (unsigned long)(&__RO_END__)
#define BL32_END (unsigned long)(&__BL32_END__)
#if USE_COHERENT_MEM
/*
* 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 BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#endif
/*******************************************************************************
* Initialize the UART
******************************************************************************/
void tsp_early_platform_setup(void)
{
/*
* Initialize a different console than already in use to display
* messages from TSP
*/
console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
}
/*******************************************************************************
* Perform platform specific setup placeholder
******************************************************************************/
void tsp_platform_setup(void)
{
plat_gic_init();
}
/*******************************************************************************
* Perform the very early platform specific architectural setup here. At the
* moment this only intializes the MMU
******************************************************************************/
void tsp_plat_arch_setup(void)
{
configure_mmu_el1(BL32_RO_BASE,
(BL32_END - BL32_RO_BASE),
BL32_RO_BASE,
BL32_RO_LIMIT
#if USE_COHERENT_MEM
, BL32_COHERENT_RAM_BASE,
BL32_COHERENT_RAM_LIMIT
#endif
);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment