x86: Add a simple TPL implementation
Add the required CPU code so that TPL builds correctly. Also update the
SPL code to deal with being booted from TPL.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h
index 8cf59d1..27432b2 100644
--- a/arch/x86/include/asm/spl.h
+++ b/arch/x86/include/asm/spl.h
@@ -2,6 +2,19 @@
/*
* Copyright (C) 2017 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
- *
- * This file is required for SPL to build, but is empty.
*/
+
+#ifndef __asm_spl_h
+#define __asm_spl_h
+
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+
+enum {
+ BOOT_DEVICE_SPI = 10,
+ BOOT_DEVICE_BOARD,
+ BOOT_DEVICE_CROS_VBOOT,
+};
+
+void jump_to_spl(ulong entry);
+
+#endif
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 56fd680..436252d 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -43,7 +43,14 @@
obj-$(CONFIG_CMD_ZBOOT) += zimage.o
endif
obj-$(CONFIG_HAVE_FSP) += fsp/
-obj-$(CONFIG_SPL_BUILD) += spl.o
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_TPL_BUILD
+obj-y += tpl.o
+else
+obj-y += spl.o
+endif
+endif
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += div64.o
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
index 7d29074..5d5d1a9 100644
--- a/arch/x86/lib/spl.c
+++ b/arch/x86/lib/spl.c
@@ -5,8 +5,10 @@
#include <common.h>
#include <debug_uart.h>
+#include <malloc.h>
#include <spl.h>
#include <asm/cpu.h>
+#include <asm/mrccache.h>
#include <asm/mtrr.h>
#include <asm/processor.h>
#include <asm-generic/sections.h>
@@ -20,6 +22,7 @@
static int x86_spl_init(void)
{
+#ifndef CONFIG_TPL
/*
* TODO(sjg@chromium.org): We use this area of RAM for the stack
* and global_data in SPL. Once U-Boot starts up and releocates it
@@ -27,6 +30,7 @@
* place it immediately below CONFIG_SYS_TEXT_BASE.
*/
char *ptr = (char *)0x110000;
+#endif
int ret;
debug("%s starting\n", __func__);
@@ -35,27 +39,44 @@
debug("%s: spl_init() failed\n", __func__);
return ret;
}
+#ifdef CONFIG_TPL
+ /* Do a mini-init if TPL has already done the full init */
+ ret = x86_cpu_reinit_f();
+#else
ret = arch_cpu_init();
+#endif
if (ret) {
debug("%s: arch_cpu_init() failed\n", __func__);
return ret;
}
+#ifndef CONFIG_TPL
ret = arch_cpu_init_dm();
if (ret) {
debug("%s: arch_cpu_init_dm() failed\n", __func__);
return ret;
}
+#endif
preloader_console_init();
+#ifndef CONFIG_TPL
ret = print_cpuinfo();
if (ret) {
debug("%s: print_cpuinfo() failed\n", __func__);
return ret;
}
+#endif
ret = dram_init();
if (ret) {
debug("%s: dram_init() failed\n", __func__);
return ret;
}
+ if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) {
+ ret = mrccache_spl_save();
+ if (ret)
+ debug("%s: Failed to write to mrccache (err=%d)\n",
+ __func__, ret);
+ }
+
+#ifndef CONFIG_TPL
memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
/* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
@@ -80,9 +101,11 @@
(1ULL << 32) - CONFIG_XIP_ROM_SIZE,
CONFIG_XIP_ROM_SIZE);
if (ret) {
- debug("%s: SPI cache setup failed\n", __func__);
+ debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
return ret;
}
+ mtrr_commit(true);
+#endif
return 0;
}
@@ -96,9 +119,17 @@
debug("Error %d\n", ret);
hang();
}
-
+#ifdef CONFIG_TPL
+ gd->bd = malloc(sizeof(*gd->bd));
+ if (!gd->bd) {
+ printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd));
+ hang();
+ }
+ board_init_r(gd, 0);
+#else
/* Uninit CAR and jump to board_init_f_r() */
board_init_f_r_trampoline(gd->start_addr_sp);
+#endif
}
void board_init_f_r(void)
@@ -144,6 +175,7 @@
return -EPERM;
}
+#ifdef CONFIG_X86_RUN_64BIT
void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
int ret;
@@ -154,3 +186,11 @@
while (1)
;
}
+#endif
+
+void spl_board_init(void)
+{
+#ifndef CONFIG_TPL
+ preloader_console_init();
+#endif
+}
diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c
new file mode 100644
index 0000000..492a2d6
--- /dev/null
+++ b/arch/x86/lib/tpl.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Google, Inc
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <spl.h>
+#include <asm/cpu.h>
+#include <asm/mtrr.h>
+#include <asm/processor.h>
+#include <asm-generic/sections.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak int arch_cpu_init_dm(void)
+{
+ return 0;
+}
+
+static int x86_tpl_init(void)
+{
+ int ret;
+
+ debug("%s starting\n", __func__);
+ ret = spl_init();
+ if (ret) {
+ debug("%s: spl_init() failed\n", __func__);
+ return ret;
+ }
+ ret = arch_cpu_init();
+ if (ret) {
+ debug("%s: arch_cpu_init() failed\n", __func__);
+ return ret;
+ }
+ ret = arch_cpu_init_dm();
+ if (ret) {
+ debug("%s: arch_cpu_init_dm() failed\n", __func__);
+ return ret;
+ }
+ preloader_console_init();
+ ret = print_cpuinfo();
+ if (ret) {
+ debug("%s: print_cpuinfo() failed\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+void board_init_f(ulong flags)
+{
+ int ret;
+
+ ret = x86_tpl_init();
+ if (ret) {
+ debug("Error %d\n", ret);
+ hang();
+ }
+
+ /* Uninit CAR and jump to board_init_f_r() */
+ board_init_r(gd, 0);
+}
+
+void board_init_f_r(void)
+{
+ /* Not used since we never call board_init_f_r_trampoline() */
+ while (1);
+}
+
+u32 spl_boot_device(void)
+{
+ return IS_ENABLED(CONFIG_CHROMEOS) ? BOOT_DEVICE_CROS_VBOOT :
+ BOOT_DEVICE_BOARD;
+}
+
+int spl_start_uboot(void)
+{
+ return 0;
+}
+
+void spl_board_announce_boot_device(void)
+{
+ printf("SPI flash");
+}
+
+static int spl_board_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ spl_image->size = CONFIG_SYS_MONITOR_LEN; /* We don't know SPL size */
+ spl_image->entry_point = CONFIG_SPL_TEXT_BASE;
+ spl_image->load_addr = CONFIG_SPL_TEXT_BASE;
+ spl_image->os = IH_OS_U_BOOT;
+ spl_image->name = "U-Boot";
+
+ debug("Loading to %lx\n", spl_image->load_addr);
+
+ return 0;
+}
+SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
+
+int spl_spi_load_image(void)
+{
+ return -EPERM;
+}
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+ printf("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point);
+ jump_to_spl(spl_image->entry_point);
+ while (1)
+ ;
+}
+
+void spl_board_init(void)
+{
+ preloader_console_init();
+}