aboutsummaryrefslogtreecommitdiff
path: root/plat/st/common/stm32mp_common.c
blob: 48a747c7c2c4d887a80737febf265c4d0c59fc0b (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
/*
 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>

#include <platform_def.h>

#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/st/stm32mp_clkfunc.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>

uintptr_t plat_get_ns_image_entrypoint(void)
{
	return BL33_BASE;
}

unsigned int plat_get_syscnt_freq2(void)
{
	return read_cntfrq_el0();
}

static uintptr_t boot_ctx_address;

void stm32mp_save_boot_ctx_address(uintptr_t address)
{
	boot_ctx_address = address;
}

uintptr_t stm32mp_get_boot_ctx_address(void)
{
	return boot_ctx_address;
}

uintptr_t stm32mp_ddrctrl_base(void)
{
	static uintptr_t ddrctrl_base;

	if (ddrctrl_base == 0) {
		ddrctrl_base = dt_get_ddrctrl_base();

		assert(ddrctrl_base == DDRCTRL_BASE);
	}

	return ddrctrl_base;
}

uintptr_t stm32mp_ddrphyc_base(void)
{
	static uintptr_t ddrphyc_base;

	if (ddrphyc_base == 0) {
		ddrphyc_base = dt_get_ddrphyc_base();

		assert(ddrphyc_base == DDRPHYC_BASE);
	}

	return ddrphyc_base;
}

uintptr_t stm32mp_pwr_base(void)
{
	static uintptr_t pwr_base;

	if (pwr_base == 0) {
		pwr_base = dt_get_pwr_base();

		assert(pwr_base == PWR_BASE);
	}

	return pwr_base;
}

uintptr_t stm32mp_rcc_base(void)
{
	static uintptr_t rcc_base;

	if (rcc_base == 0) {
		rcc_base = fdt_rcc_read_addr();

		assert(rcc_base == RCC_BASE);
	}

	return rcc_base;
}

bool stm32mp_lock_available(void)
{
	const uint32_t c_m_bits = SCTLR_M_BIT | SCTLR_C_BIT;

	/* The spinlocks are used only when MMU and data cache are enabled */
	return (read_sctlr() & c_m_bits) == c_m_bits;
}

int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer)
{
	uint32_t i;
	uint32_t img_checksum = 0U;

	/*
	 * Check header/payload validity:
	 *	- Header magic
	 *	- Header version
	 *	- Payload checksum
	 */
	if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
		ERROR("Header magic\n");
		return -EINVAL;
	}

	if (header->header_version != BOOT_API_HEADER_VERSION) {
		ERROR("Header version\n");
		return -EINVAL;
	}

	for (i = 0U; i < header->image_length; i++) {
		img_checksum += *(uint8_t *)(buffer + i);
	}

	if (header->payload_checksum != img_checksum) {
		ERROR("Checksum: 0x%x (awaited: 0x%x)\n", img_checksum,
		      header->payload_checksum);
		return -EINVAL;
	}

	return 0;
}

int stm32mp_map_ddr_non_cacheable(void)
{
	return  mmap_add_dynamic_region(STM32MP_DDR_BASE, STM32MP_DDR_BASE,
					STM32MP_DDR_MAX_SIZE,
					MT_NON_CACHEABLE | MT_RW | MT_NS);
}

int stm32mp_unmap_ddr(void)
{
	return  mmap_remove_dynamic_region(STM32MP_DDR_BASE,
					   STM32MP_DDR_MAX_SIZE);
}