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