1 /*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <arch_helpers.h>
8 #include <assert.h>
9 #include <bl_common.h>
10 #include <console.h>
11 #include <debug.h>
12 #include <errno.h>
13 #include <generic_delay_timer.h>
14 #include <mmio.h>
15 #include <partition/partition.h>
16 #include <platform.h>
17 #include <string.h>
18 #include "hi3798cv200.h"
19 #include "plat_private.h"
20
21 /* Memory ranges for code and read only data sections */
22 #define BL2_RO_BASE (unsigned long)(&__RO_START__)
23 #define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
24
25 /* Memory ranges for coherent memory section */
26 #define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
27 #define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
28
29 typedef struct bl2_to_bl31_params_mem {
30 bl31_params_t bl31_params;
31 image_info_t bl31_image_info;
32 image_info_t bl33_image_info;
33 entry_point_info_t bl33_ep_info;
34 entry_point_info_t bl31_ep_info;
35 } bl2_to_bl31_params_mem_t;
36
37 static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
38 static bl2_to_bl31_params_mem_t bl31_params_mem;
39
bl2_plat_sec_mem_layout(void)40 meminfo_t *bl2_plat_sec_mem_layout(void)
41 {
42 return &bl2_tzram_layout;
43 }
44
bl2_plat_get_bl31_params(void)45 bl31_params_t *bl2_plat_get_bl31_params(void)
46 {
47 bl31_params_t *bl2_to_bl31_params = NULL;
48
49 /*
50 * Initialise the memory for all the arguments that needs to
51 * be passed to BL3-1
52 */
53 memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
54
55 /* Assign memory for TF related information */
56 bl2_to_bl31_params = &bl31_params_mem.bl31_params;
57 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
58
59 /* Fill BL3-1 related information */
60 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
61 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
62 PARAM_IMAGE_BINARY, VERSION_1, 0);
63
64 /* Fill BL3-3 related information */
65 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
66 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
67 PARAM_EP, VERSION_1, 0);
68
69 /* BL3-3 expects to receive the primary CPU MPID (through x0) */
70 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
71
72 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
73 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
74 PARAM_IMAGE_BINARY, VERSION_1, 0);
75
76 return bl2_to_bl31_params;
77 }
78
bl2_plat_get_bl31_ep_info(void)79 struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
80 {
81 return &bl31_params_mem.bl31_ep_info;
82 }
83
bl2_plat_set_bl31_ep_info(image_info_t * image,entry_point_info_t * bl31_ep_info)84 void bl2_plat_set_bl31_ep_info(image_info_t *image,
85 entry_point_info_t *bl31_ep_info)
86 {
87 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
88 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
89 DISABLE_ALL_EXCEPTIONS);
90 }
91
hisi_get_spsr_for_bl33_entry(void)92 static uint32_t hisi_get_spsr_for_bl33_entry(void)
93 {
94 unsigned long el_status;
95 unsigned int mode;
96 uint32_t spsr;
97
98 /* Figure out what mode we enter the non-secure world in */
99 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
100 el_status &= ID_AA64PFR0_ELX_MASK;
101
102 mode = (el_status) ? MODE_EL2 : MODE_EL1;
103
104 /*
105 * TODO: Consider the possibility of specifying the SPSR in
106 * the FIP ToC and allowing the platform to have a say as
107 * well.
108 */
109 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
110 return spsr;
111 }
112
bl2_plat_set_bl33_ep_info(image_info_t * image,entry_point_info_t * bl33_ep_info)113 void bl2_plat_set_bl33_ep_info(image_info_t *image,
114 entry_point_info_t *bl33_ep_info)
115 {
116 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
117 bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
118 bl33_ep_info->args.arg2 = image->image_size;
119 }
120
bl2_plat_flush_bl31_params(void)121 void bl2_plat_flush_bl31_params(void)
122 {
123 flush_dcache_range((unsigned long)&bl31_params_mem,
124 sizeof(bl2_to_bl31_params_mem_t));
125 }
126
bl2_plat_get_bl33_meminfo(meminfo_t * bl33_meminfo)127 void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
128 {
129 bl33_meminfo->total_base = DDR_BASE;
130 bl33_meminfo->total_size = DDR_SIZE;
131 bl33_meminfo->free_base = DDR_BASE;
132 bl33_meminfo->free_size = DDR_SIZE;
133 }
134
bl2_early_platform_setup(meminfo_t * mem_layout)135 void bl2_early_platform_setup(meminfo_t *mem_layout)
136 {
137 console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
138
139 /* Enable arch timer */
140 generic_delay_timer_init();
141
142 bl2_tzram_layout = *mem_layout;
143 }
144
bl2_plat_arch_setup(void)145 void bl2_plat_arch_setup(void)
146 {
147 plat_configure_mmu_el1(bl2_tzram_layout.total_base,
148 bl2_tzram_layout.total_size,
149 BL2_RO_BASE,
150 BL2_RO_LIMIT,
151 BL2_COHERENT_RAM_BASE,
152 BL2_COHERENT_RAM_LIMIT);
153 }
154
bl2_platform_setup(void)155 void bl2_platform_setup(void)
156 {
157 plat_io_setup();
158 }
159
plat_get_ns_image_entrypoint(void)160 unsigned long plat_get_ns_image_entrypoint(void)
161 {
162 return PLAT_ARM_NS_IMAGE_OFFSET;
163 }
164