blob: da585798ded208eaa5bb3b363e66b810a66e9965 [file] [log] [blame]
/*
* Copyright (c) 2018-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <drivers/arm/sp805.h>
#include <drivers/console.h>
#include <platform.h>
#include <xlat_tables_v2.h>
/*
* The following platform functions are all weakly defined. They provide typical
* implementations that may be re-used by multiple platforms but may also be
* overridden by a platform if required.
*/
#pragma weak tftf_platform_end
#pragma weak tftf_platform_watchdog_set
#pragma weak tftf_platform_watchdog_reset
#pragma weak tftf_plat_configure_mmu
#pragma weak tftf_plat_enable_mmu
#pragma weak tftf_plat_reset
#pragma weak plat_get_prot_regions
#pragma weak plat_pcie_get_info_table
#pragma weak plat_get_invalid_addr
#if IMAGE_TFTF
#define IMAGE_TEXT_BASE TFTF_BASE
IMPORT_SYM(uintptr_t, __TEXT_END__, IMAGE_TEXT_END);
#define IMAGE_RODATA_BASE IMAGE_TEXT_END
IMPORT_SYM(uintptr_t, __RODATA_END__, IMAGE_RODATA_END);
#define IMAGE_RW_BASE IMAGE_RODATA_END
IMPORT_SYM(uintptr_t, __TFTF_END__, IMAGE_RW_END);
IMPORT_SYM(uintptr_t, __COHERENT_RAM_START__, COHERENT_RAM_START);
IMPORT_SYM(uintptr_t, __COHERENT_RAM_END__, COHERENT_RAM_END);
#elif IMAGE_NS_BL1U
#define IMAGE_TEXT_BASE NS_BL1U_BASE
IMPORT_SYM(uintptr_t, __TEXT_END__, IMAGE_TEXT_END);
#define IMAGE_RODATA_BASE IMAGE_TEXT_END
IMPORT_SYM(uintptr_t, __RODATA_END__, IMAGE_RODATA_END);
#define IMAGE_RW_BASE NS_BL1U_RW_BASE
IMPORT_SYM(uintptr_t, __NS_BL1U_RAM_END__, IMAGE_RW_END);
#elif IMAGE_NS_BL2U
#define IMAGE_TEXT_BASE NS_BL2U_BASE
IMPORT_SYM(uintptr_t, __TEXT_END__, IMAGE_TEXT_END);
#define IMAGE_RODATA_BASE IMAGE_TEXT_END
IMPORT_SYM(uintptr_t, __RODATA_END__, IMAGE_RODATA_END);
#define IMAGE_RW_BASE IMAGE_RODATA_END
IMPORT_SYM(uintptr_t, __NS_BL2U_END__, IMAGE_RW_END_UNALIGNED);
#define IMAGE_RW_END round_up(IMAGE_RW_END_UNALIGNED, PAGE_SIZE)
#endif
void tftf_platform_end(void)
{
/*
* Send EOT (End Of Transmission) on the UART.
* This can be used to shutdown a software model.
*/
static const char ascii_eot = 4;
console_putc(ascii_eot);
}
void tftf_platform_watchdog_set(void)
{
/* Placeholder function which should be redefined by each platform */
}
void tftf_platform_watchdog_reset(void)
{
/* Placeholder function which should be redefined by each platform */
}
void tftf_plat_configure_mmu(void)
{
/* Code */
mmap_add_region(IMAGE_TEXT_BASE, IMAGE_TEXT_BASE,
IMAGE_TEXT_END - IMAGE_TEXT_BASE, MT_CODE | MT_NS);
/* RO data */
mmap_add_region(IMAGE_RODATA_BASE, IMAGE_RODATA_BASE,
IMAGE_RODATA_END - IMAGE_RODATA_BASE, MT_RO_DATA | MT_NS);
/* Data + BSS */
mmap_add_region(IMAGE_RW_BASE, IMAGE_RW_BASE,
IMAGE_RW_END - IMAGE_RW_BASE, MT_RW_DATA | MT_NS);
#if IMAGE_TFTF
mmap_add_region(COHERENT_RAM_START, COHERENT_RAM_START,
COHERENT_RAM_END - COHERENT_RAM_START,
MT_DEVICE | MT_RW | MT_NS);
#endif
mmap_add(tftf_platform_get_mmap());
init_xlat_tables();
tftf_plat_enable_mmu();
}
void tftf_plat_enable_mmu(void)
{
#ifdef __aarch64__
if (IS_IN_EL1())
enable_mmu_el1(0);
else if (IS_IN_EL2())
enable_mmu_el2(0);
else
panic();
#else
if (IS_IN_HYP())
enable_mmu_hyp(0);
else
enable_mmu_svc_mon(0);
#endif
}
void tftf_plat_reset(void)
{
/*
* SP805 peripheral interrupt is not serviced in TFTF. The reset signal
* generated by it is used to reset the platform.
*/
sp805_wdog_start(1);
/*
* Reset might take some execution cycles, Depending on the ratio between
* CPU clock frequency and Watchdog clock frequency
*/
while (1)
;
}
const mem_region_t *plat_get_prot_regions(int *nelem)
{
*nelem = 0;
return NULL;
}
const struct pcie_info_table *plat_pcie_get_info_table(void)
{
return NULL;
}
uintptr_t plat_get_invalid_addr(void)
{
return (uintptr_t)0x0;
}