1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (C) 2018 Marvell International Ltd. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu * https://spdx.org/licenses 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <string.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <platform_def.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include <arch_helpers.h> 13*91f16700Schasinglulu #include <common/debug.h> 14*91f16700Schasinglulu #include <drivers/console.h> 15*91f16700Schasinglulu 16*91f16700Schasinglulu #include <marvell_plat_priv.h> 17*91f16700Schasinglulu #include <marvell_pm.h> 18*91f16700Schasinglulu #include <plat_marvell.h> 19*91f16700Schasinglulu 20*91f16700Schasinglulu #define BR_FLAG_SILENT 0x1 21*91f16700Schasinglulu #define SKIP_IMAGE_CODE 0xDEADB002 22*91f16700Schasinglulu 23*91f16700Schasinglulu void mailbox_clean(void) 24*91f16700Schasinglulu { 25*91f16700Schasinglulu uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; 26*91f16700Schasinglulu 27*91f16700Schasinglulu memset(mailbox, 0, PLAT_MARVELL_MAILBOX_SIZE); 28*91f16700Schasinglulu } 29*91f16700Schasinglulu 30*91f16700Schasinglulu int exec_ble_main(int bootrom_flags) 31*91f16700Schasinglulu { 32*91f16700Schasinglulu int skip = 0; 33*91f16700Schasinglulu uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE; 34*91f16700Schasinglulu 35*91f16700Schasinglulu /* 36*91f16700Schasinglulu * In some situations, like boot from UART, bootrom will 37*91f16700Schasinglulu * request to avoid printing to console. in that case don't 38*91f16700Schasinglulu * initialize the console and prints will be ignored 39*91f16700Schasinglulu */ 40*91f16700Schasinglulu if ((bootrom_flags & BR_FLAG_SILENT) == 0) 41*91f16700Schasinglulu marvell_console_boot_init(); 42*91f16700Schasinglulu 43*91f16700Schasinglulu NOTICE("Starting binary extension\n"); 44*91f16700Schasinglulu 45*91f16700Schasinglulu /* initialize time (for delay functionality) */ 46*91f16700Schasinglulu plat_delay_timer_init(); 47*91f16700Schasinglulu 48*91f16700Schasinglulu ble_plat_setup(&skip); 49*91f16700Schasinglulu 50*91f16700Schasinglulu /* if there's skip image request, bootrom will load from the image 51*91f16700Schasinglulu * saved on the next address of the flash 52*91f16700Schasinglulu */ 53*91f16700Schasinglulu if (skip) 54*91f16700Schasinglulu return SKIP_IMAGE_CODE; 55*91f16700Schasinglulu 56*91f16700Schasinglulu /* 57*91f16700Schasinglulu * Check if the mailbox magic number is stored at index MBOX_IDX_MAGIC 58*91f16700Schasinglulu * and the suspend to RAM magic number at index MBOX_IDX_SUSPEND_MAGIC. 59*91f16700Schasinglulu * If the above is true, this is the recovery from suspend to RAM state. 60*91f16700Schasinglulu * In such case the mailbox should remain intact, since it stores the 61*91f16700Schasinglulu * warm boot jump address to be used by the TF-A in BL31. 62*91f16700Schasinglulu * Othervise the mailbox should be cleaned from a garbage data. 63*91f16700Schasinglulu */ 64*91f16700Schasinglulu if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM || 65*91f16700Schasinglulu mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE) { 66*91f16700Schasinglulu NOTICE("Cold boot\n"); 67*91f16700Schasinglulu mailbox_clean(); 68*91f16700Schasinglulu } else { 69*91f16700Schasinglulu void (*bootrom_exit)(void) = 70*91f16700Schasinglulu (void (*)(void))mailbox[MBOX_IDX_ROM_EXIT_ADDR]; 71*91f16700Schasinglulu 72*91f16700Schasinglulu INFO("Recovery...\n"); 73*91f16700Schasinglulu /* 74*91f16700Schasinglulu * If this is recovery from suspend, two things has to be done: 75*91f16700Schasinglulu * 1. Define the DRAM region as executable memory for preparing 76*91f16700Schasinglulu * jump to TF-A 77*91f16700Schasinglulu * 2. Instead of returning control to the BootROM, invalidate 78*91f16700Schasinglulu * and flush caches, and continue execution at address stored 79*91f16700Schasinglulu * in the mailbox. 80*91f16700Schasinglulu * This should be done until the BootROM have a native support 81*91f16700Schasinglulu * for the system restore flow. 82*91f16700Schasinglulu */ 83*91f16700Schasinglulu marvell_ble_prepare_exit(); 84*91f16700Schasinglulu bootrom_exit(); 85*91f16700Schasinglulu } 86*91f16700Schasinglulu 87*91f16700Schasinglulu return 0; 88*91f16700Schasinglulu } 89*91f16700Schasinglulu 90*91f16700Schasinglulu /* NOTE: don't notify this function, all code must be added to exec_ble_main 91*91f16700Schasinglulu * in order to keep the end of ble_main as a fixed address. 92*91f16700Schasinglulu */ 93*91f16700Schasinglulu int __attribute__ ((section(".entry"))) ble_main(int bootrom_flags) 94*91f16700Schasinglulu { 95*91f16700Schasinglulu volatile int ret; 96*91f16700Schasinglulu 97*91f16700Schasinglulu ret = exec_ble_main(bootrom_flags); 98*91f16700Schasinglulu return ret; 99*91f16700Schasinglulu } 100