bl1_context_mgmt.c 3.6 KB
Newer Older
1
/*
2
 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
7
 */

#include <assert.h>
8
9

#include <arch_helpers.h>
10
#include <context.h>
11
12
13
14
#include <common/debug.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <plat/common/platform.h>

15
#include "../bl1_private.h"
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

/* Following contains the cpu context pointers. */
static void *bl1_cpu_context_ptr[2];


void *cm_get_context(uint32_t security_state)
{
	assert(sec_state_is_valid(security_state));
	return bl1_cpu_context_ptr[security_state];
}

void cm_set_context(void *context, uint32_t security_state)
{
	assert(sec_state_is_valid(security_state));
	bl1_cpu_context_ptr[security_state] = context;
}

/*******************************************************************************
 * This function prepares the context for Secure/Normal world images.
 * Normal world images are transitioned to EL2(if supported) else EL1.
 ******************************************************************************/
void bl1_prepare_next_image(unsigned int image_id)
{
39
40
41
42
43
44
45

	/*
	 * Following array will be used for context management.
	 * There are 2 instances, for the Secure and Non-Secure contexts.
	 */
	static cpu_context_t bl1_cpu_context[2];

46
	unsigned int security_state, mode = MODE_EL1;
47
	image_desc_t *desc;
48
49
	entry_point_info_t *next_bl_ep;

50
51
52
53
54
#if CTX_INCLUDE_AARCH32_REGS
	/*
	 * Ensure that the build flag to save AArch32 system registers in CPU
	 * context is not set for AArch64-only platforms.
	 */
55
	if (el_implemented(1) == EL_IMPL_A64ONLY) {
56
		ERROR("EL1 supports AArch64-only. Please set build flag "
57
				"CTX_INCLUDE_AARCH32_REGS = 0\n");
58
59
60
61
		panic();
	}
#endif

62
	/* Get the image descriptor. */
63
64
	desc = bl1_plat_get_image_desc(image_id);
	assert(desc != NULL);
65
66

	/* Get the entry point info. */
67
	next_bl_ep = &desc->ep_info;
68
69

	/* Get the image security state. */
70
	security_state = GET_SECURITY_STATE(next_bl_ep->h.attr);
71
72

	/* Setup the Secure/Non-Secure context if not done already. */
73
	if (cm_get_context(security_state) == NULL)
74
75
76
		cm_set_context(&bl1_cpu_context[security_state], security_state);

	/* Prepare the SPSR for the next BL image. */
77
78
	if ((security_state != SECURE) && (el_implemented(2) != EL_IMPL_NONE)) {
		mode = MODE_EL2;
79
80
	}

81
82
	next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode,
		(uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
83

84
85
86
87
88
89
90
91
	/* Allow platform to make change */
	bl1_plat_set_ep_info(image_id, next_bl_ep);

	/* Prepare the context for the next BL image. */
	cm_init_my_context(next_bl_ep);
	cm_prepare_el3_exit(security_state);

	/* Indicate that image is in execution state. */
92
	desc->state = IMAGE_STATE_EXECUTED;
93
94
95

	print_entry_point_info(next_bl_ep);
}
johpow01's avatar
johpow01 committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

#if ENABLE_RME
/*******************************************************************************
 * This function prepares the entry point information to run BL2 in Root world
 * i.e. EL3. It then jumps into BL2 using this entry point information.
 ******************************************************************************/
void bl1_prepare_for_bl2_in_root(void)
{
	image_desc_t *bl2_desc;
	entry_point_info_t *bl2_ep_info;

	/* Get the image descriptor. */
	bl2_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
	assert(bl2_desc != NULL);

	/* Get the entry point info. */
	bl2_ep_info = &bl2_desc->ep_info;

	bl2_ep_info->spsr = (uint32_t)SPSR_64(MODE_EL3, MODE_SP_ELX,
						DISABLE_ALL_EXCEPTIONS);

	/* Indicate that image is in execution state. */
	bl2_desc->state = IMAGE_STATE_EXECUTED;

	/* Print debug info and flush the console before running BL2. */
	print_entry_point_info(bl2_ep_info);
	console_flush();

	bl1_run_bl2_in_root(bl2_ep_info);
}
#endif /* ENABLE_RME */