bl2_plat_setup.c 5.73 KB
Newer Older
1
2
3
4
5
6
7
8
9
/*
 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <string.h>
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
#include <drivers/arm/pl011.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/partition/partition.h>
#include <drivers/synopsys/dw_mmc.h>
#include <drivers/mmc.h>
#include <lib/mmio.h>
#include <lib/optee_utils.h>
#include <plat/common/platform.h>

24
25
26
#include "hi3798cv200.h"
#include "plat_private.h"

27
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
28
static console_pl011_t console;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

/*******************************************************************************
 * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
 * Return 0 on success, -1 otherwise.
 ******************************************************************************/
int plat_poplar_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
{
	/*
	 * This platform has no SCP_BL2 yet
	 */
	return 0;
}

/*******************************************************************************
 * Gets SPSR for BL32 entry
 ******************************************************************************/
uint32_t poplar_get_spsr_for_bl32_entry(void)
{
	/*
	 * The Secure Payload Dispatcher service is responsible for
	 * setting the SPSR prior to entry into the BL3-2 image.
	 */
	return 0;
}

/*******************************************************************************
 * Gets SPSR for BL33 entry
 ******************************************************************************/
57
#ifdef __aarch64__
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
uint32_t poplar_get_spsr_for_bl33_entry(void)
{
	unsigned long el_status;
	unsigned int mode;
	uint32_t spsr;

	/* Figure out what mode we enter the non-secure world in */
	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
	el_status &= ID_AA64PFR0_ELX_MASK;

	mode = (el_status) ? MODE_EL2 : MODE_EL1;

	/*
	 * TODO: Consider the possibility of specifying the SPSR in
	 * the FIP ToC and allowing the platform to have a say as
	 * well.
	 */
	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
	return spsr;
}
#else
uint32_t poplar_get_spsr_for_bl33_entry(void)
{
	unsigned int hyp_status, mode, spsr;

	hyp_status = GET_VIRT_EXT(read_id_pfr1());

	mode = (hyp_status) ? MODE32_hyp : MODE32_svc;

	/*
	 * TODO: Consider the possibility of specifying the SPSR in
	 * the FIP ToC and allowing the platform to have a say as
	 * well.
	 */
	spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
			SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
	return spsr;
}
96
#endif /* __aarch64__ */
97
98
99
100
101

int poplar_bl2_handle_post_image_load(unsigned int image_id)
{
	int err = 0;
	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
102
103
104
105
#ifdef SPD_opteed
	bl_mem_params_node_t *pager_mem_params = NULL;
	bl_mem_params_node_t *paged_mem_params = NULL;
#endif
106
107
108
109

	assert(bl_mem_params);

	switch (image_id) {
110
#ifdef __aarch64__
111
	case BL32_IMAGE_ID:
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifdef SPD_opteed
		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
		assert(pager_mem_params);

		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
		assert(paged_mem_params);

		err = parse_optee_header(&bl_mem_params->ep_info,
				&pager_mem_params->image_info,
				&paged_mem_params->image_info);
		if (err != 0) {
			WARN("OPTEE header parse error.\n");
		}

		/*
		 * OP-TEE expect to receive DTB address in x2.
		 * This will be copied into x2 by dispatcher.
		 * Set this (arg3) if necessary
		 */
		/* bl_mem_params->ep_info.args.arg3 = PLAT_HIKEY_DT_BASE; */
#endif
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
		bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl32_entry();
		break;
#endif

	case BL33_IMAGE_ID:
		/* BL33 expects to receive the primary CPU MPID (through r0) */
		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
		bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl33_entry();
		break;

#ifdef SCP_BL2_BASE
	case SCP_BL2_IMAGE_ID:
		/* The subsequent handling of SCP_BL2 is platform specific */
		err = plat_poplar_bl2_handle_scp_bl2(&bl_mem_params->image_info);
		if (err) {
			WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
		}
		break;
#endif
152
153
154
	default:
		/* Do nothing in default case */
		break;
155
156
157
158
159
160
161
162
163
164
165
166
167
168
	}

	return err;
}

/*******************************************************************************
 * This function can be used by the platforms to update/use image
 * information for given `image_id`.
 ******************************************************************************/
int bl2_plat_handle_post_image_load(unsigned int image_id)
{
	return poplar_bl2_handle_post_image_load(image_id);
}

169
170
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
			       u_register_t arg2, u_register_t arg3)
171
{
172
	struct meminfo *mem_layout = (struct meminfo *)arg1;
173
#if !POPLAR_RECOVERY
174
175
	struct mmc_device_info info;

Victor Chong's avatar
Victor Chong committed
176
	dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
177
#endif
Victor Chong's avatar
Victor Chong committed
178

179
180
	console_pl011_register(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ,
			       PL011_BAUDRATE, &console);
181
182
183
184
185

	/* Enable arch timer */
	generic_delay_timer_init();

	bl2_tzram_layout = *mem_layout;
Victor Chong's avatar
Victor Chong committed
186

187
#if !POPLAR_RECOVERY
Victor Chong's avatar
Victor Chong committed
188
189
	/* SoC-specific emmc register are initialized/configured by bootrom */
	INFO("BL2: initializing emmc\n");
190
191
	info.mmc_dev_type = MMC_IS_EMMC;
	dw_mmc_init(&params, &info);
192
#endif
Victor Chong's avatar
Victor Chong committed
193
194

	plat_io_setup();
195
196
197
198
199
200
}

void bl2_plat_arch_setup(void)
{
	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
			       bl2_tzram_layout.total_size,
201
202
203
204
			       BL_CODE_BASE,
			       BL_CODE_END,
			       BL_COHERENT_RAM_BASE,
			       BL_COHERENT_RAM_END);
205
206
207
208
209
210
}

void bl2_platform_setup(void)
{
}

211
uintptr_t plat_get_ns_image_entrypoint(void)
212
{
213
214
215
#ifdef PRELOADED_BL33_BASE
	return PRELOADED_BL33_BASE;
#else
216
	return PLAT_POPLAR_NS_IMAGE_OFFSET;
217
#endif
218
}