gxl_bl31_setup.c 5 KB
Newer Older
1
/*
2
 * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
3
4
5
6
7
8
9
10
11
12
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <common/bl_common.h>
#include <drivers/arm/gicv2.h>
#include <common/interrupt_props.h>
#include <plat/common/platform.h>
#include <platform_def.h>
13
#include <lib/mmio.h>
14
15
#include <lib/xlat_tables/xlat_mmu_helpers.h>

16
#include "aml_private.h"
17
18
19
20
21
22

/*
 * Placeholder variables for copying the arguments that have been passed to
 * BL31 from BL2.
 */
static entry_point_info_t bl33_image_ep_info;
23
24
static image_info_t bl30_image_info;
static image_info_t bl301_image_info;
25
26
27
28
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

/*******************************************************************************
 * Return a pointer to the 'entry_point_info' structure of the next image for
 * the security state specified. BL33 corresponds to the non-secure image type
 * while BL32 corresponds to the secure image type. A NULL pointer is returned
 * if the image does not exist.
 ******************************************************************************/
entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
{
	entry_point_info_t *next_image_info;

	assert(type == NON_SECURE);

	next_image_info = &bl33_image_ep_info;

	/* None of the images can have 0x0 as the entrypoint. */
	if (next_image_info->pc != 0U) {
		return next_image_info;
	} else {
		return NULL;
	}
}

/*******************************************************************************
 * Perform any BL31 early platform setup. Here is an opportunity to copy
 * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before
 * they are lost (potentially). This needs to be done before the MMU is
 * initialized so that the memory layout can be used while creating page
 * tables. BL2 has flushed this information to memory, so we are guaranteed
 * to pick up good data.
 ******************************************************************************/
56
struct gxl_bl31_param {
57
58
59
60
61
62
	param_header_t h;
	image_info_t *bl31_image_info;
	entry_point_info_t *bl32_ep_info;
	image_info_t *bl32_image_info;
	entry_point_info_t *bl33_ep_info;
	image_info_t *bl33_image_info;
63
	image_info_t *scp_image_info[];
64
65
66
67
68
};

void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
				u_register_t arg2, u_register_t arg3)
{
69
	struct gxl_bl31_param *from_bl2;
70
71

	/* Initialize the console to provide early debug support */
72
	aml_console_init();
73
74

	/* Check that params passed from BL2 are not NULL. */
75
	from_bl2 = (struct gxl_bl31_param *) arg0;
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

	/* Check params passed from BL2 are not NULL. */
	assert(from_bl2 != NULL);
	assert(from_bl2->h.type == PARAM_BL31);
	assert(from_bl2->h.version >= VERSION_1);

	/*
	 * Copy BL33 entry point information. It is stored in Secure RAM, in
	 * BL2's address space.
	 */
	bl33_image_ep_info = *from_bl2->bl33_ep_info;

	if (bl33_image_ep_info.pc == 0U) {
		ERROR("BL31: BL33 entrypoint not obtained from BL2\n");
		panic();
	}
92
93
94

	bl30_image_info = *from_bl2->scp_image_info[0];
	bl301_image_info = *from_bl2->scp_image_info[1];
95
96
97
98
}

void bl31_plat_arch_setup(void)
{
99
	aml_setup_page_tables();
100
101
102
103

	enable_mmu_el3(0);
}

104
105
106
107
108
static inline bool gxl_scp_ready(void)
{
	return GXBB_AO_RTI_SCP_IS_READY(mmio_read_32(GXBB_AO_RTI_SCP_STAT));
}

109
110
111
112
113
114
static inline void gxl_scp_boot(void)
{
	scpi_upload_scp_fw(bl30_image_info.image_base,
			bl30_image_info.image_size, 0);
	scpi_upload_scp_fw(bl301_image_info.image_base,
			bl301_image_info.image_size, 1);
115
116
	while (!gxl_scp_ready())
		;
117
118
}

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*******************************************************************************
 * GICv2 driver setup information
 ******************************************************************************/
static const interrupt_prop_t gxbb_interrupt_props[] = {
	INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
	INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY,
		       GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL),
};

static const gicv2_driver_data_t gxbb_gic_data = {
144
145
	.gicd_base = AML_GICD_BASE,
	.gicc_base = AML_GICC_BASE,
146
147
148
149
150
151
	.interrupt_props = gxbb_interrupt_props,
	.interrupt_props_num = ARRAY_SIZE(gxbb_interrupt_props),
};

void bl31_platform_setup(void)
{
152
	aml_mhu_secure_init();
153
154
155
156
157
158

	gicv2_driver_init(&gxbb_gic_data);
	gicv2_distif_init();
	gicv2_pcpu_distif_init();
	gicv2_cpuif_enable();

159
160
	gxl_scp_boot();

161
	aml_thermal_unknown();
162
}