1e1bc64eeSSimon Glass /** 2e1bc64eeSSimon Glass * Copyright (c) 2017 Google, Inc 3e1bc64eeSSimon Glass * 4e1bc64eeSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 5e1bc64eeSSimon Glass */ 6e1bc64eeSSimon Glass 7e1bc64eeSSimon Glass #include <common.h> 8e1bc64eeSSimon Glass #include <asm/arch/bootrom.h> 9ecfd7189SPhilipp Tomsich #include <asm/setjmp.h> 10ecfd7189SPhilipp Tomsich #include <asm/system.h> 11ecfd7189SPhilipp Tomsich 12ecfd7189SPhilipp Tomsich /* 13ecfd7189SPhilipp Tomsich * Force the jmp_buf to the data-section, as .bss will not be valid 14ecfd7189SPhilipp Tomsich * when save_boot_params is invoked. 15ecfd7189SPhilipp Tomsich */ 16ecfd7189SPhilipp Tomsich static jmp_buf brom_ctx __section(".data"); 17e1bc64eeSSimon Glass 18*b82bd1f8SPhilipp Tomsich void back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd) 19e1bc64eeSSimon Glass { 2019b68fb2SPhilipp Tomsich #if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) 2119b68fb2SPhilipp Tomsich puts("Returning to boot ROM...\n"); 22e1bc64eeSSimon Glass #endif 23*b82bd1f8SPhilipp Tomsich longjmp(brom_ctx, brom_cmd); 24ecfd7189SPhilipp Tomsich } 25ecfd7189SPhilipp Tomsich 26ecfd7189SPhilipp Tomsich /* 27ecfd7189SPhilipp Tomsich * All Rockchip BROM implementations enter with a valid stack-pointer, 28ecfd7189SPhilipp Tomsich * so this can safely be implemented in C (providing a single 29ecfd7189SPhilipp Tomsich * implementation both for ARMv7 and AArch64). 30ecfd7189SPhilipp Tomsich */ 31ecfd7189SPhilipp Tomsich int save_boot_params(void) 32ecfd7189SPhilipp Tomsich { 33ecfd7189SPhilipp Tomsich int ret = setjmp(brom_ctx); 34ecfd7189SPhilipp Tomsich 35ecfd7189SPhilipp Tomsich switch (ret) { 36ecfd7189SPhilipp Tomsich case 0: 37ecfd7189SPhilipp Tomsich /* 38ecfd7189SPhilipp Tomsich * This is the initial pass through this function 39ecfd7189SPhilipp Tomsich * (i.e. saving the context), setjmp just setup up the 40ecfd7189SPhilipp Tomsich * brom_ctx: transfer back into the startup-code at 41ecfd7189SPhilipp Tomsich * 'save_boot_params_ret' and let the compiler know 42ecfd7189SPhilipp Tomsich * that this will not return. 43ecfd7189SPhilipp Tomsich */ 44ecfd7189SPhilipp Tomsich save_boot_params_ret(); 45ecfd7189SPhilipp Tomsich while (true) 46ecfd7189SPhilipp Tomsich /* does not return */; 47ecfd7189SPhilipp Tomsich break; 48ecfd7189SPhilipp Tomsich 49ecfd7189SPhilipp Tomsich case BROM_BOOT_NEXTSTAGE: 50ecfd7189SPhilipp Tomsich /* 51ecfd7189SPhilipp Tomsich * To instruct the BROM to boot the next stage, we 52ecfd7189SPhilipp Tomsich * need to return 0 to it: i.e. we need to rewrite 53ecfd7189SPhilipp Tomsich * the return code once more. 54ecfd7189SPhilipp Tomsich */ 55ecfd7189SPhilipp Tomsich ret = 0; 56ecfd7189SPhilipp Tomsich break; 57ecfd7189SPhilipp Tomsich 58ecfd7189SPhilipp Tomsich default: 59ecfd7189SPhilipp Tomsich #if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) 60ecfd7189SPhilipp Tomsich puts("FATAL: unexpected command to back_to_bootrom()\n"); 61ecfd7189SPhilipp Tomsich #endif 62ecfd7189SPhilipp Tomsich hang(); 63ecfd7189SPhilipp Tomsich }; 64ecfd7189SPhilipp Tomsich 65ecfd7189SPhilipp Tomsich return ret; 66e1bc64eeSSimon Glass } 67