1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 20ae76531SDavid Feng /* 30ae76531SDavid Feng * (C) Copyright 2008 Texas Insturments 40ae76531SDavid Feng * 50ae76531SDavid Feng * (C) Copyright 2002 60ae76531SDavid Feng * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 70ae76531SDavid Feng * Marius Groeger <mgroeger@sysgo.de> 80ae76531SDavid Feng * 90ae76531SDavid Feng * (C) Copyright 2002 100ae76531SDavid Feng * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> 110ae76531SDavid Feng */ 120ae76531SDavid Feng 130ae76531SDavid Feng #include <common.h> 140ae76531SDavid Feng #include <command.h> 150ae76531SDavid Feng #include <asm/system.h> 169a561753Smacro.wave.z@gmail.com #include <asm/secure.h> 170ae76531SDavid Feng #include <linux/compiler.h> 180ae76531SDavid Feng 198ed02bc2SAndre Przywara /* 208ed02bc2SAndre Przywara * sdelay() - simple spin loop. 218ed02bc2SAndre Przywara * 228ed02bc2SAndre Przywara * Will delay execution by roughly (@loops * 2) cycles. 238ed02bc2SAndre Przywara * This is necessary to be used before timers are accessible. 248ed02bc2SAndre Przywara * 258ed02bc2SAndre Przywara * A value of "0" will results in 2^64 loops. 268ed02bc2SAndre Przywara */ sdelay(unsigned long loops)278ed02bc2SAndre Przywaravoid sdelay(unsigned long loops) 288ed02bc2SAndre Przywara { 298ed02bc2SAndre Przywara __asm__ volatile ("1:\n" "subs %0, %0, #1\n" 308ed02bc2SAndre Przywara "b.ne 1b" : "=r" (loops) : "0"(loops) : "cc"); 318ed02bc2SAndre Przywara } 328ed02bc2SAndre Przywara cleanup_before_linux(void)330ae76531SDavid Fengint cleanup_before_linux(void) 340ae76531SDavid Feng { 350ae76531SDavid Feng /* 360ae76531SDavid Feng * this function is called just before we call linux 370ae76531SDavid Feng * it prepares the processor for linux 380ae76531SDavid Feng * 390ae76531SDavid Feng * disable interrupt and turn off caches etc ... 400ae76531SDavid Feng */ 410ae76531SDavid Feng disable_interrupts(); 420ae76531SDavid Feng 430ae76531SDavid Feng /* 440ae76531SDavid Feng * Turn off I-cache and invalidate it 450ae76531SDavid Feng */ 460ae76531SDavid Feng icache_disable(); 470ae76531SDavid Feng invalidate_icache_all(); 480ae76531SDavid Feng 490ae76531SDavid Feng /* 500ae76531SDavid Feng * turn off D-cache 510ae76531SDavid Feng * dcache_disable() in turn flushes the d-cache and disables MMU 520ae76531SDavid Feng */ 530ae76531SDavid Feng dcache_disable(); 540ae76531SDavid Feng invalidate_dcache_all(); 550ae76531SDavid Feng 560ae76531SDavid Feng return 0; 570ae76531SDavid Feng } 589a561753Smacro.wave.z@gmail.com 599a561753Smacro.wave.z@gmail.com #ifdef CONFIG_ARMV8_PSCI relocate_secure_section(void)609a561753Smacro.wave.z@gmail.comstatic void relocate_secure_section(void) 619a561753Smacro.wave.z@gmail.com { 629a561753Smacro.wave.z@gmail.com #ifdef CONFIG_ARMV8_SECURE_BASE 639a561753Smacro.wave.z@gmail.com size_t sz = __secure_end - __secure_start; 649a561753Smacro.wave.z@gmail.com 659a561753Smacro.wave.z@gmail.com memcpy((void *)CONFIG_ARMV8_SECURE_BASE, __secure_start, sz); 669a561753Smacro.wave.z@gmail.com flush_dcache_range(CONFIG_ARMV8_SECURE_BASE, 679a561753Smacro.wave.z@gmail.com CONFIG_ARMV8_SECURE_BASE + sz + 1); 689a561753Smacro.wave.z@gmail.com invalidate_icache_all(); 699a561753Smacro.wave.z@gmail.com #endif 709a561753Smacro.wave.z@gmail.com } 719a561753Smacro.wave.z@gmail.com armv8_setup_psci(void)729a561753Smacro.wave.z@gmail.comvoid armv8_setup_psci(void) 739a561753Smacro.wave.z@gmail.com { 749a561753Smacro.wave.z@gmail.com relocate_secure_section(); 759a561753Smacro.wave.z@gmail.com secure_ram_addr(psci_setup_vectors)(); 769a561753Smacro.wave.z@gmail.com secure_ram_addr(psci_arch_init)(); 779a561753Smacro.wave.z@gmail.com } 789a561753Smacro.wave.z@gmail.com #endif 79