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