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