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
|
#include <common.h>
#include <mach/atf.h>
/**
* imx8m_atf_load_bl31 - Load ATF BL31 blob and transfer control to it
*
* @fw: Pointer to the BL31 blob
* @fw_size: Size of the BL31 blob
* @atf_dest: Place where the BL31 is copied to and executed
*
* This function:
*
* 1. Copies built-in BL31 blob to an address i.MX8M's BL31
* expects to be placed
*
* 2. Sets up temporary stack pointer for EL2, which is execution
* level that BL31 will drop us off at after it completes its
* initialization routine
*
* 3. Transfers control to BL31
*
* NOTE: This function expects NXP's implementation of ATF that can be
* found at:
* https://source.codeaurora.org/external/imx/imx-atf
*
* any other implementation may or may not work
*
*/
static void imx8m_atf_load_bl31(const void *fw, size_t fw_size, void *atf_dest)
{
void __noreturn (*bl31)(void) = atf_dest;
if (WARN_ON(fw_size > MX8M_ATF_BL31_SIZE_LIMIT))
return;
memcpy(bl31, fw, fw_size);
asm volatile("msr sp_el2, %0" : :
"r" (atf_dest - 16) :
"cc");
bl31();
}
void imx8mm_atf_load_bl31(const void *fw, size_t fw_size)
{
imx8m_atf_load_bl31(fw, fw_size, (void *)MX8MM_ATF_BL31_BASE_ADDR);
}
void imx8mp_atf_load_bl31(const void *fw, size_t fw_size)
{
imx8m_atf_load_bl31(fw, fw_size, (void *)MX8MP_ATF_BL31_BASE_ADDR);
}
void imx8mq_atf_load_bl31(const void *fw, size_t fw_size)
{
imx8m_atf_load_bl31(fw, fw_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR);
}
|