aboutsummaryrefslogtreecommitdiff
path: root/plat/common/plat_common.c
blob: 4cfbebbf398f4500b6992f5678d82bc5de0a5f55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
56
57
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
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * Copyright (c) 2018, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <debug.h>
#include <drivers/arm/sp805.h>
#include <drivers/console.h>
#include <platform.h>
#include <xlat_tables_v2.h>

/*
 * The following platform functions are all weakly defined. They provide typical
 * implementations that may be re-used by multiple platforms but may also be
 * overridden by a platform if required.
 */

#pragma weak tftf_platform_end
#pragma weak tftf_platform_watchdog_set
#pragma weak tftf_platform_watchdog_reset
#pragma weak tftf_plat_configure_mmu
#pragma weak tftf_plat_enable_mmu
#pragma weak tftf_plat_reset
#pragma weak plat_get_prot_regions

#if IMAGE_TFTF

#define IMAGE_TEXT_BASE		TFTF_BASE
IMPORT_SYM(uintptr_t,		__TEXT_END__,		IMAGE_TEXT_END);

#define IMAGE_RODATA_BASE	IMAGE_TEXT_END
IMPORT_SYM(uintptr_t,		__RODATA_END__,		IMAGE_RODATA_END);

#define IMAGE_RW_BASE		IMAGE_RODATA_END
IMPORT_SYM(uintptr_t,		__TFTF_END__,		IMAGE_RW_END);

IMPORT_SYM(uintptr_t,		__COHERENT_RAM_START__,	COHERENT_RAM_START);
IMPORT_SYM(uintptr_t,		__COHERENT_RAM_END__,	COHERENT_RAM_END);

#elif IMAGE_NS_BL1U

#define IMAGE_TEXT_BASE		NS_BL1U_BASE
IMPORT_SYM(uintptr_t,		__TEXT_END__,		IMAGE_TEXT_END);

#define IMAGE_RODATA_BASE	IMAGE_TEXT_END
IMPORT_SYM(uintptr_t,		__RODATA_END__,		IMAGE_RODATA_END);

#define IMAGE_RW_BASE		NS_BL1U_RW_BASE
IMPORT_SYM(uintptr_t,		__NS_BL1U_RAM_END__,	IMAGE_RW_END);

#elif IMAGE_NS_BL2U

#define IMAGE_TEXT_BASE		NS_BL2U_BASE
IMPORT_SYM(uintptr_t,		__TEXT_END__,		IMAGE_TEXT_END);

#define IMAGE_RODATA_BASE	IMAGE_TEXT_END
IMPORT_SYM(uintptr_t,		__RODATA_END__,		IMAGE_RODATA_END);

#define IMAGE_RW_BASE		IMAGE_RODATA_END
IMPORT_SYM(uintptr_t,		__NS_BL2U_END__,	IMAGE_RW_END_UNALIGNED);
#define IMAGE_RW_END		round_up(IMAGE_RW_END_UNALIGNED, PAGE_SIZE)

#endif

void tftf_platform_end(void)
{
	/*
	 * Send EOT (End Of Transmission) on the UART.
	 * This can be used to shutdown a software model.
	 */
	static const char ascii_eot = 4;
	console_putc(ascii_eot);
}

void tftf_platform_watchdog_set(void)
{
	/* Placeholder function which should be redefined by each platform */
}

void tftf_platform_watchdog_reset(void)
{
	/* Placeholder function which should be redefined by each platform */
}

void tftf_plat_configure_mmu(void)
{
	/* Code */
	mmap_add_region(IMAGE_TEXT_BASE, IMAGE_TEXT_BASE,
			IMAGE_TEXT_END - IMAGE_TEXT_BASE, MT_CODE);

	/* RO data */
	mmap_add_region(IMAGE_RODATA_BASE, IMAGE_RODATA_BASE,
			IMAGE_RODATA_END - IMAGE_RODATA_BASE, MT_RO_DATA);

	/* Data + BSS */
	mmap_add_region(IMAGE_RW_BASE, IMAGE_RW_BASE,
			IMAGE_RW_END - IMAGE_RW_BASE, MT_RW_DATA);

#if IMAGE_TFTF
	mmap_add_region(COHERENT_RAM_START, COHERENT_RAM_START,
			COHERENT_RAM_END - COHERENT_RAM_START,
			MT_DEVICE | MT_RW | MT_NS);
#endif

	mmap_add(tftf_platform_get_mmap());
	init_xlat_tables();

	tftf_plat_enable_mmu();
}

void tftf_plat_enable_mmu(void)
{
#ifndef AARCH32
	if (IS_IN_EL1())
		enable_mmu_el1(0);
	else if (IS_IN_EL2())
		enable_mmu_el2(0);
	else
		panic();
#else
	if (IS_IN_HYP())
		enable_mmu_hyp(0);
	else
		enable_mmu_svc_mon(0);
#endif
}

void tftf_plat_reset(void)
{
	/*
	 * SP805 peripheral interrupt is not serviced in TFTF. The reset signal
	 * generated by it is used to reset the platform.
	 */
	sp805_wdog_start(1);

	/*
	 * Reset might take some execution cycles, Depending on the ratio between
	 * CPU clock frequency and Watchdog clock frequency
	 */
	while (1)
		;
}

const mem_region_t *plat_get_prot_regions(int *nelem)
{
	*nelem = 0;
	return NULL;
}