Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/12870
-gerrit
commit c2437165f549bef145abed571db997701985486e
Author: Alexandru Gagniuc <alexandrux.gagniuc(a)intel.com>
Date: Tue Oct 6 16:35:39 2015 -0700
src/arch/x86: Link the compiler runtime library in the bootblock
At least on GCC __udivdi3 and __umoddi3 are needed by the console
code. They are provided by the compiler runtime library.
Change-Id: I78bbea425c33d7eebaf829d58d763b7a1c6e997c
Signed-off-by: Alexandru Gagniuc <alexandrux.gagniuc(a)intel.com>
---
src/arch/x86/Makefile.inc | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index f372645..c940f44 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -112,8 +112,12 @@ endif
# $(obj)/arch/x86/bootblock.bootblock.ld is part of $(bootblock-objs)
$(objcbfs)/bootblock.debug: $$(bootblock-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) \
- $(filter-out %.ld,$(bootblock-objs)) \
+ $(LD_bootblock) $(LDFLAGS_bootblock) -static \
+ -o $@ $(COMPILER_RT_FLAGS_bootblock) -L$(obj) \
+ -whole-archive --start-group \
+ $(filter %.o,$(bootblock-objs)) \
+ --no-whole-archive $(COMPILER_RT_bootblock) \
+ --end-group \
-T $(obj)/arch/x86/bootblock.bootblock.ld
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/12868
-gerrit
commit 777db72d761508d3f84d89761e665177a9f13e28
Author: Martin Roth <martinroth(a)google.com>
Date: Tue Dec 22 12:40:53 2015 -0700
fsp_baytrail: Add additional PCI space above 4GB
This just tells the OS that it can use the 16GB of address space
at the 48GB mark for PCI. This is the upper 16GB of Bay Trail's 36 bit
physical address space.
This could be hardcoded into the UMEM definition, but doing it this way
makes it more plain what it's doing, and allows for modification
to put it just above the top of upper memory, similar to what is done
with the standard PCI region above the top of low memory.
Change-Id: Idb17ea919eb71e31c5f1a2f08599a412825b9c25
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Original-Commit-Id:
Original-Change-Id: Id6208c3712e5d94d62a83c4ac69e8ffd0e19f4ad
Original-Signed-off-by: Martin Roth <martinroth(a)google.com>
Original-Reviewed-on: https://review.coreboot.org/12791
Original-Tested-by: build bot (Jenkins)
Original-Reviewed-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Original-Reviewed-by: York Yang <york.yang(a)intel.com>
---
src/soc/intel/fsp_baytrail/acpi/southcluster.asl | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/soc/intel/fsp_baytrail/acpi/southcluster.asl b/src/soc/intel/fsp_baytrail/acpi/southcluster.asl
index 2fbdb16..a38b742 100644
--- a/src/soc/intel/fsp_baytrail/acpi/southcluster.asl
+++ b/src/soc/intel/fsp_baytrail/acpi/southcluster.asl
@@ -163,6 +163,12 @@ Name (MCRS, ResourceTemplate()
Cacheable, ReadWrite,
0x00000000, 0xfed40000, 0xfed44fff, 0x00000000,
0x00005000,,, TPMR)
+
+ // High PCI Memory Region
+ QwordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ Cacheable, ReadWrite,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000,,, UMEM)
})
Method (_CRS, 0, Serialized)
@@ -177,6 +183,15 @@ Method (_CRS, 0, Serialized)
Store (Subtract(CONFIG_MMCONF_BASE_ADDRESS, 1), PMAX)
Add (Subtract (PMAX, PMIN), 1, PLEN)
+ // Update High PCI resource area
+ CreateQwordField(MCRS, ^UMEM._MIN, UMIN)
+ CreateQwordField(MCRS, ^UMEM._MAX, UMAX)
+ CreateQwordField(MCRS, ^UMEM._LEN, ULEN)
+
+ Store(0x40000000 * 48, UMIN) // Set base address to 48GB
+ Store(0x40000000 * 16, ULEN) // Allocate 16GB for PCI space
+ Add(UMIN, Subtract(ULEN, 1), UMAX)
+
Return (MCRS)
}
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/11858
-gerrit
commit 0cf1773806ca08ec5e65515965ca882df1ec34ea
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sat Oct 10 16:35:58 2015 -0700
cpu/qemu-x86: Run a C environment in the bootblock
Make use of the ROMCC-less bootblock introduced earlier. The "qemu"
cpu is particularly easy because it does not require CAR setup.
Change-Id: Idf161d363d2daf3c55454d376ca42d492463971a
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/cpu/qemu-x86/Kconfig | 1 +
src/cpu/qemu-x86/Makefile.inc | 2 ++
src/cpu/qemu-x86/bootblock.c | 55 ++++++++++++++++++++++++++++++++++++++++
src/cpu/qemu-x86/bootblock_asm.S | 48 +++++++++++++++++++++++++++++++++++
4 files changed, 106 insertions(+)
diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig
index ea2bc46..0ace941 100644
--- a/src/cpu/qemu-x86/Kconfig
+++ b/src/cpu/qemu-x86/Kconfig
@@ -19,4 +19,5 @@ config CPU_QEMU_X86
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
+ select C_ENVIRONMENT_BOOTBLOCK
select SMP
diff --git a/src/cpu/qemu-x86/Makefile.inc b/src/cpu/qemu-x86/Makefile.inc
index b5f8369..0ed76f9 100644
--- a/src/cpu/qemu-x86/Makefile.inc
+++ b/src/cpu/qemu-x86/Makefile.inc
@@ -12,6 +12,8 @@
## GNU General Public License for more details.
##
+bootblock-y += bootblock_asm.S
+bootblock-y += bootblock.c
ramstage-y += qemu.c
subdirs-y += ../x86/mtrr
subdirs-y += ../x86/lapic
diff --git a/src/cpu/qemu-x86/bootblock.c b/src/cpu/qemu-x86/bootblock.c
new file mode 100644
index 0000000..92dd6f7
--- /dev/null
+++ b/src/cpu/qemu-x86/bootblock.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me(a)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.
+ */
+
+#include <arch/cpu.h>
+#include <cbfs.h>
+#include <halt.h>
+
+/* Called from assembly. Prototype not needed by external .c file */
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi);
+
+/*
+ * TODO: Implement a generic fallback/normal mechanism
+ */
+static const char *get_next_stage_name(void)
+{
+ if (IS_ENABLED(CONFIG_BOOTBLOCK_SIMPLE))
+ return CONFIG_CBFS_PREFIX "/romstage";
+
+ /* BOOTBLOCK_NORMAL not implemented */
+ return CONFIG_CBFS_PREFIX "/romstage";
+}
+
+static void enter_romstage(void *romstage_entry, uint32_t bist)
+{
+ asm volatile (
+ "jmp *%0\n\t"
+ : : "r" (romstage_entry), "a" (bist)
+ );
+}
+
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi)
+{
+ void *entry;
+ struct cbfs_stage *romstage;
+ const char* target1 = get_next_stage_name();
+
+ romstage = cbfs_boot_map_with_leak(target1, CBFS_TYPE_STAGE, NULL);
+
+ /*
+ * TODO: Do something constructive with tsc_lo and tsc_hi
+ */
+ if (romstage) {
+ entry = (void *)(uintptr_t)romstage->entry;
+ enter_romstage(entry, bist);
+ }
+ halt();
+}
diff --git a/src/cpu/qemu-x86/bootblock_asm.S b/src/cpu/qemu-x86/bootblock_asm.S
new file mode 100644
index 0000000..6e1cd2e
--- /dev/null
+++ b/src/cpu/qemu-x86/bootblock_asm.S
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me(a)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.
+ */
+
+#include <console/post_codes.h>
+
+#define STACK_SIZE 0x10000
+#define STACK_BASE 0xd0000
+
+.intel_syntax noprefix
+
+#define post_code(code) \
+ mov eax, code; \
+ out 0x80, eax
+
+.global bootblock_pre_c_entry
+
+.section .text
+bootblock_pre_c_entry:
+
+ /* Set up a stack */
+ mov esp, (STACK_BASE + STACK_SIZE - 4)
+
+ /*
+ * We have the following values saved from earlier:
+ * mm0: BIST result
+ * mm1: TSC timestamp low 32 bits
+ * mm2: TSC timestamp high 32 bits
+ */
+ movd eax, mm2
+ push eax
+ movd eax, mm1
+ push eax
+ movd eax, mm0
+ push eax
+ call bootblock_main
+
+.halt_forever:
+ post_code(POST_DEAD_CODE)
+ hlt
+ jmp .halt_forever
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/11784
-gerrit
commit 0c2292e361274222a19bfaa893dfca66525afe77
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 12:42:26 2015 -0700
arch/x86: Allow boot flow which runs CAR setup in bootblock
Some newer x86 systems can boot from non-memory-mapped boot media
(e.g. EMMC). The bootblock may be backed by small amounts of SRAM, or
other memory, similar to how most ARM chipsets work. In such cases, we
may not have enough code space for romstage very early on. This means
that CAR setup and early boot media (e.g. SPI, EMMC) drivers need to
be implemented within the limited amount memory of storage available.
Since the reset vector has to be contained in this early code memory,
the bootblock is the best place to implement loading of other stages.
This patch only adds the infrastructure to intercept the boot flow of
the bootblock before jumping to ROMCC segments, after which the
execution is passed to platform-specific code.
Change-Id: Icbf5804b66b9517f9ceb352bed86978dcf92228f
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Kconfig | 7 ++++++
src/arch/x86/Makefile.inc | 16 +++++++++---
src/arch/x86/bootblock.S | 40 -----------------------------
src/arch/x86/bootblock_crt0.S | 56 +++++++++++++++++++++++++++++++++++++++++
src/arch/x86/bootblock_legacy.S | 53 ++++++++++++++++++++++++++++++++++++++
5 files changed, 128 insertions(+), 44 deletions(-)
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 738e7d1..28ec524 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -58,6 +58,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 9713d52..f372645 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -68,16 +68,15 @@ else
LDFLAGS_bootblock += -m elf_x86_64 --oformat elf64-x86-64
endif
+bootblock-y += memcpy.c
+bootblock-y += mmap_boot.c
+
# Add the assembly file that pulls in the rest of the dependencies in
# 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
$(obj)/arch/x86/id.bootblock.o: $(obj)/build.h
-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
@@ -95,11 +94,20 @@ $(objgenerated)/bootblock.ld: $$(filter-out $(obj)/arch/x86/bootblock.bootblock.
cat $^ >> $@.tmp
mv $@.tmp $@
+ifeq ($(CONFIG_C_ENVIRONMENT_BOOTBLOCK),y)
+bootblock-y += bootblock_crt0.S
+else
+bootblock-y += bootblock_legacy.S
+bootblock-y += walkcbfs.S
+
+$(obj)/arch/x86/bootblock_legacy.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 27a23eb..0000000
--- a/src/arch/x86/bootblock.S
+++ /dev/null
@@ -1,40 +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.
- */
-
-/* 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_crt0.S b/src/arch/x86/bootblock_crt0.S
new file mode 100644
index 0000000..a9023b9
--- /dev/null
+++ b/src/arch/x86/bootblock_crt0.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(a)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
+
+bootblock_protected_mode_entry:
+ /* 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_legacy.S b/src/arch/x86/bootblock_legacy.S
new file mode 100644
index 0000000..6c1723a
--- /dev/null
+++ b/src/arch/x86/bootblock_legacy.S
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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
+ * - entry32.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 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>
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/11858
-gerrit
commit b2e05ddb5ec1735a776500bb7f7737f28d97b184
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sat Oct 10 16:35:58 2015 -0700
cpu/qemu-x86: Run a C environment in the bootblock
Make use of the ROMCC-less bootblock introduced earlier. The "qemu"
cpu is particularly easy because it does not require CAR setup.
Change-Id: Idf161d363d2daf3c55454d376ca42d492463971a
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/cpu/qemu-x86/Kconfig | 1 +
src/cpu/qemu-x86/Makefile.inc | 2 ++
src/cpu/qemu-x86/bootblock.c | 55 ++++++++++++++++++++++++++++++++++++++++
src/cpu/qemu-x86/bootblock_asm.S | 48 +++++++++++++++++++++++++++++++++++
4 files changed, 106 insertions(+)
diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig
index ea2bc46..0ace941 100644
--- a/src/cpu/qemu-x86/Kconfig
+++ b/src/cpu/qemu-x86/Kconfig
@@ -19,4 +19,5 @@ config CPU_QEMU_X86
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
+ select C_ENVIRONMENT_BOOTBLOCK
select SMP
diff --git a/src/cpu/qemu-x86/Makefile.inc b/src/cpu/qemu-x86/Makefile.inc
index b5f8369..0ed76f9 100644
--- a/src/cpu/qemu-x86/Makefile.inc
+++ b/src/cpu/qemu-x86/Makefile.inc
@@ -12,6 +12,8 @@
## GNU General Public License for more details.
##
+bootblock-y += bootblock_asm.S
+bootblock-y += bootblock.c
ramstage-y += qemu.c
subdirs-y += ../x86/mtrr
subdirs-y += ../x86/lapic
diff --git a/src/cpu/qemu-x86/bootblock.c b/src/cpu/qemu-x86/bootblock.c
new file mode 100644
index 0000000..92dd6f7
--- /dev/null
+++ b/src/cpu/qemu-x86/bootblock.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me(a)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.
+ */
+
+#include <arch/cpu.h>
+#include <cbfs.h>
+#include <halt.h>
+
+/* Called from assembly. Prototype not needed by external .c file */
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi);
+
+/*
+ * TODO: Implement a generic fallback/normal mechanism
+ */
+static const char *get_next_stage_name(void)
+{
+ if (IS_ENABLED(CONFIG_BOOTBLOCK_SIMPLE))
+ return CONFIG_CBFS_PREFIX "/romstage";
+
+ /* BOOTBLOCK_NORMAL not implemented */
+ return CONFIG_CBFS_PREFIX "/romstage";
+}
+
+static void enter_romstage(void *romstage_entry, uint32_t bist)
+{
+ asm volatile (
+ "jmp *%0\n\t"
+ : : "r" (romstage_entry), "a" (bist)
+ );
+}
+
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi)
+{
+ void *entry;
+ struct cbfs_stage *romstage;
+ const char* target1 = get_next_stage_name();
+
+ romstage = cbfs_boot_map_with_leak(target1, CBFS_TYPE_STAGE, NULL);
+
+ /*
+ * TODO: Do something constructive with tsc_lo and tsc_hi
+ */
+ if (romstage) {
+ entry = (void *)(uintptr_t)romstage->entry;
+ enter_romstage(entry, bist);
+ }
+ halt();
+}
diff --git a/src/cpu/qemu-x86/bootblock_asm.S b/src/cpu/qemu-x86/bootblock_asm.S
new file mode 100644
index 0000000..6e1cd2e
--- /dev/null
+++ b/src/cpu/qemu-x86/bootblock_asm.S
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me(a)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.
+ */
+
+#include <console/post_codes.h>
+
+#define STACK_SIZE 0x10000
+#define STACK_BASE 0xd0000
+
+.intel_syntax noprefix
+
+#define post_code(code) \
+ mov eax, code; \
+ out 0x80, eax
+
+.global bootblock_pre_c_entry
+
+.section .text
+bootblock_pre_c_entry:
+
+ /* Set up a stack */
+ mov esp, (STACK_BASE + STACK_SIZE - 4)
+
+ /*
+ * We have the following values saved from earlier:
+ * mm0: BIST result
+ * mm1: TSC timestamp low 32 bits
+ * mm2: TSC timestamp high 32 bits
+ */
+ movd eax, mm2
+ push eax
+ movd eax, mm1
+ push eax
+ movd eax, mm0
+ push eax
+ call bootblock_main
+
+.halt_forever:
+ post_code(POST_DEAD_CODE)
+ hlt
+ jmp .halt_forever
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/11784
-gerrit
commit 0a959a9efda2fb0877ebad4b521182afe9de41ba
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 12:42:26 2015 -0700
arch/x86: Allow boot flow which runs CAR setup in bootblock
Some newer x86 systems can boot from non-memory-mapped boot media
(e.g. EMMC). The bootblock may be backed by small amounts of SRAM, or
other memory, similar to how most ARM chipsets work. In such cases, we
may not have enough code space for romstage very early on. This means
that CAR setup and early boot media (e.g. SPI, EMMC) drivers need to
be implemented within the limited amount memory of storage available.
Since the reset vector has to be contained in this early code memory,
the bootblock is the best place to implement loading of other stages.
This patch only adds the infrastructure to intercept the boot flow of
the bootblock before jumping to ROMCC segments, after which the
execution is passed to platform-specific code.
Change-Id: Icbf5804b66b9517f9ceb352bed86978dcf92228f
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Kconfig | 7 ++++++
src/arch/x86/Makefile.inc | 16 +++++++++---
src/arch/x86/bootblock.S | 40 -----------------------------
src/arch/x86/bootblock_crt0.S | 56 +++++++++++++++++++++++++++++++++++++++++
src/arch/x86/bootblock_legacy.S | 53 ++++++++++++++++++++++++++++++++++++++
5 files changed, 128 insertions(+), 44 deletions(-)
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 738e7d1..28ec524 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -58,6 +58,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 9713d52..f372645 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -68,16 +68,15 @@ else
LDFLAGS_bootblock += -m elf_x86_64 --oformat elf64-x86-64
endif
+bootblock-y += memcpy.c
+bootblock-y += mmap_boot.c
+
# Add the assembly file that pulls in the rest of the dependencies in
# 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
$(obj)/arch/x86/id.bootblock.o: $(obj)/build.h
-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
@@ -95,11 +94,20 @@ $(objgenerated)/bootblock.ld: $$(filter-out $(obj)/arch/x86/bootblock.bootblock.
cat $^ >> $@.tmp
mv $@.tmp $@
+ifeq ($(CONFIG_C_ENVIRONMENT_BOOTBLOCK),y)
+bootblock-y += bootblock_crt0.S
+else
+bootblock-y += bootblock_legacy.S
+bootblock-y += walkcbfs.S
+
+$(obj)/arch/x86/bootblock_legacy.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 27a23eb..0000000
--- a/src/arch/x86/bootblock.S
+++ /dev/null
@@ -1,40 +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.
- */
-
-/* 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_crt0.S b/src/arch/x86/bootblock_crt0.S
new file mode 100644
index 0000000..a9023b9
--- /dev/null
+++ b/src/arch/x86/bootblock_crt0.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(a)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
+
+bootblock_protected_mode_entry:
+ /* 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_legacy.S b/src/arch/x86/bootblock_legacy.S
new file mode 100644
index 0000000..6c1723a
--- /dev/null
+++ b/src/arch/x86/bootblock_legacy.S
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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
+ * - entry32.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 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>
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/11858
-gerrit
commit e0306b141ddd024b592f176f28c970fbe7f28b12
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sat Oct 10 16:35:58 2015 -0700
cpu/qemu-x86: Run a C environment in the bootblock
Make use of the ROMCC-less bootblock introduced earlier. The "qemu"
cpu is particularly easy because it does not require CAR setup.
Change-Id: Idf161d363d2daf3c55454d376ca42d492463971a
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/cpu/qemu-x86/Kconfig | 2 +-
src/cpu/qemu-x86/Makefile.inc | 2 ++
src/cpu/qemu-x86/bootblock.c | 62 ++++++++++++++++++++++++++++++++++++++++
src/cpu/qemu-x86/bootblock_asm.S | 48 +++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+), 1 deletion(-)
diff --git a/src/cpu/qemu-x86/Kconfig b/src/cpu/qemu-x86/Kconfig
index ea2bc46..f956de5 100644
--- a/src/cpu/qemu-x86/Kconfig
+++ b/src/cpu/qemu-x86/Kconfig
@@ -19,4 +19,4 @@ config CPU_QEMU_X86
select ARCH_VERSTAGE_X86_32
select ARCH_ROMSTAGE_X86_32
select ARCH_RAMSTAGE_X86_32
- select SMP
+ select C_ENVIRONMENT_BOOTBLOCK
diff --git a/src/cpu/qemu-x86/Makefile.inc b/src/cpu/qemu-x86/Makefile.inc
index b5f8369..0ed76f9 100644
--- a/src/cpu/qemu-x86/Makefile.inc
+++ b/src/cpu/qemu-x86/Makefile.inc
@@ -12,6 +12,8 @@
## GNU General Public License for more details.
##
+bootblock-y += bootblock_asm.S
+bootblock-y += bootblock.c
ramstage-y += qemu.c
subdirs-y += ../x86/mtrr
subdirs-y += ../x86/lapic
diff --git a/src/cpu/qemu-x86/bootblock.c b/src/cpu/qemu-x86/bootblock.c
new file mode 100644
index 0000000..bfbac7a
--- /dev/null
+++ b/src/cpu/qemu-x86/bootblock.c
@@ -0,0 +1,62 @@
+/*
+ * 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(a)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.
+ */
+
+#include <arch/cpu.h>
+#include <cbfs.h>
+#include <halt.h>
+
+/* Called from assembly. Prototype not needed by external .c file */
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi);
+
+/*
+ * TODO: Implement a generic fallback/normal mechanism
+ */
+static const char *get_next_stage_name(void)
+{
+ if (IS_ENABLED(CONFIG_BOOTBLOCK_SIMPLE))
+ return CONFIG_CBFS_PREFIX "/romstage";
+
+ /* BOOTBLOCK_NORMAL not implemented */
+ return CONFIG_CBFS_PREFIX "/romstage";
+}
+
+static void enter_romstage(void *romstage_entry, uint32_t bist)
+{
+ asm volatile (
+ "jmp *%0\n\t"
+ : : "r" (romstage_entry), "a" (bist)
+ );
+}
+
+asmlinkage void bootblock_main(uint32_t bist, uint32_t tsc_lo, uint32_t tsc_hi)
+{
+ void *entry;
+ struct cbfs_stage *romstage;
+ const char* target1 = get_next_stage_name();
+
+ romstage = cbfs_boot_map_with_leak(target1, CBFS_TYPE_STAGE, NULL);
+
+ /*
+ * TODO: Do something constructive with tsc_lo and tsc_hi
+ */
+ if (romstage) {
+ entry = (void *)(uintptr_t)romstage->entry;
+ enter_romstage(entry, bist);
+ }
+ halt();
+}
diff --git a/src/cpu/qemu-x86/bootblock_asm.S b/src/cpu/qemu-x86/bootblock_asm.S
new file mode 100644
index 0000000..6e1cd2e
--- /dev/null
+++ b/src/cpu/qemu-x86/bootblock_asm.S
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me(a)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.
+ */
+
+#include <console/post_codes.h>
+
+#define STACK_SIZE 0x10000
+#define STACK_BASE 0xd0000
+
+.intel_syntax noprefix
+
+#define post_code(code) \
+ mov eax, code; \
+ out 0x80, eax
+
+.global bootblock_pre_c_entry
+
+.section .text
+bootblock_pre_c_entry:
+
+ /* Set up a stack */
+ mov esp, (STACK_BASE + STACK_SIZE - 4)
+
+ /*
+ * We have the following values saved from earlier:
+ * mm0: BIST result
+ * mm1: TSC timestamp low 32 bits
+ * mm2: TSC timestamp high 32 bits
+ */
+ movd eax, mm2
+ push eax
+ movd eax, mm1
+ push eax
+ movd eax, mm0
+ push eax
+ call bootblock_main
+
+.halt_forever:
+ post_code(POST_DEAD_CODE)
+ hlt
+ jmp .halt_forever
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/11784
-gerrit
commit c35a2b2dae8a5309e40f4867f5230d582acd9fe5
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 12:42:26 2015 -0700
arch/x86: Allow boot flow which runs CAR setup in bootblock
Some newer x86 systems can boot from non-memory-mapped boot media
(e.g. EMMC). The bootblock may be backed by small amounts of SRAM, or
other memory, similar to how most ARM chipsets work. In such cases, we
may not have enough code space for romstage very early on. This means
that CAR setup and early boot media (e.g. SPI, EMMC) drivers need to
be implemented within the limited amount memory of storage available.
Since the reset vector has to be contained in this early code memory,
the bootblock is the best place to implement loading of other stages.
This patch only adds the infrastructure to intercept the boot flow of
the bootblock before jumping to ROMCC segments, after which the
execution is passed to platform-specific code.
Change-Id: Icbf5804b66b9517f9ceb352bed86978dcf92228f
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Kconfig | 7 ++++++
src/arch/x86/Makefile.inc | 16 +++++++++---
src/arch/x86/bootblock.S | 40 -----------------------------
src/arch/x86/bootblock_legacy.S | 53 ++++++++++++++++++++++++++++++++++++++
src/arch/x86/bootblock_modern.S | 56 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 128 insertions(+), 44 deletions(-)
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 738e7d1..28ec524 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -58,6 +58,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 9713d52..4f2b0d4 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -68,16 +68,15 @@ else
LDFLAGS_bootblock += -m elf_x86_64 --oformat elf64-x86-64
endif
+bootblock-y += memcpy.c
+bootblock-y += mmap_boot.c
+
# Add the assembly file that pulls in the rest of the dependencies in
# 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
$(obj)/arch/x86/id.bootblock.o: $(obj)/build.h
-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
@@ -95,11 +94,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
+else
+bootblock-y += bootblock_legacy.S
+bootblock-y += walkcbfs.S
+
+$(obj)/arch/x86/bootblock_legacy.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 27a23eb..0000000
--- a/src/arch/x86/bootblock.S
+++ /dev/null
@@ -1,40 +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.
- */
-
-/* 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..9cd7eaf
--- /dev/null
+++ b/src/arch/x86/bootblock_legacy.S
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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 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_modern.S b/src/arch/x86/bootblock_modern.S
new file mode 100644
index 0000000..a9023b9
--- /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(a)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
+
+bootblock_protected_mode_entry:
+ /* 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