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