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