blob: 01ff034d6654e3b7f8390bc667a71bc5ad73a651 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Simon Glass030777d2017-01-16 07:03:56 -07002/*
3 * Copyright (c) 2016 Google, Inc
Simon Glass030777d2017-01-16 07:03:56 -07004 */
5
Simon Glass3a1d96f2023-07-15 21:39:11 -06006#define LOG_CATEGORY LOGC_BOOT
7
Simon Glass1d91ba72019-11-14 12:57:37 -07008#include <cpu_func.h>
Simon Glass030777d2017-01-16 07:03:56 -07009#include <debug_uart.h>
Simon Glass0b3c5762019-10-20 21:37:49 -060010#include <dm.h>
Simon Glassf11478f2019-12-28 10:45:07 -070011#include <hang.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060012#include <image.h>
Simon Glass97589732020-05-10 11:40:02 -060013#include <init.h>
Simon Glass9b61c7c2019-11-14 12:57:41 -070014#include <irq_func.h>
Simon Glass0f2af882020-05-10 11:40:05 -060015#include <log.h>
Simon Glass7cf5fe02019-05-02 10:52:12 -060016#include <malloc.h>
Simon Glass030777d2017-01-16 07:03:56 -070017#include <spl.h>
Simon Glass0b3c5762019-10-20 21:37:49 -060018#include <syscon.h>
Simon Glasse50c4552023-07-15 21:39:01 -060019#include <vesa.h>
Simon Glass030777d2017-01-16 07:03:56 -070020#include <asm/cpu.h>
Simon Glass0b3c5762019-10-20 21:37:49 -060021#include <asm/cpu_common.h>
Simon Glassfc557362022-03-04 08:43:05 -070022#include <asm/fsp2/fsp_api.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060023#include <asm/global_data.h>
Simon Glassfb842432023-07-15 21:38:36 -060024#include <asm/mp.h>
Simon Glass7cf5fe02019-05-02 10:52:12 -060025#include <asm/mrccache.h>
Simon Glass030777d2017-01-16 07:03:56 -070026#include <asm/mtrr.h>
Simon Glass0b3c5762019-10-20 21:37:49 -060027#include <asm/pci.h>
Simon Glass030777d2017-01-16 07:03:56 -070028#include <asm/processor.h>
Simon Glass7dc0a452023-07-30 11:16:01 -060029#include <asm/qemu.h>
Simon Glass19da9c42019-09-25 08:11:39 -060030#include <asm/spl.h>
Tom Rinidec7ea02024-05-20 13:35:03 -060031#include <asm/u-boot-x86.h>
Simon Glass030777d2017-01-16 07:03:56 -070032#include <asm-generic/sections.h>
33
34DECLARE_GLOBAL_DATA_PTR;
35
Simon Glassfc557362022-03-04 08:43:05 -070036__weak int fsp_setup_pinctrl(void *ctx, struct event *event)
Bin Meng2240fde2017-01-18 03:32:53 -080037{
38 return 0;
39}
40
Simon Glass0b3c5762019-10-20 21:37:49 -060041#ifdef CONFIG_TPL
42
43static int set_max_freq(void)
44{
45 if (cpu_get_burst_mode_state() == BURST_MODE_UNAVAILABLE) {
46 /*
47 * Burst Mode has been factory-configured as disabled and is not
48 * available in this physical processor package
49 */
50 debug("Burst Mode is factory-disabled\n");
51 return -ENOENT;
52 }
53
54 /* Enable burst mode */
55 cpu_set_burst_mode(true);
56
57 /* Enable speed step */
58 cpu_set_eist(true);
59
60 /* Set P-State ratio */
61 cpu_set_p_state_to_turbo_ratio();
62
63 return 0;
64}
65#endif
66
Simon Glass030777d2017-01-16 07:03:56 -070067static int x86_spl_init(void)
68{
Simon Glassb3f351f2023-07-15 21:39:13 -060069 struct udevice *dev;
70
Simon Glass7cf5fe02019-05-02 10:52:12 -060071#ifndef CONFIG_TPL
Simon Glass030777d2017-01-16 07:03:56 -070072 /*
73 * TODO(sjg@chromium.org): We use this area of RAM for the stack
74 * and global_data in SPL. Once U-Boot starts up and releocates it
75 * is not needed. We could make this a CONFIG option or perhaps
Simon Glass72cc5382022-10-20 18:22:39 -060076 * place it immediately below CONFIG_TEXT_BASE.
Simon Glass030777d2017-01-16 07:03:56 -070077 */
Simon Glassdae11532020-04-30 21:21:42 -060078 __maybe_unused char *ptr = (char *)0x110000;
Simon Glass0b3c5762019-10-20 21:37:49 -060079#else
80 struct udevice *punit;
Simon Glass7cf5fe02019-05-02 10:52:12 -060081#endif
Simon Glass030777d2017-01-16 07:03:56 -070082 int ret;
83
Simon Glass3a1d96f2023-07-15 21:39:11 -060084 log_debug("x86 spl starting\n");
Tom Rinidcc44ec2025-02-26 14:31:26 -060085 if (IS_ENABLED(CONFIG_TPL))
Simon Glass81f14622019-10-20 21:37:55 -060086 ret = x86_cpu_reinit_f();
Simon Glass030777d2017-01-16 07:03:56 -070087 ret = spl_init();
88 if (ret) {
Simon Glass3a1d96f2023-07-15 21:39:11 -060089 log_debug("spl_init() failed (err=%d)\n", ret);
Simon Glass030777d2017-01-16 07:03:56 -070090 return ret;
91 }
Simon Glass030777d2017-01-16 07:03:56 -070092 ret = arch_cpu_init();
93 if (ret) {
Simon Glass3a1d96f2023-07-15 21:39:11 -060094 log_debug("arch_cpu_init() failed (err=%d)\n", ret);
Simon Glass030777d2017-01-16 07:03:56 -070095 return ret;
96 }
Simon Glass7cf5fe02019-05-02 10:52:12 -060097#ifndef CONFIG_TPL
Simon Glassfc557362022-03-04 08:43:05 -070098 ret = fsp_setup_pinctrl(NULL, NULL);
Simon Glass030777d2017-01-16 07:03:56 -070099 if (ret) {
Simon Glass3a1d96f2023-07-15 21:39:11 -0600100 log_debug("fsp_setup_pinctrl() failed (err=%d)\n", ret);
Simon Glass030777d2017-01-16 07:03:56 -0700101 return ret;
102 }
Simon Glass7cf5fe02019-05-02 10:52:12 -0600103#endif
Simon Glassfbfb4762023-07-15 21:39:00 -0600104 /*
105 * spl_board_init() below sets up the console if enabled. If it isn't,
106 * do it here. We cannot call this twice since it results in a double
107 * banner and CI tests fail.
108 */
109 if (!IS_ENABLED(CONFIG_SPL_BOARD_INIT))
110 preloader_console_init();
Simon Glass2f002162021-03-15 18:11:18 +1300111#if !defined(CONFIG_TPL) && !CONFIG_IS_ENABLED(CPU)
Simon Glass030777d2017-01-16 07:03:56 -0700112 ret = print_cpuinfo();
113 if (ret) {
Simon Glass3a1d96f2023-07-15 21:39:11 -0600114 log_debug("print_cpuinfo() failed (err=%d)\n", ret);
Simon Glass030777d2017-01-16 07:03:56 -0700115 return ret;
116 }
Simon Glass7cf5fe02019-05-02 10:52:12 -0600117#endif
Simon Glassb3f351f2023-07-15 21:39:13 -0600118 /* probe the LPC so we get the GPIO_BASE set up correctly */
119 ret = uclass_first_device_err(UCLASS_LPC, &dev);
120 if (ret && ret != -ENODEV) {
121 log_debug("lpc probe failed\n");
122 return ret;
123 }
124
Simon Glass030777d2017-01-16 07:03:56 -0700125 ret = dram_init();
126 if (ret) {
Simon Glass3a1d96f2023-07-15 21:39:11 -0600127 log_debug("dram_init() failed (err=%d)\n", ret);
Simon Glass030777d2017-01-16 07:03:56 -0700128 return ret;
129 }
Simon Glass3a1d96f2023-07-15 21:39:11 -0600130 log_debug("mrc\n");
Simon Glass7cf5fe02019-05-02 10:52:12 -0600131 if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) {
132 ret = mrccache_spl_save();
133 if (ret)
Simon Glass3a1d96f2023-07-15 21:39:11 -0600134 log_debug("Failed to write to mrccache (err=%d)\n",
135 ret);
Simon Glass7cf5fe02019-05-02 10:52:12 -0600136 }
137
Simon Glassdae11532020-04-30 21:21:42 -0600138#ifndef CONFIG_SYS_COREBOOT
Shiji Yangeff11fa2023-08-03 09:47:17 +0800139 debug("BSS clear from %lx to %lx len %lx\n", (ulong)__bss_start,
140 (ulong)__bss_end, (ulong)__bss_end - (ulong)__bss_start);
141 memset(__bss_start, 0, (ulong)__bss_end - (ulong)__bss_start);
Simon Glass47717592021-01-24 10:06:10 -0700142# ifndef CONFIG_TPL
Simon Glass030777d2017-01-16 07:03:56 -0700143
144 /* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
145 ret = interrupt_init();
146 if (ret) {
147 debug("%s: interrupt_init() failed\n", __func__);
148 return ret;
149 }
150
151 /*
152 * The stack grows down from ptr. Put the global data at ptr. This
153 * will only be used for SPL. Once SPL loads U-Boot proper it will
154 * set up its own stack.
155 */
156 gd->new_gd = (struct global_data *)ptr;
157 memcpy(gd->new_gd, gd, sizeof(*gd));
Simon Glass23ae5c32023-07-15 21:39:05 -0600158
Simon Glass3a1d96f2023-07-15 21:39:11 -0600159 log_debug("logging\n");
Simon Glass23ae5c32023-07-15 21:39:05 -0600160 /*
161 * Make sure logging is disabled when we switch, since the log system
162 * list head will move
163 */
164 gd->new_gd->flags &= ~GD_FLG_LOG_READY;
Simon Glass030777d2017-01-16 07:03:56 -0700165 arch_setup_gd(gd->new_gd);
166 gd->start_addr_sp = (ulong)ptr;
167
Simon Glass23ae5c32023-07-15 21:39:05 -0600168 /* start up logging again, with the new list-head location */
169 ret = log_init();
170 if (ret) {
171 log_debug("Log setup failed (err=%d)\n", ret);
172 return ret;
173 }
174
Simon Glassfb842432023-07-15 21:38:36 -0600175 if (_LOG_DEBUG) {
176 ret = mtrr_list(mtrr_get_var_count(), MP_SELECT_BSP);
177 if (ret)
178 printf("mtrr_list failed\n");
179 }
180
Simon Glass030777d2017-01-16 07:03:56 -0700181 /* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
182 ret = mtrr_add_request(MTRR_TYPE_WRBACK,
183 (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
184 CONFIG_XIP_ROM_SIZE);
185 if (ret) {
Simon Glass7cf5fe02019-05-02 10:52:12 -0600186 debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
Simon Glass030777d2017-01-16 07:03:56 -0700187 return ret;
188 }
Simon Glassdae11532020-04-30 21:21:42 -0600189# else
Simon Glass0b3c5762019-10-20 21:37:49 -0600190 ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit);
191 if (ret)
192 debug("Could not find PUNIT (err=%d)\n", ret);
193
194 ret = set_max_freq();
195 if (ret)
196 debug("Failed to set CPU frequency (err=%d)\n", ret);
Simon Glassdae11532020-04-30 21:21:42 -0600197# endif
Simon Glass7cf5fe02019-05-02 10:52:12 -0600198#endif
Simon Glass3a1d96f2023-07-15 21:39:11 -0600199 log_debug("done\n");
Simon Glass030777d2017-01-16 07:03:56 -0700200
201 return 0;
202}
203
204void board_init_f(ulong flags)
205{
206 int ret;
207
208 ret = x86_spl_init();
209 if (ret) {
Simon Glassa0185fa2020-05-27 06:58:48 -0600210 printf("x86_spl_init: error %d\n", ret);
211 hang();
Simon Glass030777d2017-01-16 07:03:56 -0700212 }
Simon Glassdae11532020-04-30 21:21:42 -0600213#if IS_ENABLED(CONFIG_TPL) || IS_ENABLED(CONFIG_SYS_COREBOOT)
Simon Glass7cf5fe02019-05-02 10:52:12 -0600214 gd->bd = malloc(sizeof(*gd->bd));
215 if (!gd->bd) {
216 printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd));
217 hang();
218 }
219 board_init_r(gd, 0);
220#else
Simon Glass030777d2017-01-16 07:03:56 -0700221 /* Uninit CAR and jump to board_init_f_r() */
222 board_init_f_r_trampoline(gd->start_addr_sp);
Simon Glass7cf5fe02019-05-02 10:52:12 -0600223#endif
Simon Glass030777d2017-01-16 07:03:56 -0700224}
225
226void board_init_f_r(void)
227{
Simon Glass6e7b1b52023-05-04 16:50:57 -0600228 mtrr_commit(false);
229 init_cache();
Simon Glass030777d2017-01-16 07:03:56 -0700230 gd->flags &= ~GD_FLG_SERIAL_READY;
Simon Glass2a5cad02023-09-07 09:58:20 -0600231
232 /* make sure driver model is not accessed from now on */
233 gd->flags |= GD_FLG_DM_DEAD;
Simon Glass030777d2017-01-16 07:03:56 -0700234 debug("cache status %d\n", dcache_status());
235 board_init_r(gd, 0);
236}
237
238u32 spl_boot_device(void)
239{
Simon Glass19da9c42019-09-25 08:11:39 -0600240 return BOOT_DEVICE_SPI_MMAP;
Simon Glass030777d2017-01-16 07:03:56 -0700241}
242
243int spl_start_uboot(void)
244{
245 return 0;
246}
247
248void spl_board_announce_boot_device(void)
249{
250 printf("SPI flash");
251}
252
253static int spl_board_load_image(struct spl_image_info *spl_image,
254 struct spl_boot_device *bootdev)
255{
256 spl_image->size = CONFIG_SYS_MONITOR_LEN;
Simon Glass72cc5382022-10-20 18:22:39 -0600257 spl_image->entry_point = CONFIG_TEXT_BASE;
258 spl_image->load_addr = CONFIG_TEXT_BASE;
Simon Glass030777d2017-01-16 07:03:56 -0700259 spl_image->os = IH_OS_U_BOOT;
260 spl_image->name = "U-Boot";
261
Simon Glass8c434342023-09-07 09:58:17 -0600262 if (spl_image->load_addr != spl_get_image_pos()) {
Simon Glass53ea0f62023-05-04 16:50:55 -0600263 /* Copy U-Boot from ROM */
264 memcpy((void *)spl_image->load_addr,
265 (void *)spl_get_image_pos(), spl_get_image_size());
Simon Glass91fcd1d2020-04-30 21:21:41 -0600266 }
267
Simon Glass030777d2017-01-16 07:03:56 -0700268 debug("Loading to %lx\n", spl_image->load_addr);
269
270 return 0;
271}
Simon Glass19da9c42019-09-25 08:11:39 -0600272SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);
Simon Glass030777d2017-01-16 07:03:56 -0700273
274int spl_spi_load_image(void)
275{
276 return -EPERM;
277}
278
Simon Glass7cf5fe02019-05-02 10:52:12 -0600279#ifdef CONFIG_X86_RUN_64BIT
Simon Glassb3040752025-05-28 06:32:08 -0600280void __noreturn jump_to_image(struct spl_image_info *spl_image)
Simon Glass030777d2017-01-16 07:03:56 -0700281{
282 int ret;
283
Simon Glassf0dab702025-03-15 14:25:34 +0000284 log_debug("Jumping to 64-bit U-Boot\n");
Simon Glass030777d2017-01-16 07:03:56 -0700285 ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
286 debug("ret=%d\n", ret);
Simon Glass39c6f9b2019-09-25 08:11:38 -0600287 hang();
Simon Glass030777d2017-01-16 07:03:56 -0700288}
Simon Glass7cf5fe02019-05-02 10:52:12 -0600289#endif
290
291void spl_board_init(void)
292{
293#ifndef CONFIG_TPL
294 preloader_console_init();
295#endif
Simon Glass7dc0a452023-07-30 11:16:01 -0600296 if (IS_ENABLED(CONFIG_QEMU))
297 qemu_chipset_init();
Simon Glasse50c4552023-07-15 21:39:01 -0600298
Simon Glass8a4e46e2025-01-10 17:00:22 -0700299 if (CONFIG_IS_ENABLED(UPL_OUT))
300 gd->flags |= GD_FLG_UPL;
301
Simon Glasse50c4552023-07-15 21:39:01 -0600302 if (CONFIG_IS_ENABLED(VIDEO)) {
303 struct udevice *dev;
Simon Glass05f9c642025-01-10 17:00:20 -0700304 int ret;
Simon Glasse50c4552023-07-15 21:39:01 -0600305
306 /* Set up PCI video in SPL if required */
Simon Glass05f9c642025-01-10 17:00:20 -0700307 ret = uclass_first_device_err(UCLASS_PCI, &dev);
308 if (ret)
309 panic("Failed to set up PCI");
310 ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
311 if (ret)
312 panic("Failed to set up video");
Simon Glasse50c4552023-07-15 21:39:01 -0600313 }
Simon Glass7cf5fe02019-05-02 10:52:12 -0600314}