1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2008 Texas Insturments
4  *
5  * (C) Copyright 2002
6  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7  * Marius Groeger <mgroeger@sysgo.de>
8  *
9  * (C) Copyright 2002
10  * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
11  */
12 
13 #include <command.h>
14 #include <cpu_func.h>
15 #include <irq_func.h>
16 #include <asm/cache.h>
17 #include <asm/system.h>
18 #include <asm/secure.h>
19 #include <linux/compiler.h>
20 
21 /*
22  * sdelay() - simple spin loop.
23  *
24  * Will delay execution by roughly (@loops * 2) cycles.
25  * This is necessary to be used before timers are accessible.
26  *
27  * A value of "0" will results in 2^64 loops.
28  */
sdelay(unsigned long loops)29 void sdelay(unsigned long loops)
30 {
31 	__asm__ volatile ("1:\n" "subs %0, %0, #1\n"
32 			  "b.ne 1b" : "=r" (loops) : "0"(loops) : "cc");
33 }
34 
board_cleanup_before_linux(void)35 void __weak board_cleanup_before_linux(void){}
36 
cleanup_before_linux(void)37 int cleanup_before_linux(void)
38 {
39 	/*
40 	 * this function is called just before we call linux
41 	 * it prepares the processor for linux
42 	 *
43 	 * disable interrupt and turn off caches etc ...
44 	 */
45 
46 	board_cleanup_before_linux();
47 
48 	disable_interrupts();
49 
50 	if (IS_ENABLED(CONFIG_CMO_BY_VA_ONLY)) {
51 		/*
52 		 * Disable D-cache.
53 		 */
54 		dcache_disable();
55 	} else {
56 		/*
57 		 * Turn off I-cache and invalidate it
58 		 */
59 		icache_disable();
60 		invalidate_icache_all();
61 
62 		/*
63 		 * turn off D-cache
64 		 * dcache_disable() in turn flushes the d-cache and disables
65 		 * MMU
66 		 */
67 		dcache_disable();
68 		invalidate_dcache_all();
69 	}
70 
71 	return 0;
72 }
73 
74 #ifdef CONFIG_ARMV8_PSCI
relocate_secure_section(void)75 static void relocate_secure_section(void)
76 {
77 #ifdef CONFIG_ARMV8_SECURE_BASE
78 	size_t sz = __secure_end - __secure_start;
79 
80 	memcpy((void *)CONFIG_ARMV8_SECURE_BASE, __secure_start, sz);
81 	flush_dcache_range(CONFIG_ARMV8_SECURE_BASE,
82 			   CONFIG_ARMV8_SECURE_BASE + sz + 1);
83 	invalidate_icache_all();
84 #endif
85 }
86 
armv8_setup_psci(void)87 void armv8_setup_psci(void)
88 {
89 	if (current_el() != 3)
90 		return;
91 
92 	relocate_secure_section();
93 	secure_ram_addr(psci_setup_vectors)();
94 	secure_ram_addr(psci_arch_init)();
95 }
96 #endif
97 
allow_unaligned(void)98 void allow_unaligned(void)
99 {
100 	set_sctlr(get_sctlr() & ~CR_A);
101 }
102