1 /*
2  * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 
9 #include "rse_bringup_helpers.h"
10 
11 #include "rse_bringup_helpers_hal.h"
12 #include "platform_base_address.h"
13 #include "boot_hal.h"
14 #include "flash_layout.h"
15 #include "device_definition.h"
16 #include "gpio_pl061_drv.h"
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 
check_gpio_pins(void)21 static uint8_t check_gpio_pins(void)
22 {
23     uint32_t pins_offset = rse_bringup_helpers_hal_get_pins_offset();
24 
25     return (pl061_get_gpio(GPIO0_DEV_S, UINT8_MAX) >> pins_offset) & 0b11;
26 }
27 
get_gppc_val(void)28 static uint16_t get_gppc_val(void)
29 {
30     struct lcm_otp_layout_t *lcm = ((struct lcm_otp_layout_t *)(LCM_BASE_S
31                                                                 + LCM_OTP_OFFSET));
32     return (lcm->cm_config_2 >> 8) & 0xFFFF;
33 }
34 
boot_address(struct boot_arm_vector_table * vt)35 static void boot_address(struct boot_arm_vector_table *vt)
36 {
37     /* Clang at O0, stores variables on the stack with SP relative addressing.
38      * When manually set the SP th)en the place of reset vector is lost.
39      * Static variables are stored in 'data' or 'bss' section, change of SP has
40      * no effect on them.
41      */
42     static struct boot_arm_vector_table *vt_cpy;
43 
44     vt_cpy = vt;
45 
46     /* Restore the Main Stack Pointer Limit register's reset value
47      * before passing execution to runtime firmware to make the
48      * bootloader transparent to it.
49      */
50     __set_MSPLIM(0);
51 
52     __set_MSP(vt_cpy->msp);
53     __DSB();
54     __ISB();
55 
56     boot_jump_to_next_image(vt_cpy->reset);
57 }
58 
rse_run_bringup_helpers_if_requested(void)59 void rse_run_bringup_helpers_if_requested(void)
60 {
61     uint8_t gpio_pins_value = check_gpio_pins();
62     uint8_t gppc_val = get_gppc_val();
63 
64     switch (gppc_val & 0b11) {
65         case 0:
66             break;
67         case 1:
68             boot_address(rse_bringup_helpers_hal_get_vm0_exec_address());
69             break;
70         case 2:
71             boot_address(rse_bringup_helpers_hal_get_qpsi_exec_address());
72             break;
73         case 3:
74             boot_address(rse_bringup_helpers_hal_get_side_band_exec_address());
75             break;
76     }
77 
78     switch (gpio_pins_value) {
79         case 0:
80             break;
81         case 1:
82             boot_address(rse_bringup_helpers_hal_get_vm0_exec_address());
83             break;
84         case 2:
85             boot_address(rse_bringup_helpers_hal_get_qpsi_exec_address());
86             break;
87         case 3:
88             boot_address(rse_bringup_helpers_hal_get_side_band_exec_address());
89             break;
90     }
91 }
92