WANG Siyuan (wangsiyuanbuaa(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11747
-gerrit
commit 25410f81116fef49c5ce790dd624617d61666f6b
Author: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Date: Tue Aug 18 06:28:02 2015 +0800
AMD Bettong DSDT table: Declare memory between TOM1 and 0xFED40000 for PCI MMIO
In current code, \_SB.PCI0 declare MMIO between TOM1 and 4GB.
This is not correct because higher MMIO space is reserved by \_SB rather than
\_SB.PCI0. For example:
[0xFEDC2000 - 0xFEDC5FFF] reserved for FCH I2C
[0xFEDC6000 - 0xFEDC8FFF] reserved for FCH UART
Change-Id: I922d8c6a8ff1433582c70f86d5636171394af283
Signed-off-by: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Signed-off-by: WANG Siyuan <SiYuan.Wang(a)amd.com>
---
src/southbridge/amd/pi/hudson/acpi/fch.asl | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/southbridge/amd/pi/hudson/acpi/fch.asl b/src/southbridge/amd/pi/hudson/acpi/fch.asl
index cee721f..6076cde 100644
--- a/src/southbridge/amd/pi/hudson/acpi/fch.asl
+++ b/src/southbridge/amd/pi/hudson/acpi/fch.asl
@@ -120,16 +120,12 @@ Method(_CRS, 0) {
CreateDWordField(CRES, ^MMIO._LEN, MM1L)
/*
- * Declare memory between TOM1 and 4GB as available
+ * Declare memory between TOM1 and 0xFED40000 as available
* for PCI MMIO.
- * Use ShiftLeft to avoid 64bit constant (for XP).
- * This will work even if the OS does 32bit arithmetic, as
- * 32bit (0x00000000 - TOM1) will wrap and give the same
- * result as 64bit (0x100000000 - TOM1).
+ * TODO: change the hardcoded value.
*/
Store(TOM1, MM1B)
- ShiftLeft(0x10000000, 4, Local0)
- Subtract(Local0, TOM1, Local0)
+ Subtract(0xFED40000, TOM1, Local0)
Store(Local0, MM1L)
Return(CRES) /* note to change the Name buffer */
WANG Siyuan (wangsiyuanbuaa(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11750
-gerrit
commit 2f0820b9b1feb9374a2d2d6134531da7ebd28d0b
Author: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Date: Wed Sep 30 04:51:28 2015 +0800
AMD Bettong: add FCH's GPIO, UART and I2C support
Merlin Falcon's FCH has GPIO, UART and I2C. All of them are controlled
by registers mapped at MMIO space.
This ASL code is used for Windows drivers.
TEST:
1. Boot Windows 8 or Windows 10.
2. Install AMD Catalyst driver.
3. AMD FPIO, UART and I2C can be found in device manager.
4. I2C passed Multi Interface Test Tool (MITT) test.
Change-Id: I7ffe3fe0046d9a078cc38176c29a8e334646a5a3
Signed-off-by: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Signed-off-by: WANG Siyuan <SiYuan.Wang(a)amd.com>
---
src/mainboard/amd/bettong/dsdt.asl | 1 +
src/southbridge/amd/pi/hudson/acpi/carrizo_fch.asl | 101 +++++++++++++++++++++
2 files changed, 102 insertions(+)
diff --git a/src/mainboard/amd/bettong/dsdt.asl b/src/mainboard/amd/bettong/dsdt.asl
index 5e0febb..12b04cd 100644
--- a/src/mainboard/amd/bettong/dsdt.asl
+++ b/src/mainboard/amd/bettong/dsdt.asl
@@ -72,6 +72,7 @@ DefinitionBlock (
/* Describe PCI INT[A-H] for the Southbridge */
#include <southbridge/amd/pi/hudson/acpi/pci_int.asl>
+ #include <southbridge/amd/pi/hudson/acpi/carrizo_fch.asl>
} /* End \_SB scope */
diff --git a/src/southbridge/amd/pi/hudson/acpi/carrizo_fch.asl b/src/southbridge/amd/pi/hudson/acpi/carrizo_fch.asl
new file mode 100644
index 0000000..5bfb366
--- /dev/null
+++ b/src/southbridge/amd/pi/hudson/acpi/carrizo_fch.asl
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, 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.
+ */
+
+Device(GPIO) {
+ Name (_HID, "AMD0030")
+ Name (_CID, "AMD0030")
+ Name(_UID, 0)
+
+ Method (_CRS, 0x0, NotSerialized) {
+ Name (RBUF, ResourceTemplate () {
+ //
+ // Interrupt resource. In this example, banks 0 & 1 share the same
+ // interrupt to the parent controller and similarly banks 2 & 3.
+ //
+ // N.B. The definition below is chosen for an arbitrary
+ // test platform. It needs to be changed to reflect the hardware
+ // configuration of the actual platform
+ //
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {7}
+
+ //
+ // Memory resource. The definition below is chosen for an arbitrary
+ // test platform. It needs to be changed to reflect the hardware
+ // configuration of the actual platform.
+ //
+ Memory32Fixed(ReadWrite, 0xFED81500, 0x300)
+ })
+
+ Return (RBUF)
+ }
+
+ Method (_STA, 0x0, NotSerialized) {
+ Return (0x0F)
+ }
+}
+
+Device(FUR0) {
+ Name(_HID,"AMD0020")
+ Name(_UID,0x0)
+ Name(_CRS, ResourceTemplate() {
+ IRQ(Edge, ActiveHigh, Exclusive) {10}
+ Memory32Fixed(ReadWrite, 0xFEDC6000, 0x2000)
+ })
+ Method (_STA, 0x0, NotSerialized) {
+ Return (0x0F)
+ }
+}
+
+Device(FUR1) {
+ Name(_HID,"AMD0020")
+ Name(_UID,0x1)
+ Name(_CRS, ResourceTemplate() {
+ IRQ(Edge, ActiveHigh, Exclusive) {11}
+ Memory32Fixed(ReadWrite, 0xFEDC8000, 0x2000)
+ })
+ Method (_STA, 0x0, NotSerialized) {
+ Return (0x0F)
+ }
+}
+
+Device(I2CA) {
+ Name(_HID,"AMD0010")
+ Name(_UID,0x0)
+ Name(_CRS, ResourceTemplate() {
+ IRQ(Edge, ActiveHigh, Exclusive) {3}
+ Memory32Fixed(ReadWrite, 0xFEDC2000, 0x1000)
+ })
+
+ Method (_STA, 0x0, NotSerialized) {
+ Return (0x0F)
+ }
+}
+
+Device(I2CB)
+{
+ Name(_HID,"AMD0010")
+ Name(_UID,0x1)
+ Name(_CRS, ResourceTemplate() {
+ IRQ(Edge, ActiveHigh, Exclusive) {15}
+ Memory32Fixed(ReadWrite, 0xFEDC3000, 0x1000)
+ })
+ Method (_STA, 0x0, NotSerialized) {
+ Return (0x0F)
+ }
+}
WANG Siyuan (wangsiyuanbuaa(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11732
-gerrit
commit db953ebd851da8127cc1105e22afba6150f3b177
Author: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Date: Fri Jul 3 20:29:56 2015 +0800
AMD Bettong: add get_board_id to read board version
Bettong use 3 GPIO(5-7) ports to identify board.
The GPIO ports are mapped to MMIO space.
The GPIO value and board version are mapped as follow:
GPIO5 GPIO6 GPIO7 Version
0 0 0 A
0 0 1 B
......
1 1 1 H
Change-Id: I72df28043057d8c4ccc4a2e645011ca5379e9928
Signed-off-by: WANG Siyuan <wangsiyuanbuaa(a)gmail.com>
Signed-off-by: WANG Siyuan <SiYuan.Wang(a)amd.com>
---
src/mainboard/amd/bettong/Makefile.inc | 2 ++
src/mainboard/amd/bettong/boardid.c | 45 ++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/src/mainboard/amd/bettong/Makefile.inc b/src/mainboard/amd/bettong/Makefile.inc
index 70722ee..197da03 100644
--- a/src/mainboard/amd/bettong/Makefile.inc
+++ b/src/mainboard/amd/bettong/Makefile.inc
@@ -19,9 +19,11 @@
romstage-y += BiosCallOuts.c
romstage-y += PlatformGnbPcie.c
+romstage-y += boardid.c
ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
ifeq ($(CONFIG_HUDSON_IMC_FWM), y)
ramstage-y += fchec.c
endif
+ramstage-y += boardid.c
diff --git a/src/mainboard/amd/bettong/boardid.c b/src/mainboard/amd/bettong/boardid.c
new file mode 100644
index 0000000..30343d7
--- /dev/null
+++ b/src/mainboard/amd/bettong/boardid.c
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, 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.
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/acpi.h>
+#include <console/console.h>
+#include <reset.h>
+#include <boardid.h>
+
+uint8_t board_id(void)
+{
+ u32 gpiommioaddr;
+ u8 value = 0;
+ u8 boardrev = 0;
+ char boardid;
+
+ gpiommioaddr = 0xfed80000ul + 0x1500;
+ value = *(volatile u8 *) (gpiommioaddr + (7 << 2) + 2); //agpio7 //board_id2
+ boardrev = value & 1;
+ value = *(volatile u8 *) (gpiommioaddr + (6 << 2) + 2); //agpio6 //board_id1
+ boardrev |= (value & 1) << 1;
+ value = *(volatile u8 *) (gpiommioaddr + (5 << 2) + 2); //agpio5 //board_id0
+ boardrev |= (value & 1) << 2;
+
+ boardid = 'A' + boardrev;
+
+ return boardid;
+}
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/11795
-gerrit
commit 7b983bcc119081fc270c212235da4cfb6ac1e752
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Sun Oct 4 19:34:08 2015 -0700
cpu/Makefile.inc: Only inculde x86 subdir if ARCH_x86 is selected
There is no other guard to prevent this from being picked up when
building for other architectures.
Change-Id: I2039a289a4dd9970d5dd0f90d43d5d5c2a6d0a0b
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/cpu/Makefile.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cpu/Makefile.inc b/src/cpu/Makefile.inc
index 92024f3..9220a8a 100644
--- a/src/cpu/Makefile.inc
+++ b/src/cpu/Makefile.inc
@@ -9,7 +9,7 @@ subdirs-y += imgtec
subdirs-y += intel
subdirs-y += ti
subdirs-y += via
-subdirs-y += x86
+subdirs-$(CONFIG_ARCH_X86) += x86
subdirs-$(CONFIG_CPU_QEMU_X86) += qemu-x86
$(eval $(call create_class_compiler,cpu_microcode,x86_32))
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 71a6497e3174a005cfd2a84dbe74e02c4d4579dd
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 | 17 ++++
src/cpu/x86/reset_entry/reset_entry.asm | 81 ++++++++++++++++++
9 files changed, 104 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..fe3a7dd
--- /dev/null
+++ b/src/cpu/x86/reset_entry/reset16.ld
@@ -0,0 +1,17 @@
+/*
+ * _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(realmode_start >= 0xffff0000,
+ "realmode_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..9ec409d
--- /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 realmode_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 realmode_start
+
+
+section .text
+
+realmode_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/11794
-gerrit
commit 8578e258c4180114e1168214decf94c977cf83de
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 | 17 ++++
src/cpu/x86/reset_entry/reset_entry.asm | 81 ++++++++++++++++++
9 files changed, 104 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..fe3a7dd
--- /dev/null
+++ b/src/cpu/x86/reset_entry/reset16.ld
@@ -0,0 +1,17 @@
+/*
+ * _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(realmode_start >= 0xffff0000,
+ "realmode_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..9ec409d
--- /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 realmode_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 realmode_start
+
+
+section .text
+
+realmode_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