/*
 * 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);
}
