Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11794
-gerrit
commit 7b83975e0fa510eb78dc3392603b374c62acfedf
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sun Oct 4 18:30:59 2015 -0700
WIP: x86/bootblock: Code reset entry and protected mode switch in NASM
Now that we can use NASM, demonstrate its power by coding the reset
vector entry and switch to protected mode in NASM, and removing the
old implementation with GNU as.
Note that src/cpu/x86/32bit/entry32.inc is kept for now, as it is
needed by romstage. However, at this point, this patch series is
concerned with the bootblock. Other stages will be updated later in
the series.
Change-Id: Iaeb63d015950cc9df265d00805735d3f8d18735e
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/bootblock.S | 6 +-
src/arch/x86/bootblock.ld | 3 +-
src/cpu/x86/16bit/entry16.inc | 140 --------------------------------
src/cpu/x86/16bit/entry16.ld | 2 -
src/cpu/x86/16bit/reset16.inc | 16 ----
src/cpu/x86/16bit/reset16.ld | 16 ----
src/cpu/x86/Makefile.inc | 2 +
src/cpu/x86/reset_entry/reset16.ld | 16 ++++
src/cpu/x86/reset_entry/reset_entry.asm | 81 ++++++++++++++++++
9 files changed, 103 insertions(+), 179 deletions(-)
diff --git a/src/arch/x86/bootblock.S b/src/arch/x86/bootblock.S
index 645e491..d575aa4 100644
--- a/src/arch/x86/bootblock.S
+++ b/src/arch/x86/bootblock.S
@@ -22,9 +22,9 @@
* 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>
+
+.global legacy_bootblock_entry
+legacy_bootblock_entry:
#ifdef CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
#include CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
diff --git a/src/arch/x86/bootblock.ld b/src/arch/x86/bootblock.ld
index 6835430..8499b4d 100644
--- a/src/arch/x86/bootblock.ld
+++ b/src/arch/x86/bootblock.ld
@@ -18,8 +18,7 @@
*/
#include <arch/x86/failover.ld>
-#include <cpu/x86/16bit/entry16.ld>
-#include <cpu/x86/16bit/reset16.ld>
+#include <cpu/x86/reset_entry/reset16.ld>
#include <arch/x86/id.ld>
#if IS_ENABLED(CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE)
#include <cpu/intel/fit/fit.ld>
diff --git a/src/cpu/x86/16bit/entry16.inc b/src/cpu/x86/16bit/entry16.inc
deleted file mode 100644
index 4dad1e5..0000000
--- a/src/cpu/x86/16bit/entry16.inc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * This software and ancillary information (herein called SOFTWARE)
- * called LinuxBIOS is made available under the terms described here.
- *
- * The SOFTWARE has been approved for release with associated
- * LA-CC Number 00-34. Unless otherwise indicated, this SOFTWARE has
- * been authored by an employee or employees of the University of
- * California, operator of the Los Alamos National Laboratory under
- * Contract No. W-7405-ENG-36 with the U.S. Department of Energy.
- *
- * The U.S. Government has rights to use, reproduce, and distribute this
- * SOFTWARE. The public may copy, distribute, prepare derivative works
- * and publicly display this SOFTWARE without charge, provided that this
- * Notice and any statement of authorship are reproduced on all copies.
- *
- * Neither the Government nor the University makes any warranty, express
- * or implied, or assumes any liability or responsibility for the use of
- * this SOFTWARE. If SOFTWARE is modified to produce derivative works,
- * such modified SOFTWARE should be clearly marked, so as not to confuse
- * it with the version available from LANL.
- *
- * Copyright (C) 2000, Ron Minnich rminnich(a)lanl.gov
- * Advanced Computing Lab, LANL
- */
-
-
-/* Start code to put an i386 or later processor into 32-bit protected mode.
- */
-
-#include <arch/rom_segs.h>
-.code16
-.globl _start
-.type _start, @function
-
-_start:
- cli
- /* Save the BIST result */
- movl %eax, %ebp
-
- post_code(POST_RESET_VECTOR_CORRECT)
-
- /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before
- * executing any further code. Even though paging is disabled we
- * could still get false address translations due to the TLB if we
- * didn't invalidate it. Thanks to kmliu(a)sis.com.tw for this TLB fix.
- */
-
- xorl %eax, %eax
- movl %eax, %cr3 /* Invalidate TLB*/
-
- /* Invalidating the cache here seems to be a bad idea on
- * modern processors. Don't.
- * If we are hyperthreaded or we have multiple cores it is bad,
- * for SMP startup. On Opterons it causes a 5 second delay.
- * Invalidating the cache was pure paranoia in any event.
- * If you cpu needs it you can write a cpu dependent version of
- * entry16.inc.
- */
-
- /* Note: gas handles memory addresses in 16 bit code very poorly.
- * In particular it doesn't appear to have a directive allowing you
- * associate a section or even an absolute offset with a segment register.
- *
- * This means that anything except cs:ip relative offsets are
- * a real pain in 16 bit mode. And explains why it is almost
- * impossible to get gas to do lgdt correctly.
- *
- * One way to work around this is to have the linker do the
- * math instead of the assembler. This solves the very
- * pratical problem of being able to write code that can
- * be relocated.
- *
- * An lgdt call before we have memory enabled cannot be
- * position independent, as we cannot execute a call
- * instruction to get our current instruction pointer.
- * So while this code is relocateable it isn't arbitrarily
- * relocatable.
- *
- * The criteria for relocation have been relaxed to their
- * utmost, so that we can use the same code for both
- * our initial entry point and startup of the second cpu.
- * The code assumes when executing at _start that:
- * (((cs & 0xfff) == 0) and (ip == _start & 0xffff))
- * or
- * ((cs == anything) and (ip == 0)).
- *
- * The restrictions in reset16.inc mean that _start initially
- * must be loaded at or above 0xffff0000 or below 0x100000.
- *
- * The linker scripts computes gdtptr16_offset by simply returning
- * the low 16 bits. This means that the intial segment used
- * when start is called must be 64K aligned. This should not
- * restrict the address as the ip address can be anything.
- *
- * Also load an IDT with NULL limit to prevent the 16bit IDT being used
- * in protected mode before c_start.S sets up a 32bit IDT when entering
- * ram stage. In practise: CPU will shutdown on any exception.
- * See IA32 manual Vol 3A 19.26 Interrupts.
- */
-
- movw %cs, %ax
- shlw $4, %ax
- movw $nullidt_offset, %bx
- subw %ax, %bx
- lidt %cs:(%bx)
- movw $gdtptr16_offset, %bx
- subw %ax, %bx
- lgdtl %cs:(%bx)
-
- movl %cr0, %eax
- andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
- orl $0x60000001, %eax /* CD, NW, PE = 1 */
- movl %eax, %cr0
-
- /* Restore BIST to %eax */
- movl %ebp, %eax
-
- /* Now that we are in protected mode jump to a 32 bit code segment. */
- ljmpl $ROM_CODE_SEG, $__protected_start
-
- /**
- * The gdt is defined in entry32.inc, it has a 4 Gb code segment
- * at 0x08, and a 4 GB data segment at 0x10;
- */
-.align 4
-.globl gdtptr16
-gdtptr16:
- .word gdt_end - gdt -1 /* compute the table limit */
- .long gdt /* we know the offset */
-
-.align 4
-.globl nullidt
-nullidt:
- .word 0 /* limit */
- .long 0
- .word 0
-
-.globl _estart
-_estart:
- .code32
diff --git a/src/cpu/x86/16bit/entry16.ld b/src/cpu/x86/16bit/entry16.ld
deleted file mode 100644
index 112d429..0000000
--- a/src/cpu/x86/16bit/entry16.ld
+++ /dev/null
@@ -1,2 +0,0 @@
- gdtptr16_offset = gdtptr16 & 0xffff;
- nullidt_offset = nullidt & 0xffff;
diff --git a/src/cpu/x86/16bit/reset16.inc b/src/cpu/x86/16bit/reset16.inc
deleted file mode 100644
index 33712d1..0000000
--- a/src/cpu/x86/16bit/reset16.inc
+++ /dev/null
@@ -1,16 +0,0 @@
- .section ".reset"
- .code16
-.globl reset_vector
-reset_vector:
- .byte 0xe9
- .int _start - ( . + 2 )
- /* Note: The above jump is hand coded to work around bugs in binutils.
- * 5 byte are used for a 3 byte instruction. This works because x86
- * is little endian and allows us to use supported 32bit relocations
- * instead of the weird 16 bit relocations that binutils does not
- * handle consistenly between versions because they are used so rarely.
- */
- .org 0x8;
- .code32
- jmp protected_start
- .previous
diff --git a/src/cpu/x86/16bit/reset16.ld b/src/cpu/x86/16bit/reset16.ld
deleted file mode 100644
index d0c4096..0000000
--- a/src/cpu/x86/16bit/reset16.ld
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * _ROMTOP : The top of the rom used where we
- * need to put the reset vector.
- */
-
-SECTIONS {
- /* Trigger an error if I have an unuseable start address */
- _bogus = ASSERT(_start >= 0xffff0000, "_start too low. Please report.");
- _ROMTOP = 0xfffffff0;
- . = _ROMTOP;
- .reset . : {
- KEEP(*(.reset));
- . = 15 ;
- BYTE(0x00);
- }
-}
diff --git a/src/cpu/x86/Makefile.inc b/src/cpu/x86/Makefile.inc
index e9394b2..e046607 100644
--- a/src/cpu/x86/Makefile.inc
+++ b/src/cpu/x86/Makefile.inc
@@ -2,6 +2,8 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)
romstage-$(CONFIG_CACHE_AS_RAM) += car.c
endif
+bootblock-y += reset_entry/reset_entry.asm
+
subdirs-$(CONFIG_PARALLEL_MP) += name
ramstage-$(CONFIG_PARALLEL_MP) += mp_init.c
ramstage-$(CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING) += mirror_payload.c
diff --git a/src/cpu/x86/reset_entry/reset16.ld b/src/cpu/x86/reset_entry/reset16.ld
new file mode 100644
index 0000000..d0c4096
--- /dev/null
+++ b/src/cpu/x86/reset_entry/reset16.ld
@@ -0,0 +1,16 @@
+/*
+ * _ROMTOP : The top of the rom used where we
+ * need to put the reset vector.
+ */
+
+SECTIONS {
+ /* Trigger an error if I have an unuseable start address */
+ _bogus = ASSERT(_start >= 0xffff0000, "_start too low. Please report.");
+ _ROMTOP = 0xfffffff0;
+ . = _ROMTOP;
+ .reset . : {
+ KEEP(*(.reset));
+ . = 15 ;
+ BYTE(0x00);
+ }
+}
diff --git a/src/cpu/x86/reset_entry/reset_entry.asm b/src/cpu/x86/reset_entry/reset_entry.asm
new file mode 100644
index 0000000..2878ef6
--- /dev/null
+++ b/src/cpu/x86/reset_entry/reset_entry.asm
@@ -0,0 +1,81 @@
+;
+; The x86 journey, from embryo reset vector, to adult protected mode
+;
+; Copyright (C) 2015 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
+; Subject to the GNU GPL v2, or (at your option) any later version.
+;
+
+global _start
+extern legacy_bootblock_entry
+
+ROM_CODE_SEG EQU 0x08
+ROM_DATA_SEG EQU 0x10
+POST_RESET_VECTOR_CORRECT EQU 0x01
+
+%define post_code(code) \
+ mov eax, code
+ out 0x80, eax
+
+section .reset
+
+reset_vector: bits 16
+ jmp _start
+
+
+section .text
+
+_start: bits 16
+ ;
+ ; eax has BIST result, so try not to touch it
+ ;
+ mov esp, eax;
+
+ post_code(POST_RESET_VECTOR_CORRECT)
+
+ cli
+
+ lidt [cs:idt]
+ o32 lgdt [cs:gdtr] ; for some reason, this needs a 32-bit operand size
+
+ mov ecx, cr0
+ and ecx, 0x7FFAFFD1 ; original bootblock did this
+ or ecx, 0x60000001 ; and this
+ mov cr0, ecx
+
+ ; long jump to protected mode
+ jmp long ROM_CODE_SEG: protected_mode_start
+
+protected_mode_start: bits 32
+ ;
+ ; eax still has BIST result. Don't touch it
+ ;
+ mov cx, ROM_DATA_SEG
+ mov ds, cx
+ mov es, cx
+ mov ss, cx
+ mov fs, cx
+ mov gs, cx
+ mov eax, esp
+ jmp legacy_bootblock_entry
+
+align 4
+gdtr:
+ dw gdt_size - 1
+ dd gdt
+
+align 4
+gdt:
+ ; segment 0x00: unused
+ dw 0x0000, 0x0000
+ db 0x00, 0x00, 0x00, 0x00
+ ; segment 0x08: ROM_CODE_SEG
+ dw 0xffff, 0x0000
+ db 0x00, 0x9b, 0xcf, 0x00
+ ; segment 0x10: ROM_DATA_SEG
+ dw 0xffff, 0x0000
+ db 0x00, 0x93, 0xcf, 0x00
+gdt_size EQU $ - gdt ; GNU as can't do this
+
+align 4
+idt:
+ dd 0x00000000, 0x00000000
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11793
-gerrit
commit b262953b325f40ec41a7ffbfe0e2e1210d40772a
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 21:32:42 2015 -0700
arch/x86: Allow using NASM as an optional assembler
Some people, such as Aaron and myself find GNU as and its ATT syntax
to be hard to use and error-prone. Aaron knows of a few companies who
produce coreboot code (or blobs), which are also migrating to NASM. It
makes sense, from this point, to standardize on an assembler.
This patch does create the somewhat sub-optimal situation where both
NASM and GNU as can be used to create objects linked in a binary. The
long term plan is to standardize on NASM, and replace the ROMCC parts
of the bootblock with NASM assembly.
Also, NASM does not use the C preprocessor. While it is possible to
run NASM files through the C preprocessor, and allow tricks such as
Change-Id: I6ec7db2d5893bb0b9943940c4f767a45ec32dc09
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Makefile.inc | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index e17fe11..f41255e 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -113,13 +113,27 @@ $(objgenerated)/bootblock.inc: $(src)/arch/x86/$(subst ",,$(CONFIG_BOOTBLOCK_SOU
$(ROMCC) -c -S $(bootblock_romccflags) -I. $(CPPFLAGS_bootblock) $< -o $@
# $(obj)/arch/x86/bootblock.bootblock.ld is part of $(bootblock-objs)
-$(objcbfs)/bootblock.debug: $$(bootblock-objs)
+$(objcbfs)/bootblock.debug: $$(filter %.o,$$(bootblock-objs)) $$(filter %.ld,$$(bootblock-objs)) $$(nasm-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
$(LD_bootblock) $(LDFLAGS_common) $(LDFLAGS_x86) -static \
-o $@ -L$(obj) \
- $(filter %.o,$(bootblock-objs)) \
+ $(filter %.o,$(bootblock-objs)) $(nasm-objs) \
-T $(obj)/arch/x86/bootblock.bootblock.ld \
+#
+# Rules for turning NASM %. asm files into linkable %.o files
+#
+# Note that assembly files with the %.asm extension, are not automatically
+# converted to a %.o in $(bootblock-objs). If we tried to do that, the generic
+# rules would try to call the GNU compiler driver on the %.asm files. We do not
+# want that, as GCC does not know how to handle them. Instead, we do this here,
+# which allows us to maintain the logical separation.
+#
+nasm-objs = $(patsubst %.asm,%.o,$(filter %.asm,$(bootblock-objs)))
+
+$(obj)/%.bootblock.o: $(src)/%.asm $(obj)/config.h
+ @printf " NASM $(subst $(obj)/,,$(@))\n"
+ nasm -felf -o $@ $<
endif # CONFIG_ARCH_BOOTBLOCK_X86_32 / CONFIG_ARCH_BOOTBLOCK_X86_64
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11792
-gerrit
commit 8df4298bb93bd4a5f68aa1f2c6ac5c8ff405c237
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sun Oct 4 17:47:36 2015 -0700
arch/x86/bootblock: Do not include non-code files in bootblock.S
Since we can now link the bootblock, it no longer makes sense to use a
monolithic bootblock.S. Code segments must still be included as the
order in bootblock.S determines code flow. However, we can now link
data or descriptor parts, such as id.inc, or fit.inc.
Change-Id: I08e86e92d82bd2138194ed42652f268b0764aa54
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Makefile.inc | 1 +
src/arch/x86/bootblock.S | 5 -----
src/arch/x86/id.S | 20 ++++++++++++++++++++
src/arch/x86/id.inc | 20 --------------------
src/cpu/intel/Makefile.inc | 1 +
src/cpu/intel/fit/Makefile.inc | 1 +
src/cpu/intel/fit/fit.S | 30 ++++++++++++++++++++++++++++++
src/cpu/intel/fit/fit.inc | 30 ------------------------------
8 files changed, 53 insertions(+), 55 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 95ebb6a..e17fe11 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -84,6 +84,7 @@ endif
# 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
bootblock-y += bootblock.S
bootblock-y += walkcbfs.S
$(obj)/arch/x86/bootblock.bootblock.o: $(objgenerated)/bootblock.inc
diff --git a/src/arch/x86/bootblock.S b/src/arch/x86/bootblock.S
index bea178d..645e491 100644
--- a/src/arch/x86/bootblock.S
+++ b/src/arch/x86/bootblock.S
@@ -25,11 +25,6 @@
#include <cpu/x86/16bit/entry16.inc>
#include <cpu/x86/16bit/reset16.inc>
#include <cpu/x86/32bit/entry32.inc>
-#include <arch/x86/id.inc>
-
-#if IS_ENABLED(CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE)
-#include <cpu/intel/fit/fit.inc>
-#endif
#ifdef CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
#include CONFIG_CHIPSET_BOOTBLOCK_INCLUDE
diff --git a/src/arch/x86/id.S b/src/arch/x86/id.S
new file mode 100644
index 0000000..a3df25e
--- /dev/null
+++ b/src/arch/x86/id.S
@@ -0,0 +1,20 @@
+#include <build.h>
+
+ .section ".id", "a", @progbits
+
+ .globl __id_start
+__id_start:
+ver:
+ .asciz COREBOOT_VERSION
+vendor:
+ .asciz CONFIG_MAINBOARD_VENDOR
+part:
+ .asciz CONFIG_MAINBOARD_PART_NUMBER
+.long __id_end + CONFIG_ID_SECTION_OFFSET - ver /* Reverse offset to the vendor id */
+.long __id_end + CONFIG_ID_SECTION_OFFSET - vendor /* Reverse offset to the vendor id */
+.long __id_end + CONFIG_ID_SECTION_OFFSET - part /* Reverse offset to the part number */
+.long CONFIG_ROM_SIZE /* Size of this romimage */
+ .globl __id_end
+
+__id_end:
+.previous
diff --git a/src/arch/x86/id.inc b/src/arch/x86/id.inc
deleted file mode 100644
index a3df25e..0000000
--- a/src/arch/x86/id.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <build.h>
-
- .section ".id", "a", @progbits
-
- .globl __id_start
-__id_start:
-ver:
- .asciz COREBOOT_VERSION
-vendor:
- .asciz CONFIG_MAINBOARD_VENDOR
-part:
- .asciz CONFIG_MAINBOARD_PART_NUMBER
-.long __id_end + CONFIG_ID_SECTION_OFFSET - ver /* Reverse offset to the vendor id */
-.long __id_end + CONFIG_ID_SECTION_OFFSET - vendor /* Reverse offset to the vendor id */
-.long __id_end + CONFIG_ID_SECTION_OFFSET - part /* Reverse offset to the part number */
-.long CONFIG_ROM_SIZE /* Size of this romimage */
- .globl __id_end
-
-__id_end:
-.previous
diff --git a/src/cpu/intel/Makefile.inc b/src/cpu/intel/Makefile.inc
index 6f07e30..904aa5d 100644
--- a/src/cpu/intel/Makefile.inc
+++ b/src/cpu/intel/Makefile.inc
@@ -3,6 +3,7 @@
#
# Therefore: ONLY include Makefile.inc from socket directories!
+subdirs-$(CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE) += fit
subdirs-$(CONFIG_CPU_INTEL_SOCKET_441) += socket_441
subdirs-$(CONFIG_CPU_INTEL_SOCKET_BGA956) += socket_BGA956
subdirs-$(CONFIG_CPU_INTEL_EP80579) += ep80579
diff --git a/src/cpu/intel/fit/Makefile.inc b/src/cpu/intel/fit/Makefile.inc
new file mode 100644
index 0000000..4b540ba
--- /dev/null
+++ b/src/cpu/intel/fit/Makefile.inc
@@ -0,0 +1 @@
+bootblock-y += fit.S
diff --git a/src/cpu/intel/fit/fit.S b/src/cpu/intel/fit/fit.S
new file mode 100644
index 0000000..e4595c0
--- /dev/null
+++ b/src/cpu/intel/fit/fit.S
@@ -0,0 +1,30 @@
+.section ".fit_pointer", "a", @progbits
+ .code32
+.global fit_pointer
+fit_pointer:
+.long fit_table
+.long 0
+.previous
+
+.section ".rom.data", "a", @progbits
+.align 16
+.global fit_table
+.global fit_table_end
+fit_table:
+/* Address for type 0 is '_FIT_ ' */
+.long 0x5449465f
+.long 0x2020205f
+/*
+ * There is 1 entry in the table. Other tools will have to update the size
+ * and checksum when adding entries.
+ */
+.long 0x00000001
+/* Version */
+.word 0x0100
+/* Type 0 with checksum valid. */
+.byte 0x80
+/* Checksum byte - must add to zero. */
+.byte 0x7d
+.fill CONFIG_CPU_INTEL_NUM_FIT_ENTRIES*16
+fit_table_end:
+.previous
diff --git a/src/cpu/intel/fit/fit.inc b/src/cpu/intel/fit/fit.inc
deleted file mode 100644
index e4595c0..0000000
--- a/src/cpu/intel/fit/fit.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-.section ".fit_pointer", "a", @progbits
- .code32
-.global fit_pointer
-fit_pointer:
-.long fit_table
-.long 0
-.previous
-
-.section ".rom.data", "a", @progbits
-.align 16
-.global fit_table
-.global fit_table_end
-fit_table:
-/* Address for type 0 is '_FIT_ ' */
-.long 0x5449465f
-.long 0x2020205f
-/*
- * There is 1 entry in the table. Other tools will have to update the size
- * and checksum when adding entries.
- */
-.long 0x00000001
-/* Version */
-.word 0x0100
-/* Type 0 with checksum valid. */
-.byte 0x80
-/* Checksum byte - must add to zero. */
-.byte 0x7d
-.fill CONFIG_CPU_INTEL_NUM_FIT_ENTRIES*16
-fit_table_end:
-.previous
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11781
-gerrit
commit e2a1169177927734172f90cad32c2991f8e98680
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 10:59:13 2015 -0700
x86/bootblock: Use LDFLAGS_bootblock to enable garbage collection
The x86 bootblock linking is a mess. The bootblock is treated in
a very special manner, and never received the update to link-time
garbage collection.
On newer x86 platforms, the boot media is no longer memory-mapped.
That means we need to do a lot more setup in the bootblock. ROMCC is
unsuitable for this task, and walkcbfs only works on memory-mapped
CBFS. We need to revise the x86 bootflow for this new case.
The approach this patch series takes is to perform CAR setup in the
bootblock, and load the following stage (either romstage or verstage)
from the boot media. This approach is not new, but has been done on
our ARM ports for years.
Since we will be adding .c files to the bootblock, it is prudent to
use link-time garbage collection. This is also consistent to how we
do things on other architectures. Unification FTW!
Change-Id: I16b78456df56e0053984a9aca9367e2542adfdc9
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Makefile.inc | 4 ++--
src/arch/x86/id.ld | 2 +-
src/cpu/intel/fit/fit.ld | 2 +-
src/cpu/x86/16bit/reset16.ld | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index f16edcd..1bda5f6 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -106,9 +106,9 @@ $(objgenerated)/bootblock.inc: $(src)/arch/x86/$(subst ",,$(CONFIG_BOOTBLOCK_SOU
$(objcbfs)/bootblock.debug: $(obj)/arch/x86/bootblock.bootblock.o $(obj)/arch/x86/bootblock.bootblock.ld
@printf " LINK $(subst $(obj)/,,$(@))\n"
ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32),y)
- $(LD_bootblock) -m elf_i386 --oformat elf32-i386 -static -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
+ $(LD_bootblock) $(LDFLAGS_common) -m elf_i386 --oformat elf32-i386 -static -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
else
- $(LD_bootblock) -m elf_x86_64 --oformat elf64-x86-64 -static -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
+ $(LD_bootblock) $(LDFLAGS_common) -m elf_x86_64 --oformat elf64-x86-64 -static -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
endif
diff --git a/src/arch/x86/id.ld b/src/arch/x86/id.ld
index cfd091d..99d13f1 100644
--- a/src/arch/x86/id.ld
+++ b/src/arch/x86/id.ld
@@ -1,6 +1,6 @@
SECTIONS {
. = (0xffffffff - CONFIG_ID_SECTION_OFFSET) - (__id_end - __id_start) + 1;
.id (.): {
- *(.id)
+ KEEP(*(.id))
}
}
diff --git a/src/cpu/intel/fit/fit.ld b/src/cpu/intel/fit/fit.ld
index 9ccfe82..5817e1d 100644
--- a/src/cpu/intel/fit/fit.ld
+++ b/src/cpu/intel/fit/fit.ld
@@ -1,6 +1,6 @@
SECTIONS {
. = 0xffffffc0;
.fit_pointer (.): {
- *(.fit_pointer)
+ KEEP(*(.fit_pointer))
}
}
diff --git a/src/cpu/x86/16bit/reset16.ld b/src/cpu/x86/16bit/reset16.ld
index a31a580..d0c4096 100644
--- a/src/cpu/x86/16bit/reset16.ld
+++ b/src/cpu/x86/16bit/reset16.ld
@@ -9,7 +9,7 @@ SECTIONS {
_ROMTOP = 0xfffffff0;
. = _ROMTOP;
.reset . : {
- *(.reset)
+ KEEP(*(.reset));
. = 15 ;
BYTE(0x00);
}
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11783
-gerrit
commit 57475142923328f30774a0ee3679ec674716eb36
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 12:17:56 2015 -0700
arch/x86/bootblock: Link in object files selected with bootblock-y
As part of preparing for systems with non-memory-mapped media, we want
to be able to call into C code. This change allows us to link C code
directly into the bootblock. The steps of going from bootblock main()
to CAR setup to C code will be implemented in subsequent patches.
Note that a few files selected with bootblock-y will now be compiled
for the bootblock as well, but since we enabled garbage collection,
they will not be included in the final binary.
Change-Id: I5ca6dcaf176f5469c6a3bb925859399123493bc6
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Makefile.inc | 7 +++++--
src/arch/x86/failover.ld | 3 +++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index fba07c7..7c07de2 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -110,10 +110,13 @@ $(objgenerated)/bootblock.inc: $(src)/arch/x86/$(subst ",,$(CONFIG_BOOTBLOCK_SOU
$< > $(objgenerated)/bootblock.inc.d
$(ROMCC) -c -S $(bootblock_romccflags) -I. $(CPPFLAGS_bootblock) $< -o $@
-$(objcbfs)/bootblock.debug: $(obj)/arch/x86/bootblock.bootblock.o $(obj)/arch/x86/bootblock.bootblock.ld
+# $(obj)/arch/x86/bootblock.bootblock.ld is part of $(bootblock-objs)
+$(objcbfs)/bootblock.debug: $$(bootblock-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
$(LD_bootblock) $(LDFLAGS_common) $(LDFLAGS_x86) -static \
- -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
+ -o $@ -L$(obj) \
+ $(filter %.o,$(bootblock-objs)) \
+ -T $(obj)/arch/x86/bootblock.bootblock.ld \
endif # CONFIG_ARCH_BOOTBLOCK_X86_32 / CONFIG_ARCH_BOOTBLOCK_X86_64
diff --git a/src/arch/x86/failover.ld b/src/arch/x86/failover.ld
index d7aa47e..89d5449 100644
--- a/src/arch/x86/failover.ld
+++ b/src/arch/x86/failover.ld
@@ -41,6 +41,8 @@ SECTIONS
*(.rom.text);
*(.rom.data);
*(.rom.data.*);
+ *(.text);
+ *(.text.*);
*(.rodata.*);
_erom = .;
} >rom = 0xff
@@ -63,6 +65,7 @@ SECTIONS
*(.note)
*(.comment.*)
*(.note.*)
+ *(.eh_frame)
*(.iplt)
*(.rel.*)
*(.igot.*)
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11782
-gerrit
commit 23e4f5bc35f683b77b1fe49727afc1165f515f7f
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 12:24:00 2015 -0700
arch/x86/Makefile.inc: Simplify rule for bootblock.debug
The only difference between the ifeq/else/endif guarded rules is the
linker flags specific to x86. Set those flags elsewhere, in a
variable, and only use one rule for bootblock.debug.
Change-Id: I986a93e0418f05fb273512d7efe0573052493332
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Makefile.inc | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 1bda5f6..fba07c7 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -74,6 +74,13 @@ CBFS_BASE_ADDRESS=$(call int-add, $(call int-subtract, 0xffffffff $(CONFIG_CBFS_
ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32)$(CONFIG_ARCH_BOOTBLOCK_X86_64),y)
+# x86-specific linker flags
+ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32),y)
+LDFLAGS_x86 := -m elf_i386 --oformat elf32-i386
+else
+LDFLAGS_x86 := -m elf_x86_64 --oformat elf64-x86-64
+endif
+
# 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.
@@ -105,11 +112,8 @@ $(objgenerated)/bootblock.inc: $(src)/arch/x86/$(subst ",,$(CONFIG_BOOTBLOCK_SOU
$(objcbfs)/bootblock.debug: $(obj)/arch/x86/bootblock.bootblock.o $(obj)/arch/x86/bootblock.bootblock.ld
@printf " LINK $(subst $(obj)/,,$(@))\n"
-ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32),y)
- $(LD_bootblock) $(LDFLAGS_common) -m elf_i386 --oformat elf32-i386 -static -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
-else
- $(LD_bootblock) $(LDFLAGS_common) -m elf_x86_64 --oformat elf64-x86-64 -static -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
-endif
+ $(LD_bootblock) $(LDFLAGS_common) $(LDFLAGS_x86) -static \
+ -o $@ -L$(obj) $< -T $(obj)/arch/x86/bootblock.bootblock.ld
endif # CONFIG_ARCH_BOOTBLOCK_X86_32 / CONFIG_ARCH_BOOTBLOCK_X86_64
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11785
-gerrit
commit bc563e2a34e90bdfc82a3726b9efde55624327df
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Fri Oct 2 16:17:41 2015 -0700
arch/x86: Link walkcbfs.S instead on including it in bootblock.S
The code flow doesn't fall through to walkcbfs, as it does in the rest
of bootblock.S. Instead, walkcbfs is called (albeit via a jmp). The
linker cannot know this when walkcbfs.S is included directly.
When we use a CAR bootblock, we lose several hundred bytes because
walkcbfs is not garbage-collected, yet it isn't used. This problem
is solved by assembling walkcbfs.S separately, and linking it.
Change-Id: Ib3a976db09b9ff270b7677cb4f9db80b0b025e22
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/arch/x86/Makefile.inc | 1 +
src/arch/x86/bootblock.S | 2 --
src/arch/x86/walkcbfs.S | 2 ++
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 7c07de2..95ebb6a 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -85,6 +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 += bootblock.S
+bootblock-y += walkcbfs.S
$(obj)/arch/x86/bootblock.bootblock.o: $(objgenerated)/bootblock.inc
bootblock-y += bootblock.ld
diff --git a/src/arch/x86/bootblock.S b/src/arch/x86/bootblock.S
index 7276c7a..bea178d 100644
--- a/src/arch/x86/bootblock.S
+++ b/src/arch/x86/bootblock.S
@@ -47,5 +47,3 @@
* needs to come after bootblock.inc.
*/
#include <generated/bootblock.inc>
-
-#include <arch/x86/walkcbfs.S>
diff --git a/src/arch/x86/walkcbfs.S b/src/arch/x86/walkcbfs.S
index 9c26d3c..0b91f57 100644
--- a/src/arch/x86/walkcbfs.S
+++ b/src/arch/x86/walkcbfs.S
@@ -18,6 +18,8 @@
#define CBFS_FILE_STRUCTSIZE (CBFS_FILE_OFFSET + 4)
+.global walkcbfs_asm
+
/*
* input %esi: filename
* input %esp: return address (not pointer to return address!)
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11784
-gerrit
commit 180303ac40c16c9b6205b8afca5083e1f46aae30
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
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(a)gmail.com>
---
src/arch/x86/Kconfig | 6 ++++++
src/arch/x86/bootblock_simple.c | 27 ++++++++++++++++++++++-----
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 88b2592..59eeb87 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -56,6 +56,12 @@ config ARCH_RAMSTAGE_X86_64
bool
default n
+# This is a new bootflow, in which CAR setup is performed in the bootblock, then
+# calls into C code (in the bootblock)
+config CAR_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/bootblock_simple.c b/src/arch/x86/bootblock_simple.c
index adeecf7..1c8eb02 100644
--- a/src/arch/x86/bootblock_simple.c
+++ b/src/arch/x86/bootblock_simple.c
@@ -2,6 +2,24 @@
#include <bootblock_common.h>
#include <halt.h>
+static void advance_to_romstage(unsigned long bist)
+{
+ const char* target1 = "fallback/romstage";
+ unsigned long entry;
+ entry = findstage(target1);
+ if (entry) call(entry, bist);
+ halt();
+
+}
+
+static void advance_to_car_setup(unsigned long bist)
+{
+ __asm__ volatile(
+ "jmp bootblock_pre_car_entry"
+ :: "a" (bist)
+ );
+}
+
static void main(unsigned long bist)
{
if (boot_cpu()) {
@@ -15,9 +33,8 @@ static void main(unsigned long bist)
#endif
}
- const char* target1 = "fallback/romstage";
- unsigned long entry;
- entry = findstage(target1);
- if (entry) call(entry, bist);
- halt();
+ if (IS_ENABLED(CONFIG_CAR_BOOTBLOCK))
+ advance_to_car_setup(bist);
+ else
+ advance_to_romstage(bist);
}