blob: 88decdf4dd6170007546a965e0f70bd9a82500cc [file] [log] [blame]
Etienne Carriere911de8c2018-02-02 13:23:22 +01001/*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Etienne Carriere911de8c2018-02-02 13:23:22 +01007#include <assert.h>
Etienne Carriere911de8c2018-02-02 13:23:22 +01008#include <string.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009
10#include <platform_def.h>
11
12#include <arch_helpers.h>
13#include <common/bl_common.h>
14#include <common/debug.h>
15#include <drivers/arm/gic_common.h>
16#include <drivers/arm/gicv2.h>
17#include <drivers/console.h>
18#include <lib/mmio.h>
19#include <lib/xlat_tables/xlat_tables.h>
20#include <plat/common/platform.h>
21
Etienne Carriere911de8c2018-02-02 13:23:22 +010022#include "../qemu_private.h"
23
24#if RESET_TO_SP_MIN
25#error qemu does not support RESET_TO_SP_MIN
26#endif
27
28static entry_point_info_t bl33_image_ep_info;
29
30/*
31 * The next 3 constants identify the extents of the code, RO data region and the
32 * limit of the BL3-1 image. These addresses are used by the MMU setup code and
33 * therefore they must be page-aligned. It is the responsibility of the linker
34 * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols
35 * refer to page-aligned addresses.
36 */
37#define BL32_RO_BASE (unsigned long)(&__RO_START__)
38#define BL32_RO_LIMIT (unsigned long)(&__RO_END__)
39#define BL32_END (unsigned long)(&__BL32_END__)
40
41#if USE_COHERENT_MEM
42/*
43 * The next 2 constants identify the extents of the coherent memory region.
44 * These addresses are used by the MMU setup code and therefore they must be
45 * page-aligned. It is the responsibility of the linker script to ensure that
46 * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
47 * refer to page-aligned addresses.
48 */
49#define BL32_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
50#define BL32_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
51#endif
52
53/******************************************************************************
54 * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
55 * interrupts.
56 *****************************************************************************/
57#define PLATFORM_G1S_PROPS(grp) \
58 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \
59 grp, GIC_INTR_CFG_LEVEL), \
60 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \
61 grp, GIC_INTR_CFG_LEVEL), \
62 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \
63 grp, GIC_INTR_CFG_LEVEL), \
64 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \
65 grp, GIC_INTR_CFG_LEVEL), \
66 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \
67 grp, GIC_INTR_CFG_LEVEL), \
68 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \
69 grp, GIC_INTR_CFG_LEVEL), \
70 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \
71 grp, GIC_INTR_CFG_LEVEL), \
72 INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \
73 grp, GIC_INTR_CFG_LEVEL)
74
75#define PLATFORM_G0_PROPS(grp)
76
77static const interrupt_prop_t stih410_interrupt_props[] = {
78 PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
79 PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
80};
81
82static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
83
84static const struct gicv2_driver_data plat_gicv2_driver_data = {
85 .gicd_base = GICD_BASE,
86 .gicc_base = GICC_BASE,
87 .interrupt_props = stih410_interrupt_props,
88 .interrupt_props_num = ARRAY_SIZE(stih410_interrupt_props),
89 .target_masks = target_mask_array,
90 .target_masks_num = ARRAY_SIZE(target_mask_array),
91};
92
93/*******************************************************************************
94 * Return a pointer to the 'entry_point_info' structure of the next image for
95 * the security state specified. BL33 corresponds to the non-secure image type
96 * while BL32 corresponds to the secure image type. A NULL pointer is returned
97 * if the image does not exist.
98 ******************************************************************************/
99entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
100{
101 entry_point_info_t *next_image_info = &bl33_image_ep_info;
102
103 /*
104 * None of the images on the ARM development platforms can have 0x0
105 * as the entrypoint
106 */
107 if (next_image_info->pc)
108 return next_image_info;
109 else
110 return NULL;
111}
112
Antonio Nino Diaz099b0b12018-09-26 09:29:45 +0100113void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
114 u_register_t arg2, u_register_t arg3)
Etienne Carriere911de8c2018-02-02 13:23:22 +0100115{
Antonio Nino Diaz099b0b12018-09-26 09:29:45 +0100116 bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
Etienne Carriere911de8c2018-02-02 13:23:22 +0100117
118 /* Initialize the console to provide early debug support */
119 console_init(PLAT_QEMU_BOOT_UART_BASE, PLAT_QEMU_BOOT_UART_CLK_IN_HZ,
120 PLAT_QEMU_CONSOLE_BAUDRATE);
121
122 ERROR("qemu sp_min, console init\n");
123 /*
124 * Check params passed from BL2
125 */
126 assert(params_from_bl2);
127 assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
128 assert(params_from_bl2->h.version >= VERSION_2);
129
130 bl_params_node_t *bl_params = params_from_bl2->head;
131
132 /*
133 * Copy BL33 entry point information from BL2's address space.
134 */
135 while (bl_params) {
136 if (bl_params->image_id == BL33_IMAGE_ID)
137 bl33_image_ep_info = *bl_params->ep_info;
138
139 bl_params = bl_params->next_params_info;
140 }
141
142 if (!bl33_image_ep_info.pc)
143 panic();
144}
145
146void sp_min_plat_arch_setup(void)
147{
Antonio Nino Diaz099b0b12018-09-26 09:29:45 +0100148 qemu_configure_mmu_svc_mon(BL32_RO_BASE, BL32_END - BL32_RO_BASE,
Etienne Carriere911de8c2018-02-02 13:23:22 +0100149 BL32_RO_BASE, BL32_RO_LIMIT,
150 BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END);
151
152}
153
154void sp_min_platform_setup(void)
155{
156 /* Initialize the gic cpu and distributor interfaces */
157 gicv2_driver_init(&plat_gicv2_driver_data);
158 gicv2_distif_init();
159 gicv2_pcpu_distif_init();
160 gicv2_cpuif_enable();
161}
162
163unsigned int plat_get_syscnt_freq2(void)
164{
165 return SYS_COUNTER_FREQ_IN_TICKS;
166}
167
168void sp_min_plat_fiq_handler(uint32_t id)
169{
170 VERBOSE("[sp_min] interrupt #%d\n", id);
171}