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