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