blob: 5478dde6cf60362e1efe75435da7de4878257fb4 [file] [log] [blame]
/*
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
*/
#include <arch_features.h>
#include <arm_memory.h>
#include <debug.h>
#include <pl011.h>
#include <plat_common.h>
#include <platform_api.h>
#include <rmm_el3_ifc.h>
#include <sizes.h>
#include <string.h>
#include <xlat_tables.h>
#define ARM_RMM_UART MAP_REGION_FLAT( \
0, \
SZ_4K, \
(MT_DEVICE | MT_RW | MT_REALM))
/*
* Local platform setup for RMM.
*
* This function will only be invoked during
* warm boot and is expected to setup architecture and platform
* components local to a PE executing RMM.
*/
/* coverity[misra_c_2012_rule_8_7_violation:SUPPRESS] */
void plat_warmboot_setup(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
{
/* Avoid MISRA C:2012-2.7 warnings */
(void)x0;
(void)x1;
(void)x2;
(void)x3;
if (plat_cmn_warmboot_setup() != 0) {
panic();
}
}
/*
* Global platform setup for RMM.
*
* This function will only be invoked once during cold boot
* and is expected to setup architecture and platform components
* common for all PEs executing RMM. The translation tables should
* be initialized by this function.
*/
/* coverity[misra_c_2012_rule_8_7_violation:SUPPRESS] */
void plat_setup(uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
{
int ret;
struct memory_info *plat_memory_info;
struct console_list *csl_list;
struct console_info *console_ptr;
const enum dev_type type[] = {DEV_RANGE_COHERENT, DEV_RANGE_NON_COHERENT};
/* TBD Initialize UART for early log */
struct xlat_mmap_region plat_regions[] = {
ARM_RMM_UART,
{0}
};
/* Initialize the RMM-EL3 interface*/
ret = plat_cmn_init_el3_ifc(x0, x1, x2, x3);
if (ret != E_RMM_BOOT_SUCCESS) {
rmm_el3_ifc_report_fail_to_el3(ret);
}
/* Initialize console first */
ret = rmm_el3_ifc_get_console_list_pa(&csl_list);
if (ret != 0) {
rmm_el3_ifc_report_fail_to_el3(ret);
}
/* If console_info is present, we need it to be pl011 */
if (csl_list->num_consoles != 0UL) {
uintptr_t uart_base;
unsigned int uart_clk, uart_baud;
console_ptr = &csl_list->consoles[0];
if (strncmp(console_ptr->name, "pl011", sizeof("pl011")) != 0) {
rmm_el3_ifc_report_fail_to_el3(E_RMM_BOOT_UNKNOWN_ERROR);
}
uart_base = console_ptr->base;
uart_clk = (unsigned int)console_ptr->clk_in_hz;
uart_baud = (unsigned int)console_ptr->baud_rate;
/* RMM currently only supports one console */
ret = pl011_init(uart_base, uart_clk, uart_baud);
if (ret != 0) {
rmm_el3_ifc_report_fail_to_el3(E_RMM_BOOT_UNKNOWN_ERROR);
}
plat_regions[0].base_pa = uart_base;
plat_regions[0].base_va = uart_base;
}
/* Carry on with the rest of the system setup */
ret = plat_cmn_setup(plat_regions, 1U);
if (ret != 0) {
ERROR("%s (%u): Failed to setup the platform (%i)\n",
__func__, __LINE__, ret);
rmm_el3_ifc_report_fail_to_el3(E_RMM_BOOT_UNKNOWN_ERROR);
}
/*
* Validate DRAM data and get pointer
* to the platform DRAM info structure
*/
ret = rmm_el3_ifc_get_dram_data_validated_pa(
PLAT_ARM_MAX_MEM_BANKS,
&plat_memory_info);
if (ret != E_RMM_BOOT_SUCCESS) {
ERROR("DRAM data error\n");
rmm_el3_ifc_report_fail_to_el3(ret);
}
/* Set up Arm DRAM layout */
arm_set_dram_layout(plat_memory_info);
/* cppcheck-suppress misra-c2012-14.2 */
for (unsigned int i = 0U; i < ARRAY_SIZE(type); i++) {
/*
* Validate device address ranges data and get pointer
* to the platform device address ranges info structure
*/
ret = rmm_el3_ifc_get_dev_range_validated_pa(
PLAT_ARM_MAX_MEM_BANKS,
&plat_memory_info,
type[i]);
if (ret == E_RMM_BOOT_MANIFEST_VERSION_NOT_SUPPORTED) {
break;
}
if (ret != E_RMM_BOOT_SUCCESS) {
ERROR("Device address ranges data error\n");
rmm_el3_ifc_report_fail_to_el3(ret);
}
if (plat_memory_info != NULL) {
/* Set up Arm device address ranges layout */
arm_set_dev_layout(plat_memory_info, type[i]);
}
}
plat_warmboot_setup(x0, x1, x2, x3);
}