ARM: imx6q_logic: Fix MMC2 booting
[oweals/u-boot.git] / arch / x86 / lib / spl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016 Google, Inc
4  */
5
6 #include <common.h>
7 #include <debug_uart.h>
8 #include <malloc.h>
9 #include <spl.h>
10 #include <asm/cpu.h>
11 #include <asm/mrccache.h>
12 #include <asm/mtrr.h>
13 #include <asm/processor.h>
14 #include <asm-generic/sections.h>
15
16 DECLARE_GLOBAL_DATA_PTR;
17
18 __weak int arch_cpu_init_dm(void)
19 {
20         return 0;
21 }
22
23 static int x86_spl_init(void)
24 {
25 #ifndef CONFIG_TPL
26         /*
27          * TODO(sjg@chromium.org): We use this area of RAM for the stack
28          * and global_data in SPL. Once U-Boot starts up and releocates it
29          * is not needed. We could make this a CONFIG option or perhaps
30          * place it immediately below CONFIG_SYS_TEXT_BASE.
31          */
32         char *ptr = (char *)0x110000;
33 #endif
34         int ret;
35
36         debug("%s starting\n", __func__);
37         ret = spl_init();
38         if (ret) {
39                 debug("%s: spl_init() failed\n", __func__);
40                 return ret;
41         }
42 #ifdef CONFIG_TPL
43         /* Do a mini-init if TPL has already done the full init */
44         ret = x86_cpu_reinit_f();
45 #else
46         ret = arch_cpu_init();
47 #endif
48         if (ret) {
49                 debug("%s: arch_cpu_init() failed\n", __func__);
50                 return ret;
51         }
52 #ifndef CONFIG_TPL
53         ret = arch_cpu_init_dm();
54         if (ret) {
55                 debug("%s: arch_cpu_init_dm() failed\n", __func__);
56                 return ret;
57         }
58 #endif
59         preloader_console_init();
60 #ifndef CONFIG_TPL
61         ret = print_cpuinfo();
62         if (ret) {
63                 debug("%s: print_cpuinfo() failed\n", __func__);
64                 return ret;
65         }
66 #endif
67         ret = dram_init();
68         if (ret) {
69                 debug("%s: dram_init() failed\n", __func__);
70                 return ret;
71         }
72         if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) {
73                 ret = mrccache_spl_save();
74                 if (ret)
75                         debug("%s: Failed to write to mrccache (err=%d)\n",
76                               __func__, ret);
77         }
78
79 #ifndef CONFIG_TPL
80         memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
81
82         /* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
83         ret = interrupt_init();
84         if (ret) {
85                 debug("%s: interrupt_init() failed\n", __func__);
86                 return ret;
87         }
88
89         /*
90          * The stack grows down from ptr. Put the global data at ptr. This
91          * will only be used for SPL. Once SPL loads U-Boot proper it will
92          * set up its own stack.
93          */
94         gd->new_gd = (struct global_data *)ptr;
95         memcpy(gd->new_gd, gd, sizeof(*gd));
96         arch_setup_gd(gd->new_gd);
97         gd->start_addr_sp = (ulong)ptr;
98
99         /* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
100         ret = mtrr_add_request(MTRR_TYPE_WRBACK,
101                                (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
102                                CONFIG_XIP_ROM_SIZE);
103         if (ret) {
104                 debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
105                 return ret;
106         }
107         mtrr_commit(true);
108 #endif
109
110         return 0;
111 }
112
113 void board_init_f(ulong flags)
114 {
115         int ret;
116
117         ret = x86_spl_init();
118         if (ret) {
119                 debug("Error %d\n", ret);
120                 hang();
121         }
122 #ifdef CONFIG_TPL
123         gd->bd = malloc(sizeof(*gd->bd));
124         if (!gd->bd) {
125                 printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd));
126                 hang();
127         }
128         board_init_r(gd, 0);
129 #else
130         /* Uninit CAR and jump to board_init_f_r() */
131         board_init_f_r_trampoline(gd->start_addr_sp);
132 #endif
133 }
134
135 void board_init_f_r(void)
136 {
137         init_cache_f_r();
138         gd->flags &= ~GD_FLG_SERIAL_READY;
139         debug("cache status %d\n", dcache_status());
140         board_init_r(gd, 0);
141 }
142
143 u32 spl_boot_device(void)
144 {
145         return BOOT_DEVICE_BOARD;
146 }
147
148 int spl_start_uboot(void)
149 {
150         return 0;
151 }
152
153 void spl_board_announce_boot_device(void)
154 {
155         printf("SPI flash");
156 }
157
158 static int spl_board_load_image(struct spl_image_info *spl_image,
159                                 struct spl_boot_device *bootdev)
160 {
161         spl_image->size = CONFIG_SYS_MONITOR_LEN;
162         spl_image->entry_point = CONFIG_SYS_TEXT_BASE;
163         spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
164         spl_image->os = IH_OS_U_BOOT;
165         spl_image->name = "U-Boot";
166
167         debug("Loading to %lx\n", spl_image->load_addr);
168
169         return 0;
170 }
171 SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
172
173 int spl_spi_load_image(void)
174 {
175         return -EPERM;
176 }
177
178 #ifdef CONFIG_X86_RUN_64BIT
179 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
180 {
181         int ret;
182
183         printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
184         ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
185         debug("ret=%d\n", ret);
186         while (1)
187                 ;
188 }
189 #endif
190
191 void spl_board_init(void)
192 {
193 #ifndef CONFIG_TPL
194         preloader_console_init();
195 #endif
196 }