[coreboot-gerrit] Patch set updated for coreboot: WIP: arch/x86: Allow boot flow which runs CAR setup in bootblock

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Sun Oct 11 10:34:22 CEST 2015


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11784

-gerrit

commit 39ac4dd219c6b3b01457dbcd6e3157693948f844
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Fri Oct 2 12:42:26 2015 -0700

    WIP: arch/x86: Allow boot flow which runs CAR setup in bootblock
    
    On systems with non-memory-mapped boot media we simply do not have
    enough space for romstage. This means that CAR setup and early boot
    media (e.g. SPI) drivers need to be implemented with minimal overhead.
    The bootblock is the best place to do this.
    
    Note that this patch does introduce a somewhat awkward boot flow:
    reset(gas) -> bootblock main (romcc) -> car setup (gas) -> car (gcc)
    However, we've chosen this path as it is least intrusive on the
    existing infrastructure. In the future, we will investigate the
    possiblity of eliminating the romcc step.
    
    Change-Id: Icbf5804b66b9517f9ceb352bed86978dcf92228f
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 src/arch/x86/Kconfig                    |  7 +++
 src/arch/x86/Makefile.inc               | 11 ++++-
 src/arch/x86/bootblock.S                | 44 -------------------
 src/arch/x86/bootblock_legacy.S         | 56 ++++++++++++++++++++++++
 src/arch/x86/bootblock_modern.S         | 56 ++++++++++++++++++++++++
 src/arch/x86/bootblock_normal.c         |  2 +-
 src/arch/x86/bootblock_simple.c         |  2 +-
 src/arch/x86/include/arch/cbfs.h        |  6 +--
 src/arch/x86/include/bootblock.h        | 19 ++++++++
 src/arch/x86/include/bootblock_common.h | 77 ---------------------------------
 src/arch/x86/include/bootblock_legacy.h | 77 +++++++++++++++++++++++++++++++++
 11 files changed, 229 insertions(+), 128 deletions(-)

diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 88b2592..412e504 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -56,6 +56,13 @@ config ARCH_RAMSTAGE_X86_64
 	bool
 	default n
 
+# This is a new bootflow, in which a C environment is available in the
+# bootblock. That can be achieved either by performing CAR setup is in the
+# bootblock, or using memory available at boot-time (e.g. SRAM)
+config C_ENVIRONMENT_BOOTBLOCK
+	bool
+	default n
+
 # This is an SMP option. It relates to starting up APs.
 # It is usually set in mainboard/*/Kconfig.
 # TODO: Improve description.
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 56b176d..2df99cb 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -85,9 +85,7 @@ endif
 # the right order. Make sure the auto generated bootblock.inc is a proper
 # dependency. Make the same true for the linker sript.
 bootblock-y += id.S
-bootblock-y += bootblock.S
 bootblock-y += walkcbfs.S
-$(obj)/arch/x86/bootblock.bootblock.o: $(objgenerated)/bootblock.inc
 
 bootblock-y += bootblock.ld
 $(obj)/arch/x86/bootblock.bootblock.ld: $(objgenerated)/bootblock.ld
