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