@@ -106,11 +104,20 @@ $(objgenerated)/bootblock.ld: $$(filter-out $(obj)/arch/x86/bootblock.bootblock.
 	cat $^ >> $@.tmp
 	mv $@.tmp $@
 
+ifeq ($(CONFIG_C_ENVIRONMENT_BOOTBLOCK),y)
+bootblock-y += bootblock_modern.S
+bootblock-y += bootblock.c
+else
+bootblock-y += bootblock_legacy.S
+
+$(obj)/arch/x86/bootblock.bootblock.o: $(objgenerated)/bootblock.inc
+
 $(objgenerated)/bootblock.inc: $(src)/arch/x86/$(subst ",,$(CONFIG_BOOTBLOCK_SOURCE)) $(objutil)/romcc/romcc $(OPTION_TABLE_H) $(KCONFIG_AUTOHEADER)
 	@printf "    ROMCC      $(subst $(obj)/,,$(@))\n"
 	$(CC_bootblock) $(CPPFLAGS_bootblock) -MM -MT$(objgenerated)/bootblock.inc \
 		$< > $(objgenerated)/bootblock.inc.d
 	$(ROMCC) -c -S $(bootblock_romccflags) -I. $(CPPFLAGS_bootblock) $< -o $@
+endif
 
 # $(obj)/arch/x86/bootblock.bootblock.ld is part of $(bootblock-objs)
 $(objcbfs)/bootblock.debug: $$(bootblock-objs)
diff --git a/src/arch/x86/bootblock.S b/src/arch/x86/bootblock.S
deleted file mode 100644
index 645e491..0000000
--- a/src/arch/x86/bootblock.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright 2015 Google Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc.
- */
-
-/* This file assembles the bootblock program by the order of the includes. Thus,
- * it's extremely important that one pays very careful attention to the order
- * of the includes. */
-
-#include <arch/x86/prologue.inc>
-#include <cpu/x86/16bit/entry16.inc>
-#include <cpu/x86/16bit/reset16.inc>
-#include <cpu/x86/32bit/entry32.inc>
-
-#ifdef CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
-#include CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
-#endif
-
-#if IS_ENABLED(CONFIG_SSE)
-#include <cpu/x86/sse_enable.inc>
-#endif
-
-/*
- * This bootblock.inc file is generated by ROMCC. The above program flow
- * falls through to this point. ROMCC assumes the last function it parsed
- * is the main function and it places its instructions at the beginning of
- * the generated file. Moreover, any library/common code needed in bootblock
- * needs to come after bootblock.inc.
- */
-#include <generated/bootblock.inc>
diff --git a/src/arch/x86/bootblock_legacy.S b/src/arch/x86/bootblock_legacy.S
new file mode 100644
index 0000000..5b0fd17
--- /dev/null
+++ b/src/arch/x86/bootblock_legacy.S
@@ -0,0 +1,56 @@
+/*
+ * This is the original bootblock used by coreboot on x86 systems. It contains
+ * a monolithic code flow, assembled from the following stages:
+ *     - reset16.inc: the reset vector
+ *     - entry16.inc: protected mode setup
+ *     - entry16.inc: segment descriptor setup
+ *     - CONFIG_CHIPSET_BOOTBLOCK_INCLUDE: chipset-specific initialization
+ *     - generated/bootblock.inc: ROMCC part of the bootblock
+ *
+ * This is used on platforms which do not select C_ENVIRONMENT_BOOTBLOCK, and it
+ * tries to do the absolute minimum before walking CBFS and jumping to romstage.
+ *
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+/* This file assembles the bootblock program by the order of the includes. Thus,
+ * it's extremely important that one pays very careful attention to the order
+ * of the includes. */
+
+#include <arch/x86/prologue.inc>
+#include <cpu/x86/16bit/entry16.inc>
+#include <cpu/x86/16bit/reset16.inc>
+#include <cpu/x86/32bit/entry32.inc>
+
+#ifdef CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
+#include CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
+#endif
+
+#if IS_ENABLED(CONFIG_SSE)
+#include <cpu/x86/sse_enable.inc>
+#endif
+
+/*
+ * This bootblock.inc file is generated by ROMCC. The above program flow
+ * falls through to this point. ROMCC assumes the last function it parsed
+ * is the main function and it places its instructions at the beginning of
+ * the generated file. Moreover, any library/common code needed in bootblock
+ * needs to come after bootblock.inc.
+ */
+#include <generated/bootblock.inc>
+#endif /* !IS_ENABLED(CONFIG_C_ENVIRONMENT_BOOTBLOCK) */
diff --git a/src/arch/x86/bootblock_modern.S b/src/arch/x86/bootblock_modern.S
new file mode 100644
index 0000000..379228c
--- /dev/null
+++ b/src/arch/x86/bootblock_modern.S
@@ -0,0 +1,56 @@
+/*
+ * This is the modern bootblock. It is used by platforms which select
+ * C_ENVIRONMENT_BOOTBLOCK, and it prepares the system for C environment runtime
+ * setup. The actual setup is done by hardware-specific code.
+ *
+ * It provides a bootflow similar to other architectures, and thus is considered
+ * to be the modern approach.
+ *
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define CR0_MP		(1 << 1)
+#define CR0_EM		(1 << 2)
+
+#define CR4_OSFXSR	(1 << 9)
+#define CR4_OSXMMEXCPT	(1 << 10)
+
+/*
+ * Include the old code for reset vector and protected mode entry. That code has
+ * withstood the test of time
+ */
+#include <arch/x86/prologue.inc>
+#include <cpu/x86/16bit/entry16.inc>
+#include <cpu/x86/16bit/reset16.inc>
+#include <cpu/x86/32bit/entry32.inc>
+
+.intel_syntax noprefix
+
+ready_for_business:
+	/* Save BIST result */
+	movd	mm0, eax
+	/* Save an early timestamp */
+	rdtsc
+	movd	mm1, eax
+	movd	mm2, edx
+
+#if !IS_ENABLED(CONFIG_SSE)
+enable_sse:
+	mov	eax, cr0
+	and	ax, not CR0_EM		//;clear coprocessor emulation CR0.EM
+	or	ax, CR0_MP		//;set coprocessor monitoring  CR0.MP
+	mov	cr0, eax
+	mov	eax, cr4
+	or	ax, (CR4_OSFXSR | CR4_OSXMMEXCPT)
+	mov	cr4, eax
+#endif /* IS_ENABLED(CONFIG_SSE) */
+
+	/* We're done. Now it's up to platform-specific code */
+	jmp	bootblock_pre_c_entry
diff --git a/src/arch/x86/bootblock_normal.c b/src/arch/x86/bootblock_normal.c
index bde2535..aaf35ab 100644
--- a/src/arch/x86/bootblock_normal.c
+++ b/src/arch/x86/bootblock_normal.c
@@ -1,5 +1,5 @@
 #include <smp/node.h>
-#include <bootblock_common.h>
+#include <bootblock_legacy.h>
 #include <pc80/mc146818rtc.h>
 #include <halt.h>
 
diff --git a/src/arch/x86/bootblock_simple.c b/src/arch/x86/bootblock_simple.c
index adeecf7..64dc9b5 100644
--- a/src/arch/x86/bootblock_simple.c
+++ b/src/arch/x86/bootblock_simple.c
@@ -1,5 +1,5 @@
 #include <smp/node.h>
-#include <bootblock_common.h>
+#include <bootblock_legacy.h>
 #include <halt.h>
 
 static void main(unsigned long bist)
diff --git a/src/arch/x86/include/arch/cbfs.h b/src/arch/x86/include/arch/cbfs.h
index 719f8f5..8be8818 100644
--- a/src/arch/x86/include/arch/cbfs.h
+++ b/src/arch/x86/include/arch/cbfs.h
@@ -25,7 +25,7 @@
 
 #define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) )
 
-static struct cbfs_file *walkcbfs_head(char *target)
+static struct cbfs_file *walkcbfs_head(const char *target)
 {
 	void *entry;
 	asm volatile (
@@ -35,7 +35,7 @@ static struct cbfs_file *walkcbfs_head(char *target)
 	return entry;
 }
 
-static void *walkcbfs(char *target)
+static void *walkcbfs(const char *target)
 {
 	struct cbfs_file *head = walkcbfs_head(target);
 	if ((u32)head != 0)
@@ -51,7 +51,7 @@ struct cbfs_stage_restricted {
 	unsigned long entry; // this is really 64bit, but properly endianized
 };
 
-static inline unsigned long findstage(char* target)
+static inline unsigned long findstage(const char* target)
 {
 	struct cbfs_stage_restricted *stage = walkcbfs(target);
 	if ((u32)stage != 0)
diff --git a/src/arch/x86/include/bootblock.h b/src/arch/x86/include/bootblock.h
new file mode 100644
index 0000000..6408de3
--- /dev/null
+++ b/src/arch/x86/include/bootblock.h
@@ -0,0 +1,19 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _ARCH_X86_BOOTBLOCK_H
+#define _ARCH_X86_BOOTBLOCK_H
+
+#include <arch/cpu.h>
+
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi);
+
+#endif _ARCH_X86_BOOTBLOCK_H
diff --git a/src/arch/x86/include/bootblock_common.h b/src/arch/x86/include/bootblock_common.h
deleted file mode 100644
index 939ba08..0000000
--- a/src/arch/x86/include/bootblock_common.h
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <arch/cbfs.h>
-#include <cpu/x86/lapic/boot_cpu.c>
-#include <pc80/mc146818rtc.h>
-
-#ifdef CONFIG_BOOTBLOCK_RESETS
-#include CONFIG_BOOTBLOCK_RESETS
-#endif
-
-#ifdef CONFIG_BOOTBLOCK_CPU_INIT
-#include CONFIG_BOOTBLOCK_CPU_INIT
-#endif
-#ifdef CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
-#include CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
-#endif
-#ifdef CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
-#include CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
-#endif
-
-#ifdef CONFIG_BOOTBLOCK_MAINBOARD_INIT
-#include CONFIG_BOOTBLOCK_MAINBOARD_INIT
-#else
-static void bootblock_mainboard_init(void)
-{
-#ifdef CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
-	bootblock_northbridge_init();
-#endif
-#ifdef CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
-	bootblock_southbridge_init();
-#endif
-#ifdef CONFIG_BOOTBLOCK_CPU_INIT
-	bootblock_cpu_init();
-#endif
-}
-#endif
-
-#if CONFIG_USE_OPTION_TABLE
-static void sanitize_cmos(void)
-{
-	if (cmos_error() || !cmos_chksum_valid() || IS_ENABLED(CONFIG_STATIC_OPTION_TABLE)) {
-		unsigned char *cmos_default = (unsigned char*)walkcbfs("cmos.default");
-		if (cmos_default) {
-			int i;
-			cmos_disable_rtc();
-			for (i = 14; i < 128; i++) {
-				cmos_write_inner(cmos_default[i], i);
-			}
-			cmos_enable_rtc();
-		}
-	}
-}
-#endif
-
-#if CONFIG_CMOS_POST
-static void cmos_post_init(void)
-{
-	u8 magic = CMOS_POST_BANK_0_MAGIC;
-
-	/* Switch to the other bank */
-	switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
-	case CMOS_POST_BANK_1_MAGIC:
-		break;
-	case CMOS_POST_BANK_0_MAGIC:
-		magic = CMOS_POST_BANK_1_MAGIC;
-		break;
-	default:
-		/* Initialize to zero */
-		cmos_write(0, CMOS_POST_BANK_0_OFFSET);
-		cmos_write(0, CMOS_POST_BANK_1_OFFSET);
-#if CONFIG_CMOS_POST_EXTRA
-		cmos_write32(CMOS_POST_BANK_0_EXTRA, 0);
-		cmos_write32(CMOS_POST_BANK_1_EXTRA, 0);
-#endif
-	}
-
-	cmos_write(magic, CMOS_POST_BANK_OFFSET);
-}
-#endif
diff --git a/src/arch/x86/include/bootblock_legacy.h b/src/arch/x86/include/bootblock_legacy.h
new file mode 100644
index 0000000..939ba08
--- /dev/null
+++ b/src/arch/x86/include/bootblock_legacy.h
@@ -0,0 +1,77 @@
+#include <arch/cbfs.h>
+#include <cpu/x86/lapic/boot_cpu.c>
+#include <pc80/mc146818rtc.h>
+
+#ifdef CONFIG_BOOTBLOCK_RESETS
+#include CONFIG_BOOTBLOCK_RESETS
+#endif
+
+#ifdef CONFIG_BOOTBLOCK_CPU_INIT
+#include CONFIG_BOOTBLOCK_CPU_INIT
+#endif
+#ifdef CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
+#include CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
+#endif
+#ifdef CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
+#include CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
+#endif
+
+#ifdef CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#include CONFIG_BOOTBLOCK_MAINBOARD_INIT
+#else
+static void bootblock_mainboard_init(void)
+{
+#ifdef CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT
+	bootblock_northbridge_init();
+#endif
+#ifdef CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT
+	bootblock_southbridge_init();
+#endif
+#ifdef CONFIG_BOOTBLOCK_CPU_INIT
+	bootblock_cpu_init();
+#endif
+}
+#endif
+
+#if CONFIG_USE_OPTION_TABLE
+static void sanitize_cmos(void)
+{
+	if (cmos_error() || !cmos_chksum_valid() || IS_ENABLED(CONFIG_STATIC_OPTION_TABLE)) {
+		unsigned char *cmos_default = (unsigned char*)walkcbfs("cmos.default");
+		if (cmos_default) {
+			int i;
+			cmos_disable_rtc();
+			for (i = 14; i < 128; i++) {
+				cmos_write_inner(cmos_default[i], i);
+			}
+			cmos_enable_rtc();
+		}
+	}
+}
+#endif
+
+#if CONFIG_CMOS_POST
+static void cmos_post_init(void)
+{
+	u8 magic = CMOS_POST_BANK_0_MAGIC;
+
+	/* Switch to the other bank */
+	switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
+	case CMOS_POST_BANK_1_MAGIC:
+		break;
+	case CMOS_POST_BANK_0_MAGIC:
+		magic = CMOS_POST_BANK_1_MAGIC;
+		break;
+	default:
+		/* Initialize to zero */
+		cmos_write(0, CMOS_POST_BANK_0_OFFSET);
+		cmos_write(0, CMOS_POST_BANK_1_OFFSET);
+#if CONFIG_CMOS_POST_EXTRA
+		cmos_write32(CMOS_POST_BANK_0_EXTRA, 0);
+		cmos_write32(CMOS_POST_BANK_1_EXTRA, 0);
+#endif
+	}
+
+	cmos_write(magic, CMOS_POST_BANK_OFFSET);
+}
+#endif



More information about the coreboot-gerrit mailing list