Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9316
-gerrit
commit 443ba6e5ce0da4a5ba6a2ddb4a8ceba135386feb
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Apr 5 17:54:08 2015 -0500
mainboards/lenovo: Copy X200 board to T400 for future expansion
Change-Id: If2d48b84fe7bd7b144e96171e54067891e3c4e2e
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/mainboard/lenovo/Kconfig | 6 +
src/mainboard/lenovo/t400/Kconfig | 49 ++++++
src/mainboard/lenovo/t400/Makefile.inc | 20 +++
src/mainboard/lenovo/t400/acpi/dock.asl | 73 ++++++++
src/mainboard/lenovo/t400/acpi/ec.asl | 1 +
src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl | 86 ++++++++++
src/mainboard/lenovo/t400/acpi/gpe.asl | 29 ++++
src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl | 110 ++++++++++++
src/mainboard/lenovo/t400/acpi/platform.asl | 206 +++++++++++++++++++++++
src/mainboard/lenovo/t400/acpi/superio.asl | 0
src/mainboard/lenovo/t400/acpi_tables.c | 91 ++++++++++
src/mainboard/lenovo/t400/board_info.txt | 5 +
src/mainboard/lenovo/t400/cmos.default | 15 ++
src/mainboard/lenovo/t400/cmos.layout | 145 ++++++++++++++++
src/mainboard/lenovo/t400/cstates.c | 41 +++++
src/mainboard/lenovo/t400/devicetree.cb | 203 ++++++++++++++++++++++
src/mainboard/lenovo/t400/dock.c | 65 +++++++
src/mainboard/lenovo/t400/dock.h | 26 +++
src/mainboard/lenovo/t400/dsdt.asl | 59 +++++++
src/mainboard/lenovo/t400/fadt.c | 158 +++++++++++++++++
src/mainboard/lenovo/t400/hda_verb.c | 51 ++++++
src/mainboard/lenovo/t400/mainboard.c | 70 ++++++++
src/mainboard/lenovo/t400/mptable.c | 1 +
src/mainboard/lenovo/t400/romstage.c | 205 ++++++++++++++++++++++
src/mainboard/lenovo/t400/smihandler.c | 75 +++++++++
25 files changed, 1790 insertions(+)
diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig
index 95f7cfd..b6da044 100644
--- a/src/mainboard/lenovo/Kconfig
+++ b/src/mainboard/lenovo/Kconfig
@@ -32,6 +32,11 @@ config BOARD_LENOVO_X230
help
Lenovo X230 laptop. Consult wiki for details.
+config BOARD_LENOVO_T400
+ bool "ThinkPad T400"
+ help
+ Lenovo T400 laptop. Consult wiki for details.
+
config BOARD_LENOVO_T420S
bool "ThinkPad T420s"
help
@@ -72,6 +77,7 @@ source "src/mainboard/lenovo/x200/Kconfig"
source "src/mainboard/lenovo/x201/Kconfig"
source "src/mainboard/lenovo/x220/Kconfig"
source "src/mainboard/lenovo/x230/Kconfig"
+source "src/mainboard/lenovo/t400/Kconfig"
source "src/mainboard/lenovo/t420s/Kconfig"
source "src/mainboard/lenovo/t430s/Kconfig"
source "src/mainboard/lenovo/t520/Kconfig"
diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig
new file mode 100644
index 0000000..392ce692
--- /dev/null
+++ b/src/mainboard/lenovo/t400/Kconfig
@@ -0,0 +1,49 @@
+if BOARD_LENOVO_T400
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select SYSTEM_TYPE_LAPTOP
+ select CPU_INTEL_SOCKET_BGA956
+ select NORTHBRIDGE_INTEL_GM45
+ select SOUTHBRIDGE_INTEL_I82801IX
+ select EC_LENOVO_PMH7
+ select EC_LENOVO_H8
+ select NO_UART_ON_SUPERIO
+ select DRIVERS_ICS_954309
+ select BOARD_ROMSIZE_KB_8192
+ select DRIVERS_GENERIC_IOAPIC
+ select HAVE_MP_TABLE
+ select HAVE_ACPI_TABLES
+ select EC_ACPI
+ select HAVE_OPTION_TABLE
+ select HAVE_CMOS_DEFAULT
+ select HAVE_ACPI_RESUME
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG
+ select INTEL_INT15
+
+config MAINBOARD_DIR
+ string
+ default lenovo/t400
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "ThinkPad T400"
+
+config MMCONF_BASE_ADDRESS
+ hex
+ default 0xf0000000
+
+config USBDEBUG_HCD_INDEX
+ int
+ default 2
+
+config MAX_CPUS
+ int
+ default 2
+
+config CBFS_SIZE
+ hex
+ default 0x200000
+
+endif # BOARD_LENOVO_T400
diff --git a/src/mainboard/lenovo/t400/Makefile.inc b/src/mainboard/lenovo/t400/Makefile.inc
new file mode 100644
index 0000000..4eb1216
--- /dev/null
+++ b/src/mainboard/lenovo/t400/Makefile.inc
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 secunet Security Networks AG
+##
+## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+ramstage-y += dock.c
diff --git a/src/mainboard/lenovo/t400/acpi/dock.asl b/src/mainboard/lenovo/t400/acpi/dock.asl
new file mode 100644
index 0000000..605836b
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/dock.asl
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Scope (\_SB)
+{
+ Device(DOCK)
+ {
+ Name(_HID, "ACPI0003")
+ Name(_UID, 0x00)
+ Name(_PCL, Package() { \_SB } )
+
+ Method(_DCK, 1, NotSerialized)
+ {
+ if (Arg0) {
+ /* connect dock */
+ Store (1, \GP28)
+ Store (1, \_SB.PCI0.LPCB.EC.DKR1)
+ } else {
+ /* disconnect dock */
+ Store (0, \GP28)
+ Store (0, \_SB.PCI0.LPCB.EC.DKR1)
+ }
+ Xor(Arg0, \_SB.PCI0.LPCB.EC.DKR1, Local0)
+ Return (Local0)
+ }
+
+ Method(_STA, 0, NotSerialized)
+ {
+ Return (\_SB.PCI0.LPCB.EC.DKR1)
+ }
+ }
+}
+
+Scope(\_SB.PCI0.LPCB.EC)
+{
+ Method(_Q18, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 3)
+ }
+
+ Method(_Q45, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 3)
+ }
+
+ Method(_Q58, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 0)
+ }
+
+ Method(_Q37, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 0)
+ }
+}
diff --git a/src/mainboard/lenovo/t400/acpi/ec.asl b/src/mainboard/lenovo/t400/acpi/ec.asl
new file mode 100644
index 0000000..c3569e8
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/ec.asl
@@ -0,0 +1 @@
+#include <ec/lenovo/h8/acpi/ec.asl>
diff --git a/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl b/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl
new file mode 100644
index 0000000..83c7762
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* This is board specific information: IRQ routing for the
+ * gm45
+ */
+
+
+// PCI Interrupt Routing
+Method(_PRT)
+{
+ If (PICM) {
+ Return (Package() {
+ // PCIe Graphics 0:1.0
+ Package() { 0x0001ffff, 0, 0, 16 },
+ // Onboard graphics (IGD) 0:2.0
+ Package() { 0x0002ffff, 0, 0, 16 },
+ // USB and EHCI 0:1a.x
+ Package() { 0x001affff, 0, 0, 16 },
+ Package() { 0x001affff, 1, 0, 17 },
+ Package() { 0x001affff, 2, 0, 18 },
+ // High Definition Audio 0:1b.0
+ Package() { 0x001bffff, 0, 0, 16 },
+ // PCIe Root Ports 0:1c.x
+ Package() { 0x001cffff, 0, 0, 16 },
+ // USB and EHCI 0:1d.x
+ Package() { 0x001dffff, 0, 0, 16 },
+ Package() { 0x001dffff, 1, 0, 17 },
+ Package() { 0x001dffff, 2, 0, 18 },
+ // FIXME
+ // CardBus/IEEE1394 0:1e.2, 0:1e.3
+ // Package() { 0x001effff, 0, 0, 22 },
+ // Package() { 0x001effff, 1, 0, 20 },
+ // LPC device 0:1f.0
+ Package() { 0x001fffff, 0, 0, 16 },
+ Package() { 0x001fffff, 1, 0, 17 },
+ Package() { 0x001fffff, 2, 0, 18 }
+ })
+ } Else {
+ Return (Package() {
+ // PCIe Graphics 0:1.0
+ Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // Onboard graphics (IGD) 0:2.0
+ Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // USB and EHCI 0:1a.x
+ Package() { 0x001affff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x001affff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x001affff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+ // High Definition Audio 0:1b.0
+ Package() { 0x001bffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // PCIe Root Ports 0:1c.x
+ Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // USB and EHCI 0:1d.x
+ Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x001dffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x001dffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+ // FIXME
+ // CardBus/IEEE1394 0:1e.2, 0:1e.3
+ // Package() { 0x001effff, 0, \_SB.PCI0.LPCB.LNKG, 0 },
+ // Package() { 0x001effff, 1, \_SB.PCI0.LPCB.LNKE, 0 },
+ // LPC device 0:1f.0
+ Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }
+ })
+ }
+}
+
diff --git a/src/mainboard/lenovo/t400/acpi/gpe.asl b/src/mainboard/lenovo/t400/acpi/gpe.asl
new file mode 100644
index 0000000..3120caf
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/gpe.asl
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Scope (\_GPE)
+{
+ Method(_L18, 0, NotSerialized)
+ {
+ /* Read EC register to clear wake status */
+ Store(\_SB.PCI0.LPCB.EC.WAKE, Local0)
+ }
+}
diff --git a/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl b/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl
new file mode 100644
index 0000000..325f13c
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* This is board specific information: IRQ routing for the
+ * 0:1e.0 PCI bridge of the ICH9
+ */
+
+/* TODO: which slots are actually relevant? */
+If (PICM) {
+ Return (Package() {
+ // PCI Slot 1 routes ABCD
+ Package() { 0x0000ffff, 0, 0, 16},
+ Package() { 0x0000ffff, 1, 0, 17},
+ Package() { 0x0000ffff, 2, 0, 18},
+ Package() { 0x0000ffff, 3, 0, 19},
+
+ // PCI Slot 2 routes BCDA
+ Package() { 0x0001ffff, 0, 0, 17},
+ Package() { 0x0001ffff, 1, 0, 18},
+ Package() { 0x0001ffff, 2, 0, 19},
+ Package() { 0x0001ffff, 3, 0, 16},
+
+ // PCI Slot 3 routes CDAB
+ Package() { 0x0002ffff, 0, 0, 18},
+ Package() { 0x0002ffff, 1, 0, 19},
+ Package() { 0x0002ffff, 2, 0, 16},
+ Package() { 0x0002ffff, 3, 0, 17},
+
+ // PCI Slot 4 routes ABCD
+ Package() { 0x0003ffff, 0, 0, 16},
+ Package() { 0x0003ffff, 1, 0, 17},
+ Package() { 0x0003ffff, 2, 0, 18},
+ Package() { 0x0003ffff, 3, 0, 19},
+
+ // PCI Slot 5 routes ABCD
+ Package() { 0x0004ffff, 0, 0, 16},
+ Package() { 0x0004ffff, 1, 0, 17},
+ Package() { 0x0004ffff, 2, 0, 18},
+ Package() { 0x0004ffff, 3, 0, 19},
+
+ // PCI Slot 6 routes BCDA
+ Package() { 0x0005ffff, 0, 0, 17},
+ Package() { 0x0005ffff, 1, 0, 18},
+ Package() { 0x0005ffff, 2, 0, 19},
+ Package() { 0x0005ffff, 3, 0, 16},
+
+ // FIXME: what's this supposed to mean? (adopted from ich7)
+ //Package() { 0x0008ffff, 0, 0, 20},
+ })
+} Else {
+ Return (Package() {
+ // PCI Slot 1 routes ABCD
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
+
+ // PCI Slot 2 routes BCDA
+ Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKD, 0},
+ Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
+
+ // PCI Slot 3 routes CDAB
+ Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKD, 0},
+ Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKB, 0},
+
+ // PCI Slot 4 routes ABCD
+ Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0003ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0003ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0003ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
+
+ // PCI Slot 5 routes ABCD
+ Package() { 0x0004ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0004ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0004ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0004ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
+
+ // PCI Slot 6 routes BCDA
+ Package() { 0x0005ffff, 0, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0005ffff, 1, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0005ffff, 2, \_SB.PCI0.LPCB.LNKD, 0},
+ Package() { 0x0005ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
+
+ // FIXME
+ // Package() { 0x0008ffff, 0, \_SB.PCI0.LPCB.LNKE, 0},
+ })
+}
+
diff --git a/src/mainboard/lenovo/t400/acpi/platform.asl b/src/mainboard/lenovo/t400/acpi/platform.asl
new file mode 100644
index 0000000..2aa556f
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/platform.asl
@@ -0,0 +1,206 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* These come from the dynamically created CPU SSDT */
+External(PDC0)
+External(PDC1)
+
+/* The APM port can be used for generating software SMIs */
+
+OperationRegion (APMP, SystemIO, 0xb2, 2)
+Field (APMP, ByteAcc, NoLock, Preserve)
+{
+ APMC, 8, // APM command
+ APMS, 8 // APM status
+}
+
+/* Port 80 POST */
+
+OperationRegion (POST, SystemIO, 0x80, 1)
+Field (POST, ByteAcc, Lock, Preserve)
+{
+ DBG0, 8
+}
+
+/* SMI I/O Trap */
+Method(TRAP, 1, Serialized)
+{
+ Store (Arg0, SMIF) // SMI Function
+ Store (0, TRP0) // Generate trap
+ Return (SMIF) // Return value of SMI handler
+}
+
+/* The _PIC method is called by the OS to choose between interrupt
+ * routing via the i8259 interrupt controller or the APIC.
+ *
+ * _PIC is called with a parameter of 0 for i8259 configuration and
+ * with a parameter of 1 for Local Apic/IOAPIC configuration.
+ */
+
+Method(_PIC, 1)
+{
+ // Remember the OS' IRQ routing choice.
+ Store(Arg0, PICM)
+}
+
+/* The _PTS method (Prepare To Sleep) is called before the OS is
+ * entering a sleep state. The sleep state number is passed in Arg0
+ */
+
+Method(_PTS,1)
+{
+ // Call a trap so SMI can prepare for Sleep as well.
+ // TRAP(0x55)
+}
+
+/* The _WAK method is called on system wakeup */
+
+Method(_WAK,1)
+{
+ // CPU specific part
+
+ // Notify PCI Express slots in case a card
+ // was inserted while a sleep state was active.
+
+ // Are we going to S3?
+ If (LEqual(Arg0, 3)) {
+ // ..
+ }
+
+ // Are we going to S4?
+ If (LEqual(Arg0, 4)) {
+ // ..
+ }
+
+ // TODO: Windows XP SP2 P-State restore
+
+ // TODO: Return Arg0 as second value if S-Arg0 was entered
+ // before.
+
+ Return(Package(){0,0})
+}
+
+// Power notification
+
+External (\_PR_.CP00, DeviceObj)
+External (\_PR_.CP01, DeviceObj)
+
+Method (PNOT)
+{
+ If (MPEN) {
+ If(And(PDC0, 0x08)) {
+ Notify (\_PR_.CP00, 0x80) // _PPC
+
+ If (And(PDC0, 0x10)) {
+ Sleep(100)
+ Notify(\_PR_.CP00, 0x81) // _CST
+ }
+ }
+
+ If(And(PDC1, 0x08)) {
+ Notify (\_PR_.CP01, 0x80) // _PPC
+ If (And(PDC1, 0x10)) {
+ Sleep(100)
+ Notify(\_PR_.CP01, 0x81) // _CST
+ }
+ }
+
+ } Else { // UP
+ Notify (\_PR_.CP00, 0x80)
+ Sleep(0x64)
+ Notify(\_PR_.CP00, 0x81)
+ }
+
+}
+
+/* System Bus */
+
+Scope(\_SB)
+{
+ /* This method is placed on the top level, so we can make sure it's the
+ * first executed _INI method.
+ */
+ Method(_INI, 0)
+ {
+ /* The DTS data in NVS is probably not up to date.
+ * Update temperature values and make sure AP thermal
+ * interrupts can happen
+ */
+
+ // TRAP(71) // TODO
+
+ /* Determine the Operating System and save the value in OSYS.
+ * We have to do this in order to be able to work around
+ * certain windows bugs.
+ *
+ * OSYS value | Operating System
+ * -----------+------------------
+ * 2000 | Windows 2000
+ * 2001 | Windows XP(+SP1)
+ * 2002 | Windows XP SP2
+ * 2006 | Windows Vista
+ * ???? | Windows 7
+ */
+
+ /* Let's assume we're running at least Windows 2000 */
+ Store (2000, OSYS)
+
+ If (CondRefOf(_OSI, Local0)) {
+ /* Linux answers _OSI with "True" for a couple of
+ * Windows version queries. But unlike Windows it
+ * needs a Video repost, so let's determine whether
+ * we're running Linux.
+ */
+
+ If (_OSI("Linux")) {
+ Store (1, LINX)
+ }
+
+ If (_OSI("Windows 2001")) {
+ Store (2001, OSYS)
+ }
+
+ If (_OSI("Windows 2001 SP1")) {
+ Store (2001, OSYS)
+ }
+
+ If (_OSI("Windows 2001 SP2")) {
+ Store (2002, OSYS)
+ }
+
+ If (_OSI("Windows 2006")) {
+ Store (2006, OSYS)
+ }
+ }
+
+ /* And the OS workarounds start right after we know what we're
+ * running: Windows XP SP1 needs to have C-State coordination
+ * enabled in SMM.
+ */
+ If (LAnd(LEqual(OSYS, 2001), MPEN)) {
+ // TRAP(61) // TODO
+ }
+
+ /* SMM power state and C4-on-C3 settings need to be updated */
+ // TRAP(43) // TODO
+ }
+}
+
diff --git a/src/mainboard/lenovo/t400/acpi/superio.asl b/src/mainboard/lenovo/t400/acpi/superio.asl
new file mode 100644
index 0000000..e69de29
diff --git a/src/mainboard/lenovo/t400/acpi_tables.c b/src/mainboard/lenovo/t400/acpi_tables.c
new file mode 100644
index 0000000..77491dc
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi_tables.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <arch/smp/mpspec.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include "southbridge/intel/i82801ix/nvs.h"
+void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+ memset((void *)gnvs, 0, sizeof(*gnvs));
+ gnvs->apic = 1;
+ gnvs->mpen = 1; /* Enable Multi Processing */
+
+ /* Enable both COM ports */
+ gnvs->cmap = 0x01;
+ gnvs->cmbp = 0x01;
+
+ /* IGD Displays */
+ gnvs->ndid = 0; /* Will use default of 0x00000400. */
+ gnvs->did[0] = 0x80000100;
+ gnvs->did[1] = 0x80000240;
+ gnvs->did[2] = 0x80000410;
+ gnvs->did[3] = 0x80000410;
+ gnvs->did[4] = 0x00000005;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+ /* Local APICs */
+ current = acpi_create_madt_lapics(current);
+
+ /* IOAPIC */
+ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+ 2, IO_APIC_ADDR, 0);
+
+ /* LAPIC_NMI */
+ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
+ current, 0,
+ MP_IRQ_POLARITY_HIGH |
+ MP_IRQ_TRIGGER_EDGE, 0x01);
+ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
+ current, 1, MP_IRQ_POLARITY_HIGH |
+ MP_IRQ_TRIGGER_EDGE, 0x01);
+
+ /* INT_SRC_OVR */
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE);
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL);
+
+
+ return current;
+}
+
+unsigned long acpi_fill_slit(unsigned long current)
+{
+ // Not implemented
+ return current;
+}
+
+unsigned long acpi_fill_srat(unsigned long current)
+{
+ /* No NUMA, no SRAT */
+ return current;
+}
diff --git a/src/mainboard/lenovo/t400/board_info.txt b/src/mainboard/lenovo/t400/board_info.txt
new file mode 100644
index 0000000..60496f5
--- /dev/null
+++ b/src/mainboard/lenovo/t400/board_info.txt
@@ -0,0 +1,5 @@
+Category: laptop
+ROM package: SOIC-16
+ROM protocol: SPI
+ROM socketed: n
+Flashrom support: n
diff --git a/src/mainboard/lenovo/t400/cmos.default b/src/mainboard/lenovo/t400/cmos.default
new file mode 100644
index 0000000..1da4c7c
--- /dev/null
+++ b/src/mainboard/lenovo/t400/cmos.default
@@ -0,0 +1,15 @@
+boot_option=Fallback
+last_boot=Fallback
+baud_rate=115200
+debug_level=Spew
+volume=0x3
+first_battery=Primary
+bluetooth=Enable
+wwan=Enable
+wlan=Enable
+trackpoint=Enable
+fn_ctrl_swap=Disable
+sticky_fn=Disable
+power_management_beeps=Enable
+low_battery_beep=Enable
+sata_mode=AHCI
diff --git a/src/mainboard/lenovo/t400/cmos.layout b/src/mainboard/lenovo/t400/cmos.layout
new file mode 100644
index 0000000..57dd4d1
--- /dev/null
+++ b/src/mainboard/lenovo/t400/cmos.layout
@@ -0,0 +1,145 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2007-2008 coresystems GmbH
+# 2012 secunet Security Networks AG
+#
+# 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., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+# -----------------------------------------------------------------
+entries
+
+# -----------------------------------------------------------------
+# Status Register A
+# -----------------------------------------------------------------
+# Status Register B
+# -----------------------------------------------------------------
+# Status Register C
+#96 4 r 0 status_c_rsvd
+#100 1 r 0 uf_flag
+#101 1 r 0 af_flag
+#102 1 r 0 pf_flag
+#103 1 r 0 irqf_flag
+# -----------------------------------------------------------------
+# Status Register D
+#104 7 r 0 status_d_rsvd
+#111 1 r 0 valid_cmos_ram
+# -----------------------------------------------------------------
+# Diagnostic Status Register
+#112 8 r 0 diag_rsvd1
+
+# -----------------------------------------------------------------
+0 120 r 0 reserved_memory
+#120 240 r 0 unused
+
+# -----------------------------------------------------------------
+# RTC_BOOT_BYTE (coreboot hardcoded)
+384 1 e 4 boot_option
+385 1 e 4 last_boot
+388 4 r 0 reboot_bits
+#390 2 r 0 unused?
+
+# -----------------------------------------------------------------
+# coreboot config options: console
+392 3 e 5 baud_rate
+395 4 e 6 debug_level
+#399 1 r 0 unused
+
+# coreboot config options: EC
+400 8 h 0 volume
+
+# coreboot config options: southbridge
+408 1 e 10 sata_mode
+
+# coreboot config options: EC
+409 1 e 9 first_battery
+410 1 e 1 bluetooth
+411 1 e 1 wwan
+412 1 e 1 wlan
+413 1 e 1 trackpoint
+414 1 e 1 fn_ctrl_swap
+415 1 e 1 sticky_fn
+
+# coreboot config options: bootloader
+416 512 s 0 boot_devices
+928 8 h 0 boot_default
+
+936 1 e 1 power_management_beeps
+937 1 e 1 low_battery_beep
+938 1 e 1 uwb
+
+# coreboot config options: northbridge
+939 3 e 11 gfx_uma_size
+
+#942 2 r 0 unused
+
+# coreboot config options: check sums
+984 16 h 0 check_sum
+#1000 24 r 0 unused
+
+# ram initialization internal data
+1024 128 r 0 read_training_results
+
+# -----------------------------------------------------------------
+
+enumerations
+
+#ID value text
+1 0 Disable
+1 1 Enable
+2 0 Enable
+2 1 Disable
+4 0 Fallback
+4 1 Normal
+5 0 115200
+5 1 57600
+5 2 38400
+5 3 19200
+5 4 9600
+5 5 4800
+5 6 2400
+5 7 1200
+6 1 Emergency
+6 2 Alert
+6 3 Critical
+6 4 Error
+6 5 Warning
+6 6 Notice
+6 7 Info
+6 8 Debug
+6 9 Spew
+7 0 Disable
+7 1 Enable
+7 2 Keep
+8 0 No
+8 1 Yes
+9 0 Secondary
+9 1 Primary
+10 0 AHCI
+10 1 Compatible
+11 0 32M
+11 1 48M
+11 2 64M
+11 3 128M
+11 5 96M
+11 6 160M
+
+# -----------------------------------------------------------------
+checksums
+
+checksum 392 983 984
+
diff --git a/src/mainboard/lenovo/t400/cstates.c b/src/mainboard/lenovo/t400/cstates.c
new file mode 100644
index 0000000..aacfc31
--- /dev/null
+++ b/src/mainboard/lenovo/t400/cstates.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/acpigen.h>
+#include <device/device.h> /* fix for i82801ix.h */
+#include <southbridge/intel/i82801ix/i82801ix.h>
+
+static acpi_cstate_t cst_entries[] = {
+ {
+ /* acpi C1 / cpu C1 */
+ 1, 0x01, 1000,
+ { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0, 0 }
+ },
+ {
+ /* acpi C2 / cpu C2 */
+ 2, 0x01, 500,
+ { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0x10, 0 }
+ },
+};
+
+int get_cst_entries(acpi_cstate_t **entries)
+{
+ *entries = cst_entries;
+ return ARRAY_SIZE(cst_entries);
+}
diff --git a/src/mainboard/lenovo/t400/devicetree.cb b/src/mainboard/lenovo/t400/devicetree.cb
new file mode 100644
index 0000000..cc27d25
--- /dev/null
+++ b/src/mainboard/lenovo/t400/devicetree.cb
@@ -0,0 +1,203 @@
+chip northbridge/intel/gm45
+
+ register "gfx.use_spread_spectrum_clock" = "1"
+ register "gfx.lvds_dual_channel" = "0"
+ register "gfx.link_frequency_270_mhz" = "1"
+ register "gfx.lvds_num_lanes" = "4"
+
+ device cpu_cluster 0 on
+ chip cpu/intel/socket_BGA956
+ device lapic 0 on end
+ end
+ chip cpu/intel/model_1067x
+ # Magic APIC ID to locate this chip
+ device lapic 0xACAC off end
+
+ # Enable Super LFM
+ register "slfm" = "1"
+
+ # Enable C5, C6
+ register "c5" = "1"
+ register "c6" = "1"
+ end
+ end
+
+ device domain 0 on
+ device pci 00.0 on
+ subsystemid 0x17aa 0x20e0
+ end # host bridge
+ device pci 02.0 on # VGA
+ subsystemid 0x17aa 0x20e4
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 02.1 on
+ subsystemid 0x17aa 0x20e4
+ end # Display
+ device pci 03.0 on
+ subsystemid 0x17aa 0x20e6
+ end # ME
+ device pci 03.1 off end # ME
+ device pci 03.2 off end # ME
+ device pci 03.3 off end # ME
+ chip southbridge/intel/i82801ix
+ register "pirqa_routing" = "0x0b"
+ register "pirqb_routing" = "0x0b"
+ register "pirqc_routing" = "0x0b"
+ register "pirqd_routing" = "0x0b"
+ register "pirqe_routing" = "0x80"
+ register "pirqf_routing" = "0x80"
+ register "pirqg_routing" = "0x80"
+ register "pirqh_routing" = "0x80"
+
+ register "gpi8_routing" = "2"
+ register "gpe0_en" = "0x01000000"
+ register "gpi1_routing" = "2"
+
+ # Set AHCI mode, enable ports 1 and 2.
+ register "sata_port_map" = "0x03"
+ register "sata_clock_request" = "0"
+ register "sata_traffic_monitor" = "0"
+
+ # Set c-state support
+ register "c4onc3_enable" = "0"
+ register "c5_enable" = "1"
+ register "c6_enable" = "1"
+
+ # Set thermal throttling to 75%.
+ register "throttle_duty" = "THTL_75_0"
+
+ # Enable PCIe ports 1,2,4 as slots (Mini * PCIe).
+ register "pcie_slot_implemented" = "0xb"
+ # Set power limits to 10 * 10^0 watts.
+ # Maybe we should set less for Mini PCIe.
+ register "pcie_power_limits" = "{ { 10, 0 }, { 10, 0 }, { 0, 0 }, { 10, 0 }, { 0, 0 }, { 0, 0 } }"
+ register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }"
+
+ chip drivers/generic/ioapic
+ register "have_isa_interrupts" = "1"
+ register "irq_on_fsb" = "1"
+ register "enable_virtual_wire" = "1"
+ register "base" = "(void *)0xfec00000"
+ device ioapic 2 on end
+ end
+
+ device pci 19.0 on end # LAN
+ device pci 1a.0 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1a.1 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTB 0x11
+ end
+ device pci 1a.2 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTC 0x12
+ end
+ device pci 1a.7 on # EHCI
+ subsystemid 0x17aa 0x20f1
+ ioapic_irq 2 INTC 0x12
+ end
+ device pci 1b.0 on # HD Audio
+ subsystemid 0x17aa 0x20f2
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1c.0 on # PCIe Port #1
+ subsystemid 0x17aa 0x20f3 # WWAN
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1c.1 on
+ subsystemid 0x17aa 0x20f3 # WLAN
+ end # PCIe Port #2
+ device pci 1c.2 on
+ subsystemid 0x17aa 0x20f3 # UWB
+ end # PCIe Port #3
+ device pci 1c.3 on
+ subsystemid 0x17aa 0x20f3 # Expresscard
+ end # PCIe Port #4
+ device pci 1c.4 off end # PCIe Port #5
+ device pci 1c.5 off end # PCIe Port #6
+ device pci 1d.0 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1d.1 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTB 0x11
+ end
+ device pci 1d.2 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTC 0x12
+ end
+ device pci 1d.7 on # EHCI
+ subsystemid 0x17aa 0x20f1
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1e.0 on # PCI
+ subsystemid 0x17aa 0x20f4
+ end
+ device pci 1f.0 on # LPC bridge
+ subsystemid 0x17aa 0x20f5
+ chip ec/lenovo/pmh7
+ device pnp ff.1 on # dummy
+ end
+ register "backlight_enable" = "0x01"
+ register "dock_event_enable" = "0x01"
+ end
+
+ chip ec/lenovo/h8
+ device pnp ff.2 on # dummy
+ io 0x60 = 0x62
+ io 0x62 = 0x66
+ io 0x64 = 0x1600
+ io 0x66 = 0x1604
+ end
+
+ register "config0" = "0xa6"
+ register "config1" = "0x04"
+ register "config2" = "0xa0"
+ register "config3" = "0x01"
+
+ register "beepmask0" = "0xfe"
+ register "beepmask1" = "0x96"
+ register "has_power_management_beeps" = "1"
+ register "has_uwb" = "1"
+
+ register "event2_enable" = "0xff"
+ register "event3_enable" = "0xff"
+ register "event4_enable" = "0xf4"
+ register "event5_enable" = "0x3c"
+ register "event6_enable" = "0x80"
+ register "event7_enable" = "0x01"
+ register "event8_enable" = "0x01"
+ register "event9_enable" = "0xff"
+ register "eventa_enable" = "0xff"
+ register "eventb_enable" = "0xff"
+ register "eventc_enable" = "0xff"
+ register "eventd_enable" = "0xff"
+ end
+ end
+ device pci 1f.2 on # SATA/IDE 1
+ subsystemid 0x17aa 0x20f8
+ ioapic_irq 2 INTB 0x11
+ end
+ device pci 1f.3 on # SMBus
+ subsystemid 0x17aa 0x20f9
+ ioapic_irq 2 INTC 0x12
+ # eeprom, 8 virtual devices, same chip
+ chip drivers/i2c/at24rf08c
+ device i2c 54 on end
+ device i2c 55 on end
+ device i2c 56 on end
+ device i2c 57 on end
+ device i2c 5c on end
+ device i2c 5d on end
+ device i2c 5e on end
+ device i2c 5f on end
+ end
+ end
+ device pci 1f.5 off end # SATA/IDE 2
+ device pci 1f.6 off end # Thermal
+ end
+ end
+end
diff --git a/src/mainboard/lenovo/t400/dock.c b/src/mainboard/lenovo/t400/dock.c
new file mode 100644
index 0000000..6f9e953
--- /dev/null
+++ b/src/mainboard/lenovo/t400/dock.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org>
+ * Copyright (C) 2013 Vladimir Serbinenko <phcoder(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; 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define __SIMPLE_DEVICE__
+#include <console/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <delay.h>
+#include "dock.h"
+#include "southbridge/intel/i82801ix/i82801ix.h"
+#include "ec/lenovo/h8/h8.h"
+#include <ec/acpi/ec.h>
+
+#define LPC_DEV PCI_DEV(0, 0x1f, 0)
+
+void h8_mainboard_init_dock (void)
+{
+ if (dock_present()) {
+ printk(BIOS_DEBUG, "dock is connected\n");
+ dock_connect();
+ } else
+ printk(BIOS_DEBUG, "dock is not connected\n");
+}
+
+void dock_connect(void)
+{
+ u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc;
+ ec_set_bit(0x02, 0);
+ outl(inl(gpiobase + 0x0c) | (1 << 28), gpiobase + 0x0c);
+}
+
+void dock_disconnect(void)
+{
+ u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc;
+ ec_clr_bit(0x02, 0);
+ outl(inl(gpiobase + 0x0c) & ~(1 << 28), gpiobase + 0x0c);
+}
+
+int dock_present(void)
+{
+ u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc;
+ u8 st = inb(gpiobase + 0x0c);
+
+ return ((st >> 2) & 7) != 7;
+}
diff --git a/src/mainboard/lenovo/t400/dock.h b/src/mainboard/lenovo/t400/dock.h
new file mode 100644
index 0000000..e888583
--- /dev/null
+++ b/src/mainboard/lenovo/t400/dock.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef THINKPAD_X200_DOCK_H
+#define THINKPAD_X200_DOCK_H
+
+extern void dock_connect(void);
+extern void dock_disconnect(void);
+extern int dock_present(void);
+#endif
diff --git a/src/mainboard/lenovo/t400/dsdt.asl b/src/mainboard/lenovo/t400/dsdt.asl
new file mode 100644
index 0000000..0409e66
--- /dev/null
+++ b/src/mainboard/lenovo/t400/dsdt.asl
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define THINKPAD_EC_GPE 17
+#define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB
+#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB
+#define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0
+#define DISPLAY_DEVICE_2_IS_LCD_SCREEN 1
+
+DefinitionBlock(
+ "dsdt.aml",
+ "DSDT",
+ 0x03, // DSDT revision: ACPI v3.0
+ "COREv4", // OEM id
+ "COREBOOT", // OEM table id
+ 0x20090419 // OEM revision
+)
+{
+ // Some generic macros
+ #include "acpi/platform.asl"
+
+ // global NVS and variables
+ #include <southbridge/intel/i82801ix/acpi/globalnvs.asl>
+
+ // General Purpose Events
+ #include "acpi/gpe.asl"
+
+ Scope (\_SB) {
+ Device (PCI0)
+ {
+ #include <northbridge/intel/gm45/acpi/gm45.asl>
+ #include <southbridge/intel/i82801ix/acpi/ich9.asl>
+ }
+ }
+
+ /* Chipset specific sleep states */
+ #include <southbridge/intel/i82801ix/acpi/sleepstates.asl>
+
+ /* Dock support code */
+ #include "acpi/dock.asl"
+}
diff --git a/src/mainboard/lenovo/t400/fadt.c b/src/mainboard/lenovo/t400/fadt.c
new file mode 100644
index 0000000..fef9721
--- /dev/null
+++ b/src/mainboard/lenovo/t400/fadt.c
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <device/pci.h>
+#include <arch/acpi.h>
+#include <cpu/x86/smm.h>
+
+void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+ u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe;
+
+ memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+ memcpy(header->signature, "FACP", 4);
+ header->length = sizeof(acpi_fadt_t);
+ header->revision = 3;
+ memcpy(header->oem_id, OEM_ID, 6);
+ memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+ memcpy(header->asl_compiler_id, ASLC, 4);
+ header->asl_compiler_revision = 0;
+
+ fadt->firmware_ctrl = (unsigned long) facs;
+ fadt->dsdt = (unsigned long) dsdt;
+ fadt->model = 0x00;
+ fadt->preferred_pm_profile = PM_MOBILE;
+ fadt->sci_int = 0x9;
+ fadt->smi_cmd = APM_CNT;
+ fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+ fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = APM_CNT_PST_CONTROL;
+
+ fadt->pm1a_evt_blk = pmbase;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = pmbase + 0x4;
+ fadt->pm1b_cnt_blk = 0x0;
+ fadt->pm2_cnt_blk = pmbase + 0x50;
+ fadt->pm_tmr_blk = pmbase + 0x8;
+ fadt->gpe0_blk = pmbase + 0x20;
+ fadt->gpe1_blk = 0;
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2; /* Upper word is reserved and
+ Linux complains about 32 bit. */
+ fadt->pm2_cnt_len = 1;
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 16;
+ fadt->gpe1_blk_len = 0;
+ fadt->gpe1_base = 0;
+ fadt->cst_cnt = APM_CNT_CST_CONTROL;
+ fadt->p_lvl2_lat = 1;
+ fadt->p_lvl3_lat = 0x39;
+ fadt->flush_size = 0;
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 1;
+ fadt->duty_width = 3;
+ fadt->day_alrm = 0xd;
+ fadt->mon_alrm = 0x00;
+ fadt->century = 0x32;
+ fadt->iapc_boot_arch = 0x00;
+ fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+ ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
+ ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER |
+ ACPI_FADT_PLATFORM_CLOCK;
+
+ fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
+ fadt->reset_reg.bit_width = 8;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0xcf9;
+ fadt->reset_reg.addrh = 0;
+ fadt->reset_value = 0x06;
+
+ fadt->x_firmware_ctl_l = 0; /* Set X_FIRMWARE_CTRL only if FACS is */
+ fadt->x_firmware_ctl_h = 0; /* above 4GB. If X_FIRMWARE_CTRL is set, */
+ /* then FIRMWARE_CTRL must be zero. */
+ fadt->x_dsdt_l = (unsigned long)dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = 32;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = pmbase;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 0;
+ fadt->x_pm1b_evt_blk.bit_width = 0;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = 0x0;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = 16; /* Upper word is reserved and
+ Linux complains about 32 bit. */
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 0;
+ fadt->x_pm1b_cnt_blk.bit_width = 0;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = 0x0;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = 8;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = 32;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = 128;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = pmbase + 0x20;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+ fadt->x_gpe1_blk.space_id = 0;
+ fadt->x_gpe1_blk.bit_width = 0;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = 0x0;
+ fadt->x_gpe1_blk.addrh = 0x0;
+
+ header->checksum =
+ acpi_checksum((void *) fadt, header->length);
+}
diff --git a/src/mainboard/lenovo/t400/hda_verb.c b/src/mainboard/lenovo/t400/hda_verb.c
new file mode 100644
index 0000000..c1cd542
--- /dev/null
+++ b/src/mainboard/lenovo/t400/hda_verb.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/azalia_device.h>
+
+const u32 cim_verb_data[] = {
+ /* coreboot specific header */
+ 0x14f15051, // Conexant CX20561 (Hermosa)
+ 0x17aa20ff, // Subsystem ID
+ 0x00000008, // Number of entries
+
+ /* Pin Widget Verb Table */
+
+ AZALIA_PIN_CFG(0, 0x16, 0x042140f0),
+ AZALIA_PIN_CFG(0, 0x17, 0x61a190f0),
+ AZALIA_PIN_CFG(0, 0x18, 0x04a190f0),
+ AZALIA_PIN_CFG(0, 0x19, 0x612140f0),
+ AZALIA_PIN_CFG(0, 0x1a, 0x901701f0),
+ AZALIA_PIN_CFG(0, 0x1b, 0x40f001f0),
+ AZALIA_PIN_CFG(0, 0x1c, 0x40f001f0),
+ AZALIA_PIN_CFG(0, 0x1d, 0x90a601f0)
+};
+
+const u32 pc_beep_verbs[] = {
+ 0x00170500, /* power up codec */
+ 0x01470500, /* power up speakers */
+ 0x01470100, /* select lout1 (input 0x0) for speakers */
+ 0x01470740, /* enable speakers output */
+ 0x00b37517, /* unmute beep (mixer's input 0x5), set amp 0dB */
+ 0x00c37100, /* unmute mixer in lout1 (lout1 input 0x1) */
+ 0x00c3b015, /* set lout1 output volume -15dB */
+ 0x0143b000, /* unmute speakers */
+};
+AZALIA_ARRAY_SIZES;
diff --git a/src/mainboard/lenovo/t400/mainboard.c b/src/mainboard/lenovo/t400/mainboard.c
new file mode 100644
index 0000000..5354834
--- /dev/null
+++ b/src/mainboard/lenovo/t400/mainboard.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <console/console.h>
+#include <drivers/intel/gma/int15.h>
+#include <pc80/keyboard.h>
+#include <ec/acpi/ec.h>
+#include <smbios.h>
+#include <string.h>
+#include <version.h>
+#include <ec/lenovo/pmh7/pmh7.h>
+#include <ec/acpi/ec.h>
+#include <ec/lenovo/h8/h8.h>
+
+#include "cstates.c" /* Include it, as the linker won't find
+ the overloaded weak function in there. */
+
+const char *smbios_mainboard_bios_version(void)
+{
+ static char *s = NULL;
+
+ /* Satisfy thinkpad_acpi. */
+ if (strlen(CONFIG_LOCALVERSION))
+ return "CBET4000 " CONFIG_LOCALVERSION;
+
+ if (s != NULL)
+ return s;
+ s = strconcat("CBET4000 ", coreboot_version);
+ return s;
+}
+
+static void mainboard_init(device_t dev)
+{
+ /* This sneaked in here, because X200 SuperIO chip isn't really
+ connected to anything and hence we don't init it.
+ */
+ pc_keyboard_init();
+}
+
+static void mainboard_enable(device_t dev)
+{
+ install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_CENTERING, GMA_INT15_BOOT_DISPLAY_DEFAULT, 2);
+
+ dev->ops->init = mainboard_init;
+}
+
+struct chip_operations mainboard_ops = {
+ .enable_dev = mainboard_enable,
+};
+
diff --git a/src/mainboard/lenovo/t400/mptable.c b/src/mainboard/lenovo/t400/mptable.c
new file mode 100644
index 0000000..f1839f0
--- /dev/null
+++ b/src/mainboard/lenovo/t400/mptable.c
@@ -0,0 +1 @@
+/* dummy file */
diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c
new file mode 100644
index 0000000..5f50f32
--- /dev/null
+++ b/src/mainboard/lenovo/t400/romstage.c
@@ -0,0 +1,205 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// __PRE_RAM__ means: use "unsigned" for device, not a struct.
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <cbmem.h>
+#include <lib.h>
+#include <pc80/mc146818rtc.h>
+#include <console/console.h>
+#include <southbridge/intel/i82801ix/i82801ix.h>
+#include <northbridge/intel/gm45/gm45.h>
+#include <cpu/intel/romstage.h>
+
+#define LPC_DEV PCI_DEV(0, 0x1f, 0)
+#define MCH_DEV PCI_DEV(0, 0, 0)
+
+static void default_southbridge_gpio_setup(void)
+{
+ outl(0x197e23fe, DEFAULT_GPIOBASE + GP_IO_USE_SEL);
+ outl(0xe1a66dfe, DEFAULT_GPIOBASE + GP_IO_SEL);
+ outl(0xe3faef3f, DEFAULT_GPIOBASE + GP_LVL);
+
+ /* Disable blink [31:0]. */
+ outl(0x00000000, DEFAULT_GPIOBASE + GPO_BLINK);
+ /* Set input inversion [31:0]. */
+ outl(0x00000102, DEFAULT_GPIOBASE + GPI_INV);
+
+ /* Enable GPIOs [60:32]. */
+ outl(0x030306f6, DEFAULT_GPIOBASE + GP_IO_USE_SEL2);
+ /* Set input/output mode [60:32] (0 == out, 1 == in). */
+ outl(0x1f55f9f1, DEFAULT_GPIOBASE + GP_IO_SEL2);
+ /* Set gpio levels [60:32]. */
+ outl(0x1dffff53, DEFAULT_GPIOBASE + GP_LVL2);
+}
+
+static void early_lpc_setup(void)
+{
+ /* Set up SuperIO LPC forwards */
+
+ /* Configure serial IRQs.*/
+ pci_write_config8(LPC_DEV, D31F0_SERIRQ_CNTL, 0xd0);
+ /* Map COMa on 0x3f8, COMb on 0x2f8. */
+ pci_write_config16(LPC_DEV, D31F0_LPC_IODEC, 0x0010);
+ pci_write_config16(LPC_DEV, D31F0_LPC_EN, 0x3f0f);
+ pci_write_config32(LPC_DEV, D31F0_GEN1_DEC, 0x7c1601);
+ pci_write_config32(LPC_DEV, D31F0_GEN2_DEC, 0xc15e1);
+ pci_write_config32(LPC_DEV, D31F0_GEN3_DEC, 0x1c1681);
+}
+
+void main(unsigned long bist)
+{
+ sysinfo_t sysinfo;
+ int s3resume = 0;
+ int cbmem_initted;
+ u16 reg16;
+
+ /* basic northbridge setup, including MMCONF BAR */
+ gm45_early_init();
+
+ if (bist == 0)
+ enable_lapic();
+
+ /* First, run everything needed for console output. */
+ i82801ix_early_init();
+ early_lpc_setup();
+ console_init();
+ printk(BIOS_DEBUG, "running main(bist = %lu)\n", bist);
+
+ reg16 = pci_read_config16(LPC_DEV, D31F0_GEN_PMCON_3);
+ pci_write_config16(LPC_DEV, D31F0_GEN_PMCON_3, reg16);
+ if ((MCHBAR16(SSKPD_MCHBAR) == 0xCAFE) && !(reg16 & (1 << 9))) {
+ printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n");
+ gm45_early_reset();
+ }
+
+ default_southbridge_gpio_setup();
+
+ /* ASPM related setting, set early by original BIOS. */
+ DMIBAR16(0x204) &= ~(3 << 10);
+
+ /* Check for S3 resume. */
+ const u32 pm1_cnt = inl(DEFAULT_PMBASE + 0x04);
+ if (((pm1_cnt >> 10) & 7) == 5) {
+#if CONFIG_HAVE_ACPI_RESUME
+ printk(BIOS_DEBUG, "Resume from S3 detected.\n");
+ s3resume = 1;
+ /* Clear SLP_TYPE. This will break stage2 but
+ * we care for that when we get there.
+ */
+ outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + 0x04);
+#else
+ printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
+#endif
+ }
+
+ /* RAM initialization */
+ enter_raminit_or_reset();
+ memset(&sysinfo, 0, sizeof(sysinfo));
+ sysinfo.spd_map[0] = 0x50;
+ sysinfo.spd_map[2] = 0x51;
+ sysinfo.enable_igd = 1;
+ sysinfo.enable_peg = 0;
+ get_gmch_info(&sysinfo);
+ raminit(&sysinfo, s3resume);
+
+ const u32 deven = pci_read_config32(MCH_DEV, D0F0_DEVEN);
+ /* Disable D4F0 (unknown signal controller). */
+ pci_write_config32(MCH_DEV, D0F0_DEVEN, deven & ~0x4000);
+
+ init_pm(&sysinfo, 0);
+
+ i82801ix_dmi_setup();
+ gm45_late_init(sysinfo.stepping);
+ i82801ix_dmi_poll_vc1();
+
+ MCHBAR16(SSKPD_MCHBAR) = 0xCAFE;
+ /* Enable ethernet. */
+ RCBA32(0x3414) &= ~0x20;
+
+ RCBA32(0x0238) = 0x00543210;
+ RCBA32(0x0240) = 0x009c0b02;
+ RCBA32(0x0244) = 0x00a20b1a;
+ RCBA32(0x0248) = 0x005402cb;
+ RCBA32(0x0254) = 0x00470966;
+ RCBA32(0x0258) = 0x00470473;
+ RCBA32(0x0260) = 0x00e90825;
+ RCBA32(0x0278) = 0x00bc0efb;
+ RCBA32(0x027c) = 0x00c00f0b;
+ RCBA32(0x0280) = 0x00670000;
+ RCBA32(0x0284) = 0x006d0000;
+ RCBA32(0x0288) = 0x00600b4e;
+ RCBA32(0x1e10) = 0x00020800;
+ RCBA32(0x1e18) = 0x36ea00a0;
+ RCBA32(0x1e80) = 0x000c0801;
+ RCBA32(0x1e84) = 0x000200f0;
+ RCBA32(0x2028) = 0x04c8f95e;
+ RCBA32(0x202c) = 0x055c095e;
+ RCBA32(0x204c) = 0x001ffc00;
+ RCBA32(0x2050) = 0x00100fff;
+ RCBA32(0x2090) = 0x37000000;
+ RCBA32(0x20b0) = 0x0c000000;
+ RCBA32(0x20d0) = 0x09000000;
+ RCBA32(0x20f0) = 0x05000000;
+ RCBA32(0x3400) = 0x0000001c;
+ RCBA32(0x3410) = 0x00100461;
+ RCBA32(0x3414) = 0x00000000;
+ RCBA32(0x341c) = 0xbf4f001f;
+ RCBA32(0x3420) = 0x00000000;
+ RCBA32(0x3430) = 0x00000001;
+
+ init_iommu();
+
+ /* FIXME: make a proper SMBUS mux support. */
+ outl(inl(DEFAULT_GPIOBASE + 0x38) & ~0x400, DEFAULT_GPIOBASE + 0x38);
+
+ cbmem_initted = !cbmem_recovery(s3resume);
+#if CONFIG_HAVE_ACPI_RESUME
+ /* If there is no high memory area, we didn't boot before, so
+ * this is not a resume. In that case we just create the cbmem toc.
+ */
+ if (s3resume && cbmem_initted) {
+ void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
+
+ /* copy 1MB - 64K to high tables ram_base to prevent memory corruption
+ * through stage 2. We could keep stuff like stack and heap in high tables
+ * memory completely, but that's a wonderful clean up task for another
+ * day.
+ */
+ if (resume_backup_memory)
+ memcpy(resume_backup_memory, (void *)CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
+
+ /* Magic for S3 resume */
+ pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_ACPI_S3_MAGIC);
+ } else {
+ /* Magic for S3 resume */
+ pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_NORMAL_BOOT_MAGIC);
+ }
+#endif
+ printk(BIOS_SPEW, "exit main()\n");
+}
+
diff --git a/src/mainboard/lenovo/t400/smihandler.c b/src/mainboard/lenovo/t400/smihandler.c
new file mode 100644
index 0000000..baa038e
--- /dev/null
+++ b/src/mainboard/lenovo/t400/smihandler.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <southbridge/intel/i82801ix/nvs.h>
+#include <southbridge/intel/i82801ix/i82801ix.h>
+#include <ec/acpi/ec.h>
+
+/* The southbridge SMI handler checks whether gnvs has a
+ * valid pointer before calling the trap handler
+ */
+extern global_nvs_t *gnvs;
+
+int mainboard_io_trap_handler(int smif)
+{
+ switch (smif) {
+ case 0x99:
+ printk(BIOS_DEBUG, "Sample\n");
+ gnvs->smif = 0;
+ break;
+ default:
+ return 0;
+ }
+
+ /* On success, the IO Trap Handler returns 0
+ * On failure, the IO Trap Handler returns a value != 0
+ *
+ * For now, we force the return value to 0 and log all traps to
+ * see what's going on.
+ */
+ //gnvs->smif = 0;
+ return 1;
+}
+
+void mainboard_smi_gpi(u32 gpi_sts)
+{
+ if (gpi_sts & (1 << 1)) {
+ printk(BIOS_DEBUG, "EC/SMI\n");
+ /* TODO */
+ }
+}
+
+int mainboard_smi_apmc(u8 apmc)
+{
+ switch (apmc) {
+ case APM_CNT_ACPI_ENABLE:
+ send_ec_command(0x05); /* Set_SMI_Disable */
+ send_ec_command(0xaa); /* Set_ACPI_Enable */
+ break;
+
+ case APM_CNT_ACPI_DISABLE:
+ send_ec_command(0x04); /* Set_SMI_Enable */
+ send_ec_command(0xab); /* Set_ACPI_Disable */
+ break;
+ }
+ return 0;
+}
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9316
-gerrit
commit 0aa2b4b8dc5c7af925259734225d3ab3f13b87be
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Sun Apr 5 17:54:08 2015 -0500
mainboards/lenovo: Copy X200 board to T400 for future expansion
Change-Id: If2d48b84fe7bd7b144e96171e54067891e3c4e2e
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/mainboard/lenovo/Kconfig | 6 +
src/mainboard/lenovo/t400/Kconfig | 49 ++++++
src/mainboard/lenovo/t400/Makefile.inc | 20 +++
src/mainboard/lenovo/t400/acpi/dock.asl | 73 ++++++++
src/mainboard/lenovo/t400/acpi/ec.asl | 1 +
src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl | 86 ++++++++++
src/mainboard/lenovo/t400/acpi/gpe.asl | 29 ++++
src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl | 110 ++++++++++++
src/mainboard/lenovo/t400/acpi/platform.asl | 206 +++++++++++++++++++++++
src/mainboard/lenovo/t400/acpi/superio.asl | 0
src/mainboard/lenovo/t400/acpi_tables.c | 91 ++++++++++
src/mainboard/lenovo/t400/board_info.txt | 5 +
src/mainboard/lenovo/t400/cmos.default | 15 ++
src/mainboard/lenovo/t400/cmos.layout | 145 ++++++++++++++++
src/mainboard/lenovo/t400/cstates.c | 41 +++++
src/mainboard/lenovo/t400/devicetree.cb | 203 ++++++++++++++++++++++
src/mainboard/lenovo/t400/dock.c | 65 +++++++
src/mainboard/lenovo/t400/dock.h | 26 +++
src/mainboard/lenovo/t400/dsdt.asl | 59 +++++++
src/mainboard/lenovo/t400/fadt.c | 158 +++++++++++++++++
src/mainboard/lenovo/t400/hda_verb.c | 51 ++++++
src/mainboard/lenovo/t400/mainboard.c | 70 ++++++++
src/mainboard/lenovo/t400/mptable.c | 1 +
src/mainboard/lenovo/t400/romstage.c | 205 ++++++++++++++++++++++
src/mainboard/lenovo/t400/smihandler.c | 75 +++++++++
25 files changed, 1790 insertions(+)
diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig
index 95f7cfd..b6da044 100644
--- a/src/mainboard/lenovo/Kconfig
+++ b/src/mainboard/lenovo/Kconfig
@@ -32,6 +32,11 @@ config BOARD_LENOVO_X230
help
Lenovo X230 laptop. Consult wiki for details.
+config BOARD_LENOVO_T400
+ bool "ThinkPad T400"
+ help
+ Lenovo T400 laptop. Consult wiki for details.
+
config BOARD_LENOVO_T420S
bool "ThinkPad T420s"
help
@@ -72,6 +77,7 @@ source "src/mainboard/lenovo/x200/Kconfig"
source "src/mainboard/lenovo/x201/Kconfig"
source "src/mainboard/lenovo/x220/Kconfig"
source "src/mainboard/lenovo/x230/Kconfig"
+source "src/mainboard/lenovo/t400/Kconfig"
source "src/mainboard/lenovo/t420s/Kconfig"
source "src/mainboard/lenovo/t430s/Kconfig"
source "src/mainboard/lenovo/t520/Kconfig"
diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig
new file mode 100644
index 0000000..392ce692
--- /dev/null
+++ b/src/mainboard/lenovo/t400/Kconfig
@@ -0,0 +1,49 @@
+if BOARD_LENOVO_T400
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select SYSTEM_TYPE_LAPTOP
+ select CPU_INTEL_SOCKET_BGA956
+ select NORTHBRIDGE_INTEL_GM45
+ select SOUTHBRIDGE_INTEL_I82801IX
+ select EC_LENOVO_PMH7
+ select EC_LENOVO_H8
+ select NO_UART_ON_SUPERIO
+ select DRIVERS_ICS_954309
+ select BOARD_ROMSIZE_KB_8192
+ select DRIVERS_GENERIC_IOAPIC
+ select HAVE_MP_TABLE
+ select HAVE_ACPI_TABLES
+ select EC_ACPI
+ select HAVE_OPTION_TABLE
+ select HAVE_CMOS_DEFAULT
+ select HAVE_ACPI_RESUME
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG
+ select INTEL_INT15
+
+config MAINBOARD_DIR
+ string
+ default lenovo/t400
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "ThinkPad T400"
+
+config MMCONF_BASE_ADDRESS
+ hex
+ default 0xf0000000
+
+config USBDEBUG_HCD_INDEX
+ int
+ default 2
+
+config MAX_CPUS
+ int
+ default 2
+
+config CBFS_SIZE
+ hex
+ default 0x200000
+
+endif # BOARD_LENOVO_T400
diff --git a/src/mainboard/lenovo/t400/Makefile.inc b/src/mainboard/lenovo/t400/Makefile.inc
new file mode 100644
index 0000000..4eb1216
--- /dev/null
+++ b/src/mainboard/lenovo/t400/Makefile.inc
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2012 secunet Security Networks AG
+##
+## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+ramstage-y += dock.c
diff --git a/src/mainboard/lenovo/t400/acpi/dock.asl b/src/mainboard/lenovo/t400/acpi/dock.asl
new file mode 100644
index 0000000..605836b
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/dock.asl
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Scope (\_SB)
+{
+ Device(DOCK)
+ {
+ Name(_HID, "ACPI0003")
+ Name(_UID, 0x00)
+ Name(_PCL, Package() { \_SB } )
+
+ Method(_DCK, 1, NotSerialized)
+ {
+ if (Arg0) {
+ /* connect dock */
+ Store (1, \GP28)
+ Store (1, \_SB.PCI0.LPCB.EC.DKR1)
+ } else {
+ /* disconnect dock */
+ Store (0, \GP28)
+ Store (0, \_SB.PCI0.LPCB.EC.DKR1)
+ }
+ Xor(Arg0, \_SB.PCI0.LPCB.EC.DKR1, Local0)
+ Return (Local0)
+ }
+
+ Method(_STA, 0, NotSerialized)
+ {
+ Return (\_SB.PCI0.LPCB.EC.DKR1)
+ }
+ }
+}
+
+Scope(\_SB.PCI0.LPCB.EC)
+{
+ Method(_Q18, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 3)
+ }
+
+ Method(_Q45, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 3)
+ }
+
+ Method(_Q58, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 0)
+ }
+
+ Method(_Q37, 0, NotSerialized)
+ {
+ Notify(\_SB.DOCK, 0)
+ }
+}
diff --git a/src/mainboard/lenovo/t400/acpi/ec.asl b/src/mainboard/lenovo/t400/acpi/ec.asl
new file mode 100644
index 0000000..c3569e8
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/ec.asl
@@ -0,0 +1 @@
+#include <ec/lenovo/h8/acpi/ec.asl>
diff --git a/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl b/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl
new file mode 100644
index 0000000..83c7762
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/gm45_pci_irqs.asl
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* This is board specific information: IRQ routing for the
+ * gm45
+ */
+
+
+// PCI Interrupt Routing
+Method(_PRT)
+{
+ If (PICM) {
+ Return (Package() {
+ // PCIe Graphics 0:1.0
+ Package() { 0x0001ffff, 0, 0, 16 },
+ // Onboard graphics (IGD) 0:2.0
+ Package() { 0x0002ffff, 0, 0, 16 },
+ // USB and EHCI 0:1a.x
+ Package() { 0x001affff, 0, 0, 16 },
+ Package() { 0x001affff, 1, 0, 17 },
+ Package() { 0x001affff, 2, 0, 18 },
+ // High Definition Audio 0:1b.0
+ Package() { 0x001bffff, 0, 0, 16 },
+ // PCIe Root Ports 0:1c.x
+ Package() { 0x001cffff, 0, 0, 16 },
+ // USB and EHCI 0:1d.x
+ Package() { 0x001dffff, 0, 0, 16 },
+ Package() { 0x001dffff, 1, 0, 17 },
+ Package() { 0x001dffff, 2, 0, 18 },
+ // FIXME
+ // CardBus/IEEE1394 0:1e.2, 0:1e.3
+ // Package() { 0x001effff, 0, 0, 22 },
+ // Package() { 0x001effff, 1, 0, 20 },
+ // LPC device 0:1f.0
+ Package() { 0x001fffff, 0, 0, 16 },
+ Package() { 0x001fffff, 1, 0, 17 },
+ Package() { 0x001fffff, 2, 0, 18 }
+ })
+ } Else {
+ Return (Package() {
+ // PCIe Graphics 0:1.0
+ Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // Onboard graphics (IGD) 0:2.0
+ Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // USB and EHCI 0:1a.x
+ Package() { 0x001affff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x001affff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x001affff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+ // High Definition Audio 0:1b.0
+ Package() { 0x001bffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // PCIe Root Ports 0:1c.x
+ Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ // USB and EHCI 0:1d.x
+ Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x001dffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x001dffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+ // FIXME
+ // CardBus/IEEE1394 0:1e.2, 0:1e.3
+ // Package() { 0x001effff, 0, \_SB.PCI0.LPCB.LNKG, 0 },
+ // Package() { 0x001effff, 1, \_SB.PCI0.LPCB.LNKE, 0 },
+ // LPC device 0:1f.0
+ Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }
+ })
+ }
+}
+
diff --git a/src/mainboard/lenovo/t400/acpi/gpe.asl b/src/mainboard/lenovo/t400/acpi/gpe.asl
new file mode 100644
index 0000000..3120caf
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/gpe.asl
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Scope (\_GPE)
+{
+ Method(_L18, 0, NotSerialized)
+ {
+ /* Read EC register to clear wake status */
+ Store(\_SB.PCI0.LPCB.EC.WAKE, Local0)
+ }
+}
diff --git a/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl b/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl
new file mode 100644
index 0000000..325f13c
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/ich9_pci_irqs.asl
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* This is board specific information: IRQ routing for the
+ * 0:1e.0 PCI bridge of the ICH9
+ */
+
+/* TODO: which slots are actually relevant? */
+If (PICM) {
+ Return (Package() {
+ // PCI Slot 1 routes ABCD
+ Package() { 0x0000ffff, 0, 0, 16},
+ Package() { 0x0000ffff, 1, 0, 17},
+ Package() { 0x0000ffff, 2, 0, 18},
+ Package() { 0x0000ffff, 3, 0, 19},
+
+ // PCI Slot 2 routes BCDA
+ Package() { 0x0001ffff, 0, 0, 17},
+ Package() { 0x0001ffff, 1, 0, 18},
+ Package() { 0x0001ffff, 2, 0, 19},
+ Package() { 0x0001ffff, 3, 0, 16},
+
+ // PCI Slot 3 routes CDAB
+ Package() { 0x0002ffff, 0, 0, 18},
+ Package() { 0x0002ffff, 1, 0, 19},
+ Package() { 0x0002ffff, 2, 0, 16},
+ Package() { 0x0002ffff, 3, 0, 17},
+
+ // PCI Slot 4 routes ABCD
+ Package() { 0x0003ffff, 0, 0, 16},
+ Package() { 0x0003ffff, 1, 0, 17},
+ Package() { 0x0003ffff, 2, 0, 18},
+ Package() { 0x0003ffff, 3, 0, 19},
+
+ // PCI Slot 5 routes ABCD
+ Package() { 0x0004ffff, 0, 0, 16},
+ Package() { 0x0004ffff, 1, 0, 17},
+ Package() { 0x0004ffff, 2, 0, 18},
+ Package() { 0x0004ffff, 3, 0, 19},
+
+ // PCI Slot 6 routes BCDA
+ Package() { 0x0005ffff, 0, 0, 17},
+ Package() { 0x0005ffff, 1, 0, 18},
+ Package() { 0x0005ffff, 2, 0, 19},
+ Package() { 0x0005ffff, 3, 0, 16},
+
+ // FIXME: what's this supposed to mean? (adopted from ich7)
+ //Package() { 0x0008ffff, 0, 0, 20},
+ })
+} Else {
+ Return (Package() {
+ // PCI Slot 1 routes ABCD
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
+
+ // PCI Slot 2 routes BCDA
+ Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0001ffff, 1, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0001ffff, 2, \_SB.PCI0.LPCB.LNKD, 0},
+ Package() { 0x0001ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
+
+ // PCI Slot 3 routes CDAB
+ Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0002ffff, 1, \_SB.PCI0.LPCB.LNKD, 0},
+ Package() { 0x0002ffff, 2, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0002ffff, 3, \_SB.PCI0.LPCB.LNKB, 0},
+
+ // PCI Slot 4 routes ABCD
+ Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0003ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0003ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0003ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
+
+ // PCI Slot 5 routes ABCD
+ Package() { 0x0004ffff, 0, \_SB.PCI0.LPCB.LNKA, 0},
+ Package() { 0x0004ffff, 1, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0004ffff, 2, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0004ffff, 3, \_SB.PCI0.LPCB.LNKD, 0},
+
+ // PCI Slot 6 routes BCDA
+ Package() { 0x0005ffff, 0, \_SB.PCI0.LPCB.LNKB, 0},
+ Package() { 0x0005ffff, 1, \_SB.PCI0.LPCB.LNKC, 0},
+ Package() { 0x0005ffff, 2, \_SB.PCI0.LPCB.LNKD, 0},
+ Package() { 0x0005ffff, 3, \_SB.PCI0.LPCB.LNKA, 0},
+
+ // FIXME
+ // Package() { 0x0008ffff, 0, \_SB.PCI0.LPCB.LNKE, 0},
+ })
+}
+
diff --git a/src/mainboard/lenovo/t400/acpi/platform.asl b/src/mainboard/lenovo/t400/acpi/platform.asl
new file mode 100644
index 0000000..2aa556f
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi/platform.asl
@@ -0,0 +1,206 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* These come from the dynamically created CPU SSDT */
+External(PDC0)
+External(PDC1)
+
+/* The APM port can be used for generating software SMIs */
+
+OperationRegion (APMP, SystemIO, 0xb2, 2)
+Field (APMP, ByteAcc, NoLock, Preserve)
+{
+ APMC, 8, // APM command
+ APMS, 8 // APM status
+}
+
+/* Port 80 POST */
+
+OperationRegion (POST, SystemIO, 0x80, 1)
+Field (POST, ByteAcc, Lock, Preserve)
+{
+ DBG0, 8
+}
+
+/* SMI I/O Trap */
+Method(TRAP, 1, Serialized)
+{
+ Store (Arg0, SMIF) // SMI Function
+ Store (0, TRP0) // Generate trap
+ Return (SMIF) // Return value of SMI handler
+}
+
+/* The _PIC method is called by the OS to choose between interrupt
+ * routing via the i8259 interrupt controller or the APIC.
+ *
+ * _PIC is called with a parameter of 0 for i8259 configuration and
+ * with a parameter of 1 for Local Apic/IOAPIC configuration.
+ */
+
+Method(_PIC, 1)
+{
+ // Remember the OS' IRQ routing choice.
+ Store(Arg0, PICM)
+}
+
+/* The _PTS method (Prepare To Sleep) is called before the OS is
+ * entering a sleep state. The sleep state number is passed in Arg0
+ */
+
+Method(_PTS,1)
+{
+ // Call a trap so SMI can prepare for Sleep as well.
+ // TRAP(0x55)
+}
+
+/* The _WAK method is called on system wakeup */
+
+Method(_WAK,1)
+{
+ // CPU specific part
+
+ // Notify PCI Express slots in case a card
+ // was inserted while a sleep state was active.
+
+ // Are we going to S3?
+ If (LEqual(Arg0, 3)) {
+ // ..
+ }
+
+ // Are we going to S4?
+ If (LEqual(Arg0, 4)) {
+ // ..
+ }
+
+ // TODO: Windows XP SP2 P-State restore
+
+ // TODO: Return Arg0 as second value if S-Arg0 was entered
+ // before.
+
+ Return(Package(){0,0})
+}
+
+// Power notification
+
+External (\_PR_.CP00, DeviceObj)
+External (\_PR_.CP01, DeviceObj)
+
+Method (PNOT)
+{
+ If (MPEN) {
+ If(And(PDC0, 0x08)) {
+ Notify (\_PR_.CP00, 0x80) // _PPC
+
+ If (And(PDC0, 0x10)) {
+ Sleep(100)
+ Notify(\_PR_.CP00, 0x81) // _CST
+ }
+ }
+
+ If(And(PDC1, 0x08)) {
+ Notify (\_PR_.CP01, 0x80) // _PPC
+ If (And(PDC1, 0x10)) {
+ Sleep(100)
+ Notify(\_PR_.CP01, 0x81) // _CST
+ }
+ }
+
+ } Else { // UP
+ Notify (\_PR_.CP00, 0x80)
+ Sleep(0x64)
+ Notify(\_PR_.CP00, 0x81)
+ }
+
+}
+
+/* System Bus */
+
+Scope(\_SB)
+{
+ /* This method is placed on the top level, so we can make sure it's the
+ * first executed _INI method.
+ */
+ Method(_INI, 0)
+ {
+ /* The DTS data in NVS is probably not up to date.
+ * Update temperature values and make sure AP thermal
+ * interrupts can happen
+ */
+
+ // TRAP(71) // TODO
+
+ /* Determine the Operating System and save the value in OSYS.
+ * We have to do this in order to be able to work around
+ * certain windows bugs.
+ *
+ * OSYS value | Operating System
+ * -----------+------------------
+ * 2000 | Windows 2000
+ * 2001 | Windows XP(+SP1)
+ * 2002 | Windows XP SP2
+ * 2006 | Windows Vista
+ * ???? | Windows 7
+ */
+
+ /* Let's assume we're running at least Windows 2000 */
+ Store (2000, OSYS)
+
+ If (CondRefOf(_OSI, Local0)) {
+ /* Linux answers _OSI with "True" for a couple of
+ * Windows version queries. But unlike Windows it
+ * needs a Video repost, so let's determine whether
+ * we're running Linux.
+ */
+
+ If (_OSI("Linux")) {
+ Store (1, LINX)
+ }
+
+ If (_OSI("Windows 2001")) {
+ Store (2001, OSYS)
+ }
+
+ If (_OSI("Windows 2001 SP1")) {
+ Store (2001, OSYS)
+ }
+
+ If (_OSI("Windows 2001 SP2")) {
+ Store (2002, OSYS)
+ }
+
+ If (_OSI("Windows 2006")) {
+ Store (2006, OSYS)
+ }
+ }
+
+ /* And the OS workarounds start right after we know what we're
+ * running: Windows XP SP1 needs to have C-State coordination
+ * enabled in SMM.
+ */
+ If (LAnd(LEqual(OSYS, 2001), MPEN)) {
+ // TRAP(61) // TODO
+ }
+
+ /* SMM power state and C4-on-C3 settings need to be updated */
+ // TRAP(43) // TODO
+ }
+}
+
diff --git a/src/mainboard/lenovo/t400/acpi/superio.asl b/src/mainboard/lenovo/t400/acpi/superio.asl
new file mode 100644
index 0000000..e69de29
diff --git a/src/mainboard/lenovo/t400/acpi_tables.c b/src/mainboard/lenovo/t400/acpi_tables.c
new file mode 100644
index 0000000..77491dc
--- /dev/null
+++ b/src/mainboard/lenovo/t400/acpi_tables.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <arch/smp/mpspec.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include "southbridge/intel/i82801ix/nvs.h"
+void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+ memset((void *)gnvs, 0, sizeof(*gnvs));
+ gnvs->apic = 1;
+ gnvs->mpen = 1; /* Enable Multi Processing */
+
+ /* Enable both COM ports */
+ gnvs->cmap = 0x01;
+ gnvs->cmbp = 0x01;
+
+ /* IGD Displays */
+ gnvs->ndid = 0; /* Will use default of 0x00000400. */
+ gnvs->did[0] = 0x80000100;
+ gnvs->did[1] = 0x80000240;
+ gnvs->did[2] = 0x80000410;
+ gnvs->did[3] = 0x80000410;
+ gnvs->did[4] = 0x00000005;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+ /* Local APICs */
+ current = acpi_create_madt_lapics(current);
+
+ /* IOAPIC */
+ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+ 2, IO_APIC_ADDR, 0);
+
+ /* LAPIC_NMI */
+ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
+ current, 0,
+ MP_IRQ_POLARITY_HIGH |
+ MP_IRQ_TRIGGER_EDGE, 0x01);
+ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)
+ current, 1, MP_IRQ_POLARITY_HIGH |
+ MP_IRQ_TRIGGER_EDGE, 0x01);
+
+ /* INT_SRC_OVR */
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE);
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL);
+
+
+ return current;
+}
+
+unsigned long acpi_fill_slit(unsigned long current)
+{
+ // Not implemented
+ return current;
+}
+
+unsigned long acpi_fill_srat(unsigned long current)
+{
+ /* No NUMA, no SRAT */
+ return current;
+}
diff --git a/src/mainboard/lenovo/t400/board_info.txt b/src/mainboard/lenovo/t400/board_info.txt
new file mode 100644
index 0000000..60496f5
--- /dev/null
+++ b/src/mainboard/lenovo/t400/board_info.txt
@@ -0,0 +1,5 @@
+Category: laptop
+ROM package: SOIC-16
+ROM protocol: SPI
+ROM socketed: n
+Flashrom support: n
diff --git a/src/mainboard/lenovo/t400/cmos.default b/src/mainboard/lenovo/t400/cmos.default
new file mode 100644
index 0000000..1da4c7c
--- /dev/null
+++ b/src/mainboard/lenovo/t400/cmos.default
@@ -0,0 +1,15 @@
+boot_option=Fallback
+last_boot=Fallback
+baud_rate=115200
+debug_level=Spew
+volume=0x3
+first_battery=Primary
+bluetooth=Enable
+wwan=Enable
+wlan=Enable
+trackpoint=Enable
+fn_ctrl_swap=Disable
+sticky_fn=Disable
+power_management_beeps=Enable
+low_battery_beep=Enable
+sata_mode=AHCI
diff --git a/src/mainboard/lenovo/t400/cmos.layout b/src/mainboard/lenovo/t400/cmos.layout
new file mode 100644
index 0000000..57dd4d1
--- /dev/null
+++ b/src/mainboard/lenovo/t400/cmos.layout
@@ -0,0 +1,145 @@
+#
+# This file is part of the coreboot project.
+#
+# Copyright (C) 2007-2008 coresystems GmbH
+# 2012 secunet Security Networks AG
+#
+# 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., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+# -----------------------------------------------------------------
+entries
+
+# -----------------------------------------------------------------
+# Status Register A
+# -----------------------------------------------------------------
+# Status Register B
+# -----------------------------------------------------------------
+# Status Register C
+#96 4 r 0 status_c_rsvd
+#100 1 r 0 uf_flag
+#101 1 r 0 af_flag
+#102 1 r 0 pf_flag
+#103 1 r 0 irqf_flag
+# -----------------------------------------------------------------
+# Status Register D
+#104 7 r 0 status_d_rsvd
+#111 1 r 0 valid_cmos_ram
+# -----------------------------------------------------------------
+# Diagnostic Status Register
+#112 8 r 0 diag_rsvd1
+
+# -----------------------------------------------------------------
+0 120 r 0 reserved_memory
+#120 240 r 0 unused
+
+# -----------------------------------------------------------------
+# RTC_BOOT_BYTE (coreboot hardcoded)
+384 1 e 4 boot_option
+385 1 e 4 last_boot
+388 4 r 0 reboot_bits
+#390 2 r 0 unused?
+
+# -----------------------------------------------------------------
+# coreboot config options: console
+392 3 e 5 baud_rate
+395 4 e 6 debug_level
+#399 1 r 0 unused
+
+# coreboot config options: EC
+400 8 h 0 volume
+
+# coreboot config options: southbridge
+408 1 e 10 sata_mode
+
+# coreboot config options: EC
+409 1 e 9 first_battery
+410 1 e 1 bluetooth
+411 1 e 1 wwan
+412 1 e 1 wlan
+413 1 e 1 trackpoint
+414 1 e 1 fn_ctrl_swap
+415 1 e 1 sticky_fn
+
+# coreboot config options: bootloader
+416 512 s 0 boot_devices
+928 8 h 0 boot_default
+
+936 1 e 1 power_management_beeps
+937 1 e 1 low_battery_beep
+938 1 e 1 uwb
+
+# coreboot config options: northbridge
+939 3 e 11 gfx_uma_size
+
+#942 2 r 0 unused
+
+# coreboot config options: check sums
+984 16 h 0 check_sum
+#1000 24 r 0 unused
+
+# ram initialization internal data
+1024 128 r 0 read_training_results
+
+# -----------------------------------------------------------------
+
+enumerations
+
+#ID value text
+1 0 Disable
+1 1 Enable
+2 0 Enable
+2 1 Disable
+4 0 Fallback
+4 1 Normal
+5 0 115200
+5 1 57600
+5 2 38400
+5 3 19200
+5 4 9600
+5 5 4800
+5 6 2400
+5 7 1200
+6 1 Emergency
+6 2 Alert
+6 3 Critical
+6 4 Error
+6 5 Warning
+6 6 Notice
+6 7 Info
+6 8 Debug
+6 9 Spew
+7 0 Disable
+7 1 Enable
+7 2 Keep
+8 0 No
+8 1 Yes
+9 0 Secondary
+9 1 Primary
+10 0 AHCI
+10 1 Compatible
+11 0 32M
+11 1 48M
+11 2 64M
+11 3 128M
+11 5 96M
+11 6 160M
+
+# -----------------------------------------------------------------
+checksums
+
+checksum 392 983 984
+
diff --git a/src/mainboard/lenovo/t400/cstates.c b/src/mainboard/lenovo/t400/cstates.c
new file mode 100644
index 0000000..aacfc31
--- /dev/null
+++ b/src/mainboard/lenovo/t400/cstates.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/acpigen.h>
+#include <device/device.h> /* fix for i82801ix.h */
+#include <southbridge/intel/i82801ix/i82801ix.h>
+
+static acpi_cstate_t cst_entries[] = {
+ {
+ /* acpi C1 / cpu C1 */
+ 1, 0x01, 1000,
+ { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0, 0 }
+ },
+ {
+ /* acpi C2 / cpu C2 */
+ 2, 0x01, 500,
+ { ACPI_ADDRESS_SPACE_FIXED, 1, 2, { 1 }, 0x10, 0 }
+ },
+};
+
+int get_cst_entries(acpi_cstate_t **entries)
+{
+ *entries = cst_entries;
+ return ARRAY_SIZE(cst_entries);
+}
diff --git a/src/mainboard/lenovo/t400/devicetree.cb b/src/mainboard/lenovo/t400/devicetree.cb
new file mode 100644
index 0000000..cc27d25
--- /dev/null
+++ b/src/mainboard/lenovo/t400/devicetree.cb
@@ -0,0 +1,203 @@
+chip northbridge/intel/gm45
+
+ register "gfx.use_spread_spectrum_clock" = "1"
+ register "gfx.lvds_dual_channel" = "0"
+ register "gfx.link_frequency_270_mhz" = "1"
+ register "gfx.lvds_num_lanes" = "4"
+
+ device cpu_cluster 0 on
+ chip cpu/intel/socket_BGA956
+ device lapic 0 on end
+ end
+ chip cpu/intel/model_1067x
+ # Magic APIC ID to locate this chip
+ device lapic 0xACAC off end
+
+ # Enable Super LFM
+ register "slfm" = "1"
+
+ # Enable C5, C6
+ register "c5" = "1"
+ register "c6" = "1"
+ end
+ end
+
+ device domain 0 on
+ device pci 00.0 on
+ subsystemid 0x17aa 0x20e0
+ end # host bridge
+ device pci 02.0 on # VGA
+ subsystemid 0x17aa 0x20e4
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 02.1 on
+ subsystemid 0x17aa 0x20e4
+ end # Display
+ device pci 03.0 on
+ subsystemid 0x17aa 0x20e6
+ end # ME
+ device pci 03.1 off end # ME
+ device pci 03.2 off end # ME
+ device pci 03.3 off end # ME
+ chip southbridge/intel/i82801ix
+ register "pirqa_routing" = "0x0b"
+ register "pirqb_routing" = "0x0b"
+ register "pirqc_routing" = "0x0b"
+ register "pirqd_routing" = "0x0b"
+ register "pirqe_routing" = "0x80"
+ register "pirqf_routing" = "0x80"
+ register "pirqg_routing" = "0x80"
+ register "pirqh_routing" = "0x80"
+
+ register "gpi8_routing" = "2"
+ register "gpe0_en" = "0x01000000"
+ register "gpi1_routing" = "2"
+
+ # Set AHCI mode, enable ports 1 and 2.
+ register "sata_port_map" = "0x03"
+ register "sata_clock_request" = "0"
+ register "sata_traffic_monitor" = "0"
+
+ # Set c-state support
+ register "c4onc3_enable" = "0"
+ register "c5_enable" = "1"
+ register "c6_enable" = "1"
+
+ # Set thermal throttling to 75%.
+ register "throttle_duty" = "THTL_75_0"
+
+ # Enable PCIe ports 1,2,4 as slots (Mini * PCIe).
+ register "pcie_slot_implemented" = "0xb"
+ # Set power limits to 10 * 10^0 watts.
+ # Maybe we should set less for Mini PCIe.
+ register "pcie_power_limits" = "{ { 10, 0 }, { 10, 0 }, { 0, 0 }, { 10, 0 }, { 0, 0 }, { 0, 0 } }"
+ register "pcie_hotplug_map" = "{ 0, 0, 0, 1, 0, 0, 0, 0 }"
+
+ chip drivers/generic/ioapic
+ register "have_isa_interrupts" = "1"
+ register "irq_on_fsb" = "1"
+ register "enable_virtual_wire" = "1"
+ register "base" = "(void *)0xfec00000"
+ device ioapic 2 on end
+ end
+
+ device pci 19.0 on end # LAN
+ device pci 1a.0 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1a.1 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTB 0x11
+ end
+ device pci 1a.2 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTC 0x12
+ end
+ device pci 1a.7 on # EHCI
+ subsystemid 0x17aa 0x20f1
+ ioapic_irq 2 INTC 0x12
+ end
+ device pci 1b.0 on # HD Audio
+ subsystemid 0x17aa 0x20f2
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1c.0 on # PCIe Port #1
+ subsystemid 0x17aa 0x20f3 # WWAN
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1c.1 on
+ subsystemid 0x17aa 0x20f3 # WLAN
+ end # PCIe Port #2
+ device pci 1c.2 on
+ subsystemid 0x17aa 0x20f3 # UWB
+ end # PCIe Port #3
+ device pci 1c.3 on
+ subsystemid 0x17aa 0x20f3 # Expresscard
+ end # PCIe Port #4
+ device pci 1c.4 off end # PCIe Port #5
+ device pci 1c.5 off end # PCIe Port #6
+ device pci 1d.0 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1d.1 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTB 0x11
+ end
+ device pci 1d.2 on # UHCI
+ subsystemid 0x17aa 0x20f0
+ ioapic_irq 2 INTC 0x12
+ end
+ device pci 1d.7 on # EHCI
+ subsystemid 0x17aa 0x20f1
+ ioapic_irq 2 INTA 0x10
+ end
+ device pci 1e.0 on # PCI
+ subsystemid 0x17aa 0x20f4
+ end
+ device pci 1f.0 on # LPC bridge
+ subsystemid 0x17aa 0x20f5
+ chip ec/lenovo/pmh7
+ device pnp ff.1 on # dummy
+ end
+ register "backlight_enable" = "0x01"
+ register "dock_event_enable" = "0x01"
+ end
+
+ chip ec/lenovo/h8
+ device pnp ff.2 on # dummy
+ io 0x60 = 0x62
+ io 0x62 = 0x66
+ io 0x64 = 0x1600
+ io 0x66 = 0x1604
+ end
+
+ register "config0" = "0xa6"
+ register "config1" = "0x04"
+ register "config2" = "0xa0"
+ register "config3" = "0x01"
+
+ register "beepmask0" = "0xfe"
+ register "beepmask1" = "0x96"
+ register "has_power_management_beeps" = "1"
+ register "has_uwb" = "1"
+
+ register "event2_enable" = "0xff"
+ register "event3_enable" = "0xff"
+ register "event4_enable" = "0xf4"
+ register "event5_enable" = "0x3c"
+ register "event6_enable" = "0x80"
+ register "event7_enable" = "0x01"
+ register "event8_enable" = "0x01"
+ register "event9_enable" = "0xff"
+ register "eventa_enable" = "0xff"
+ register "eventb_enable" = "0xff"
+ register "eventc_enable" = "0xff"
+ register "eventd_enable" = "0xff"
+ end
+ end
+ device pci 1f.2 on # SATA/IDE 1
+ subsystemid 0x17aa 0x20f8
+ ioapic_irq 2 INTB 0x11
+ end
+ device pci 1f.3 on # SMBus
+ subsystemid 0x17aa 0x20f9
+ ioapic_irq 2 INTC 0x12
+ # eeprom, 8 virtual devices, same chip
+ chip drivers/i2c/at24rf08c
+ device i2c 54 on end
+ device i2c 55 on end
+ device i2c 56 on end
+ device i2c 57 on end
+ device i2c 5c on end
+ device i2c 5d on end
+ device i2c 5e on end
+ device i2c 5f on end
+ end
+ end
+ device pci 1f.5 off end # SATA/IDE 2
+ device pci 1f.6 off end # Thermal
+ end
+ end
+end
diff --git a/src/mainboard/lenovo/t400/dock.c b/src/mainboard/lenovo/t400/dock.c
new file mode 100644
index 0000000..6f9e953
--- /dev/null
+++ b/src/mainboard/lenovo/t400/dock.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org>
+ * Copyright (C) 2013 Vladimir Serbinenko <phcoder(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; 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define __SIMPLE_DEVICE__
+#include <console/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <delay.h>
+#include "dock.h"
+#include "southbridge/intel/i82801ix/i82801ix.h"
+#include "ec/lenovo/h8/h8.h"
+#include <ec/acpi/ec.h>
+
+#define LPC_DEV PCI_DEV(0, 0x1f, 0)
+
+void h8_mainboard_init_dock (void)
+{
+ if (dock_present()) {
+ printk(BIOS_DEBUG, "dock is connected\n");
+ dock_connect();
+ } else
+ printk(BIOS_DEBUG, "dock is not connected\n");
+}
+
+void dock_connect(void)
+{
+ u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc;
+ ec_set_bit(0x02, 0);
+ outl(inl(gpiobase + 0x0c) | (1 << 28), gpiobase + 0x0c);
+}
+
+void dock_disconnect(void)
+{
+ u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc;
+ ec_clr_bit(0x02, 0);
+ outl(inl(gpiobase + 0x0c) & ~(1 << 28), gpiobase + 0x0c);
+}
+
+int dock_present(void)
+{
+ u16 gpiobase = pci_read_config16(LPC_DEV, D31F0_GPIO_BASE) & 0xfffc;
+ u8 st = inb(gpiobase + 0x0c);
+
+ return ((st >> 2) & 7) != 7;
+}
diff --git a/src/mainboard/lenovo/t400/dock.h b/src/mainboard/lenovo/t400/dock.h
new file mode 100644
index 0000000..e888583
--- /dev/null
+++ b/src/mainboard/lenovo/t400/dock.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef THINKPAD_X200_DOCK_H
+#define THINKPAD_X200_DOCK_H
+
+extern void dock_connect(void);
+extern void dock_disconnect(void);
+extern int dock_present(void);
+#endif
diff --git a/src/mainboard/lenovo/t400/dsdt.asl b/src/mainboard/lenovo/t400/dsdt.asl
new file mode 100644
index 0000000..0409e66
--- /dev/null
+++ b/src/mainboard/lenovo/t400/dsdt.asl
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define THINKPAD_EC_GPE 17
+#define BRIGHTNESS_UP \_SB.PCI0.GFX0.LCD0.INCB
+#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.LCD0.DECB
+#define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0
+#define DISPLAY_DEVICE_2_IS_LCD_SCREEN 1
+
+DefinitionBlock(
+ "dsdt.aml",
+ "DSDT",
+ 0x03, // DSDT revision: ACPI v3.0
+ "COREv4", // OEM id
+ "COREBOOT", // OEM table id
+ 0x20090419 // OEM revision
+)
+{
+ // Some generic macros
+ #include "acpi/platform.asl"
+
+ // global NVS and variables
+ #include <southbridge/intel/i82801ix/acpi/globalnvs.asl>
+
+ // General Purpose Events
+ #include "acpi/gpe.asl"
+
+ Scope (\_SB) {
+ Device (PCI0)
+ {
+ #include <northbridge/intel/gm45/acpi/gm45.asl>
+ #include <southbridge/intel/i82801ix/acpi/ich9.asl>
+ }
+ }
+
+ /* Chipset specific sleep states */
+ #include <southbridge/intel/i82801ix/acpi/sleepstates.asl>
+
+ /* Dock support code */
+ #include "acpi/dock.asl"
+}
diff --git a/src/mainboard/lenovo/t400/fadt.c b/src/mainboard/lenovo/t400/fadt.c
new file mode 100644
index 0000000..fef9721
--- /dev/null
+++ b/src/mainboard/lenovo/t400/fadt.c
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2008 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <device/pci.h>
+#include <arch/acpi.h>
+#include <cpu/x86/smm.h>
+
+void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+ u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe;
+
+ memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+ memcpy(header->signature, "FACP", 4);
+ header->length = sizeof(acpi_fadt_t);
+ header->revision = 3;
+ memcpy(header->oem_id, OEM_ID, 6);
+ memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+ memcpy(header->asl_compiler_id, ASLC, 4);
+ header->asl_compiler_revision = 0;
+
+ fadt->firmware_ctrl = (unsigned long) facs;
+ fadt->dsdt = (unsigned long) dsdt;
+ fadt->model = 0x00;
+ fadt->preferred_pm_profile = PM_MOBILE;
+ fadt->sci_int = 0x9;
+ fadt->smi_cmd = APM_CNT;
+ fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
+ fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = APM_CNT_PST_CONTROL;
+
+ fadt->pm1a_evt_blk = pmbase;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = pmbase + 0x4;
+ fadt->pm1b_cnt_blk = 0x0;
+ fadt->pm2_cnt_blk = pmbase + 0x50;
+ fadt->pm_tmr_blk = pmbase + 0x8;
+ fadt->gpe0_blk = pmbase + 0x20;
+ fadt->gpe1_blk = 0;
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2; /* Upper word is reserved and
+ Linux complains about 32 bit. */
+ fadt->pm2_cnt_len = 1;
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 16;
+ fadt->gpe1_blk_len = 0;
+ fadt->gpe1_base = 0;
+ fadt->cst_cnt = APM_CNT_CST_CONTROL;
+ fadt->p_lvl2_lat = 1;
+ fadt->p_lvl3_lat = 0x39;
+ fadt->flush_size = 0;
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 1;
+ fadt->duty_width = 3;
+ fadt->day_alrm = 0xd;
+ fadt->mon_alrm = 0x00;
+ fadt->century = 0x32;
+ fadt->iapc_boot_arch = 0x00;
+ fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+ ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
+ ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER |
+ ACPI_FADT_PLATFORM_CLOCK;
+
+ fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
+ fadt->reset_reg.bit_width = 8;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0xcf9;
+ fadt->reset_reg.addrh = 0;
+ fadt->reset_value = 0x06;
+
+ fadt->x_firmware_ctl_l = 0; /* Set X_FIRMWARE_CTRL only if FACS is */
+ fadt->x_firmware_ctl_h = 0; /* above 4GB. If X_FIRMWARE_CTRL is set, */
+ /* then FIRMWARE_CTRL must be zero. */
+ fadt->x_dsdt_l = (unsigned long)dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = 32;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = pmbase;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 0;
+ fadt->x_pm1b_evt_blk.bit_width = 0;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = 0x0;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = 16; /* Upper word is reserved and
+ Linux complains about 32 bit. */
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 0;
+ fadt->x_pm1b_cnt_blk.bit_width = 0;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = 0x0;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = 8;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = 32;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = 128;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = pmbase + 0x20;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+ fadt->x_gpe1_blk.space_id = 0;
+ fadt->x_gpe1_blk.bit_width = 0;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = 0x0;
+ fadt->x_gpe1_blk.addrh = 0x0;
+
+ header->checksum =
+ acpi_checksum((void *) fadt, header->length);
+}
diff --git a/src/mainboard/lenovo/t400/hda_verb.c b/src/mainboard/lenovo/t400/hda_verb.c
new file mode 100644
index 0000000..c1cd542
--- /dev/null
+++ b/src/mainboard/lenovo/t400/hda_verb.c
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/azalia_device.h>
+
+const u32 cim_verb_data[] = {
+ /* coreboot specific header */
+ 0x14f15051, // Conexant CX20561 (Hermosa)
+ 0x17aa20ff, // Subsystem ID
+ 0x00000008, // Number of entries
+
+ /* Pin Widget Verb Table */
+
+ AZALIA_PIN_CFG(0, 0x16, 0x042140f0),
+ AZALIA_PIN_CFG(0, 0x17, 0x61a190f0),
+ AZALIA_PIN_CFG(0, 0x18, 0x04a190f0),
+ AZALIA_PIN_CFG(0, 0x19, 0x612140f0),
+ AZALIA_PIN_CFG(0, 0x1a, 0x901701f0),
+ AZALIA_PIN_CFG(0, 0x1b, 0x40f001f0),
+ AZALIA_PIN_CFG(0, 0x1c, 0x40f001f0),
+ AZALIA_PIN_CFG(0, 0x1d, 0x90a601f0)
+};
+
+const u32 pc_beep_verbs[] = {
+ 0x00170500, /* power up codec */
+ 0x01470500, /* power up speakers */
+ 0x01470100, /* select lout1 (input 0x0) for speakers */
+ 0x01470740, /* enable speakers output */
+ 0x00b37517, /* unmute beep (mixer's input 0x5), set amp 0dB */
+ 0x00c37100, /* unmute mixer in lout1 (lout1 input 0x1) */
+ 0x00c3b015, /* set lout1 output volume -15dB */
+ 0x0143b000, /* unmute speakers */
+};
+AZALIA_ARRAY_SIZES;
diff --git a/src/mainboard/lenovo/t400/mainboard.c b/src/mainboard/lenovo/t400/mainboard.c
new file mode 100644
index 0000000..5354834
--- /dev/null
+++ b/src/mainboard/lenovo/t400/mainboard.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <console/console.h>
+#include <drivers/intel/gma/int15.h>
+#include <pc80/keyboard.h>
+#include <ec/acpi/ec.h>
+#include <smbios.h>
+#include <string.h>
+#include <version.h>
+#include <ec/lenovo/pmh7/pmh7.h>
+#include <ec/acpi/ec.h>
+#include <ec/lenovo/h8/h8.h>
+
+#include "cstates.c" /* Include it, as the linker won't find
+ the overloaded weak function in there. */
+
+const char *smbios_mainboard_bios_version(void)
+{
+ static char *s = NULL;
+
+ /* Satisfy thinkpad_acpi. */
+ if (strlen(CONFIG_LOCALVERSION))
+ return "CBET4000 " CONFIG_LOCALVERSION;
+
+ if (s != NULL)
+ return s;
+ s = strconcat("CBET4000 ", coreboot_version);
+ return s;
+}
+
+static void mainboard_init(device_t dev)
+{
+ /* This sneaked in here, because X200 SuperIO chip isn't really
+ connected to anything and hence we don't init it.
+ */
+ pc_keyboard_init();
+}
+
+static void mainboard_enable(device_t dev)
+{
+ install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_CENTERING, GMA_INT15_BOOT_DISPLAY_DEFAULT, 2);
+
+ dev->ops->init = mainboard_init;
+}
+
+struct chip_operations mainboard_ops = {
+ .enable_dev = mainboard_enable,
+};
+
diff --git a/src/mainboard/lenovo/t400/mptable.c b/src/mainboard/lenovo/t400/mptable.c
new file mode 100644
index 0000000..f1839f0
--- /dev/null
+++ b/src/mainboard/lenovo/t400/mptable.c
@@ -0,0 +1 @@
+/* dummy file */
diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c
new file mode 100644
index 0000000..5f50f32
--- /dev/null
+++ b/src/mainboard/lenovo/t400/romstage.c
@@ -0,0 +1,205 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// __PRE_RAM__ means: use "unsigned" for device, not a struct.
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <cpu/x86/lapic.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/tsc.h>
+#include <cbmem.h>
+#include <lib.h>
+#include <pc80/mc146818rtc.h>
+#include <console/console.h>
+#include <southbridge/intel/i82801ix/i82801ix.h>
+#include <northbridge/intel/gm45/gm45.h>
+#include <cpu/intel/romstage.h>
+
+#define LPC_DEV PCI_DEV(0, 0x1f, 0)
+#define MCH_DEV PCI_DEV(0, 0, 0)
+
+static void default_southbridge_gpio_setup(void)
+{
+ outl(0x197e23fe, DEFAULT_GPIOBASE + GP_IO_USE_SEL);
+ outl(0xe1a66dfe, DEFAULT_GPIOBASE + GP_IO_SEL);
+ outl(0xe3faef3f, DEFAULT_GPIOBASE + GP_LVL);
+
+ /* Disable blink [31:0]. */
+ outl(0x00000000, DEFAULT_GPIOBASE + GPO_BLINK);
+ /* Set input inversion [31:0]. */
+ outl(0x00000102, DEFAULT_GPIOBASE + GPI_INV);
+
+ /* Enable GPIOs [60:32]. */
+ outl(0x030306f6, DEFAULT_GPIOBASE + GP_IO_USE_SEL2);
+ /* Set input/output mode [60:32] (0 == out, 1 == in). */
+ outl(0x1f55f9f1, DEFAULT_GPIOBASE + GP_IO_SEL2);
+ /* Set gpio levels [60:32]. */
+ outl(0x1dffff53, DEFAULT_GPIOBASE + GP_LVL2);
+}
+
+static void early_lpc_setup(void)
+{
+ /* Set up SuperIO LPC forwards */
+
+ /* Configure serial IRQs.*/
+ pci_write_config8(LPC_DEV, D31F0_SERIRQ_CNTL, 0xd0);
+ /* Map COMa on 0x3f8, COMb on 0x2f8. */
+ pci_write_config16(LPC_DEV, D31F0_LPC_IODEC, 0x0010);
+ pci_write_config16(LPC_DEV, D31F0_LPC_EN, 0x3f0f);
+ pci_write_config32(LPC_DEV, D31F0_GEN1_DEC, 0x7c1601);
+ pci_write_config32(LPC_DEV, D31F0_GEN2_DEC, 0xc15e1);
+ pci_write_config32(LPC_DEV, D31F0_GEN3_DEC, 0x1c1681);
+}
+
+void main(unsigned long bist)
+{
+ sysinfo_t sysinfo;
+ int s3resume = 0;
+ int cbmem_initted;
+ u16 reg16;
+
+ /* basic northbridge setup, including MMCONF BAR */
+ gm45_early_init();
+
+ if (bist == 0)
+ enable_lapic();
+
+ /* First, run everything needed for console output. */
+ i82801ix_early_init();
+ early_lpc_setup();
+ console_init();
+ printk(BIOS_DEBUG, "running main(bist = %lu)\n", bist);
+
+ reg16 = pci_read_config16(LPC_DEV, D31F0_GEN_PMCON_3);
+ pci_write_config16(LPC_DEV, D31F0_GEN_PMCON_3, reg16);
+ if ((MCHBAR16(SSKPD_MCHBAR) == 0xCAFE) && !(reg16 & (1 << 9))) {
+ printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n");
+ gm45_early_reset();
+ }
+
+ default_southbridge_gpio_setup();
+
+ /* ASPM related setting, set early by original BIOS. */
+ DMIBAR16(0x204) &= ~(3 << 10);
+
+ /* Check for S3 resume. */
+ const u32 pm1_cnt = inl(DEFAULT_PMBASE + 0x04);
+ if (((pm1_cnt >> 10) & 7) == 5) {
+#if CONFIG_HAVE_ACPI_RESUME
+ printk(BIOS_DEBUG, "Resume from S3 detected.\n");
+ s3resume = 1;
+ /* Clear SLP_TYPE. This will break stage2 but
+ * we care for that when we get there.
+ */
+ outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + 0x04);
+#else
+ printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
+#endif
+ }
+
+ /* RAM initialization */
+ enter_raminit_or_reset();
+ memset(&sysinfo, 0, sizeof(sysinfo));
+ sysinfo.spd_map[0] = 0x50;
+ sysinfo.spd_map[2] = 0x51;
+ sysinfo.enable_igd = 1;
+ sysinfo.enable_peg = 0;
+ get_gmch_info(&sysinfo);
+ raminit(&sysinfo, s3resume);
+
+ const u32 deven = pci_read_config32(MCH_DEV, D0F0_DEVEN);
+ /* Disable D4F0 (unknown signal controller). */
+ pci_write_config32(MCH_DEV, D0F0_DEVEN, deven & ~0x4000);
+
+ init_pm(&sysinfo, 0);
+
+ i82801ix_dmi_setup();
+ gm45_late_init(sysinfo.stepping);
+ i82801ix_dmi_poll_vc1();
+
+ MCHBAR16(SSKPD_MCHBAR) = 0xCAFE;
+ /* Enable ethernet. */
+ RCBA32(0x3414) &= ~0x20;
+
+ RCBA32(0x0238) = 0x00543210;
+ RCBA32(0x0240) = 0x009c0b02;
+ RCBA32(0x0244) = 0x00a20b1a;
+ RCBA32(0x0248) = 0x005402cb;
+ RCBA32(0x0254) = 0x00470966;
+ RCBA32(0x0258) = 0x00470473;
+ RCBA32(0x0260) = 0x00e90825;
+ RCBA32(0x0278) = 0x00bc0efb;
+ RCBA32(0x027c) = 0x00c00f0b;
+ RCBA32(0x0280) = 0x00670000;
+ RCBA32(0x0284) = 0x006d0000;
+ RCBA32(0x0288) = 0x00600b4e;
+ RCBA32(0x1e10) = 0x00020800;
+ RCBA32(0x1e18) = 0x36ea00a0;
+ RCBA32(0x1e80) = 0x000c0801;
+ RCBA32(0x1e84) = 0x000200f0;
+ RCBA32(0x2028) = 0x04c8f95e;
+ RCBA32(0x202c) = 0x055c095e;
+ RCBA32(0x204c) = 0x001ffc00;
+ RCBA32(0x2050) = 0x00100fff;
+ RCBA32(0x2090) = 0x37000000;
+ RCBA32(0x20b0) = 0x0c000000;
+ RCBA32(0x20d0) = 0x09000000;
+ RCBA32(0x20f0) = 0x05000000;
+ RCBA32(0x3400) = 0x0000001c;
+ RCBA32(0x3410) = 0x00100461;
+ RCBA32(0x3414) = 0x00000000;
+ RCBA32(0x341c) = 0xbf4f001f;
+ RCBA32(0x3420) = 0x00000000;
+ RCBA32(0x3430) = 0x00000001;
+
+ init_iommu();
+
+ /* FIXME: make a proper SMBUS mux support. */
+ outl(inl(DEFAULT_GPIOBASE + 0x38) & ~0x400, DEFAULT_GPIOBASE + 0x38);
+
+ cbmem_initted = !cbmem_recovery(s3resume);
+#if CONFIG_HAVE_ACPI_RESUME
+ /* If there is no high memory area, we didn't boot before, so
+ * this is not a resume. In that case we just create the cbmem toc.
+ */
+ if (s3resume && cbmem_initted) {
+ void *resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
+
+ /* copy 1MB - 64K to high tables ram_base to prevent memory corruption
+ * through stage 2. We could keep stuff like stack and heap in high tables
+ * memory completely, but that's a wonderful clean up task for another
+ * day.
+ */
+ if (resume_backup_memory)
+ memcpy(resume_backup_memory, (void *)CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
+
+ /* Magic for S3 resume */
+ pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_ACPI_S3_MAGIC);
+ } else {
+ /* Magic for S3 resume */
+ pci_write_config32(PCI_DEV(0, 0, 0), D0F0_SKPD, SKPAD_NORMAL_BOOT_MAGIC);
+ }
+#endif
+ printk(BIOS_SPEW, "exit main()\n");
+}
+
diff --git a/src/mainboard/lenovo/t400/smihandler.c b/src/mainboard/lenovo/t400/smihandler.c
new file mode 100644
index 0000000..baa038e
--- /dev/null
+++ b/src/mainboard/lenovo/t400/smihandler.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+#include <southbridge/intel/i82801ix/nvs.h>
+#include <southbridge/intel/i82801ix/i82801ix.h>
+#include <ec/acpi/ec.h>
+
+/* The southbridge SMI handler checks whether gnvs has a
+ * valid pointer before calling the trap handler
+ */
+extern global_nvs_t *gnvs;
+
+int mainboard_io_trap_handler(int smif)
+{
+ switch (smif) {
+ case 0x99:
+ printk(BIOS_DEBUG, "Sample\n");
+ gnvs->smif = 0;
+ break;
+ default:
+ return 0;
+ }
+
+ /* On success, the IO Trap Handler returns 0
+ * On failure, the IO Trap Handler returns a value != 0
+ *
+ * For now, we force the return value to 0 and log all traps to
+ * see what's going on.
+ */
+ //gnvs->smif = 0;
+ return 1;
+}
+
+void mainboard_smi_gpi(u32 gpi_sts)
+{
+ if (gpi_sts & (1 << 1)) {
+ printk(BIOS_DEBUG, "EC/SMI\n");
+ /* TODO */
+ }
+}
+
+int mainboard_smi_apmc(u8 apmc)
+{
+ switch (apmc) {
+ case APM_CNT_ACPI_ENABLE:
+ send_ec_command(0x05); /* Set_SMI_Disable */
+ send_ec_command(0xaa); /* Set_ACPI_Enable */
+ break;
+
+ case APM_CNT_ACPI_DISABLE:
+ send_ec_command(0x04); /* Set_SMI_Enable */
+ send_ec_command(0xab); /* Set_ACPI_Disable */
+ break;
+ }
+ return 0;
+}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9283
-gerrit
commit 23a5dbc3a0f93ac1b4cbce911366079c990ee6d5
Author: Julius Werner <jwerner(a)chromium.org>
Date: Wed Aug 20 15:29:56 2014 -0700
New mechanism to define SRAM/memory map with automatic bounds checking
This patch creates a new mechanism to define the static memory layout
(primarily in SRAM) for a given board, superseding the brittle mass of
Kconfigs that we were using before. The core part is a memlayout.ld file
in the mainboard directory (although boards are expected to just include
the SoC default in most cases), which is the primary linker script for
all stages (though not rmodules for now). It uses preprocessor macros
from <memlayout.h> to form a different valid linker script for all
stages while looking like a declarative, boilerplate-free map of memory
addresses to the programmer. Linker asserts will automatically guarantee
that the defined regions cannot overlap. Stages are defined with a
maximum size that will be enforced by the linker. The file serves to
both define and document the memory layout, so that the documentation
cannot go missing or out of date.
The mechanism is implemented for all boards in the ARM, ARM64 and MIPS
architectures, and should be extended onto all systems using SRAM in the
future. The CAR/XIP environment on x86 has very different requirements
and the layout is generally not as static, so it will stay like it is
and be unaffected by this patch (save for aligning some symbol names for
consistency and sharing the new common ramstage linker script include).
BUG=None
TEST=Booted normally and in recovery mode, checked suspend/resume and
the CBMEM console on Falco, Blaze (both normal and vboot2), Pinky and
Pit. Compiled Ryu, Storm and Urara, manually compared the disassemblies
with ToT and looked for red flags.
Change-Id: Ifd2276417f2036cbe9c056f17e42f051bcd20e81
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: f1e2028e7ebceeb2d71ff366150a37564595e614
Original-Change-Id: I005506add4e8fcdb74db6d5e6cb2d4cb1bd3cda5
Original-Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/213370
---
Makefile.inc | 5 +
src/arch/arm/Makefile.inc | 29 ++---
src/arch/arm/armv4/bootblock.S | 20 +---
src/arch/arm/armv7/bootblock.S | 20 +---
src/arch/arm/armv7/mmu.c | 5 +-
src/arch/arm/bootblock.ld | 60 -----------
src/arch/arm/include/arch/header.ld | 33 ++++++
src/arch/arm/include/arch/memlayout.h | 38 +++++++
src/arch/arm/include/arch/stages.h | 2 +-
src/arch/arm/ramstage.ld | 134 ------------------------
src/arch/arm/romstage.ld | 79 --------------
src/arch/arm/stages.c | 8 +-
src/arch/arm/verstage.ld | 66 ------------
src/arch/arm64/Makefile.inc | 21 ++--
src/arch/arm64/bootblock.ld | 64 -----------
src/arch/arm64/include/arch/header.ld | 32 ++++++
src/arch/arm64/include/arch/memlayout.h | 35 +++++++
src/arch/arm64/ramstage.ld | 119 ---------------------
src/arch/arm64/romstage.ld | 87 ---------------
src/arch/mips/Makefile.inc | 19 ++--
src/arch/mips/bootblock.S | 6 +-
src/arch/mips/bootblock.ld | 57 ----------
src/arch/mips/include/arch/header.ld | 32 ++++++
src/arch/mips/include/arch/memlayout.h | 31 ++++++
src/arch/mips/ramstage.ld | 121 ---------------------
src/arch/mips/romstage.ld | 72 -------------
src/arch/mips/stages.c | 2 +-
src/arch/riscv/Makefile.inc | 18 ++--
src/arch/riscv/bootblock.S | 2 +-
src/arch/riscv/bootblock.ld | 56 ----------
src/arch/riscv/include/arch/header.ld | 33 ++++++
src/arch/riscv/include/arch/memlayout.h | 31 ++++++
src/arch/riscv/include/arch/stages.h | 2 +-
src/arch/riscv/ramstage.ld | 134 ------------------------
src/arch/riscv/romstage.ld | 83 ---------------
src/arch/x86/Makefile.inc | 2 +-
src/arch/x86/boot/boot.c | 6 +-
src/arch/x86/init/romstage.ld | 8 +-
src/arch/x86/lib/c_start.S | 2 +-
src/arch/x86/ramstage.ld | 117 ++-------------------
src/console/Kconfig | 10 --
src/cpu/allwinner/a10/Kconfig | 36 -------
src/cpu/allwinner/a10/cpu.c | 3 +-
src/cpu/allwinner/a10/ram_segs.h | 3 +-
src/cpu/ti/am335x/Kconfig | 32 ------
src/cpu/ti/am335x/Makefile.inc | 10 +-
src/cpu/ti/am335x/bootblock_media.c | 6 +-
src/cpu/ti/am335x/cbmem.c | 3 +-
src/cpu/ti/am335x/header.c | 3 +-
src/cpu/ti/am335x/header.ld | 13 +--
src/cpu/ti/am335x/memlayout.ld | 42 ++++++++
src/cpu/x86/lapic/lapic_cpu_init.c | 1 +
src/cpu/x86/mp_init.c | 1 +
src/cpu/x86/smm/smm.ld | 4 +-
src/cpu/x86/smm/smm_tseg.ld | 2 +
src/include/lib.h | 5 -
src/include/memlayout.h | 105 +++++++++++++++++++
src/include/symbols.h | 76 ++++++++++++++
src/lib/Makefile.inc | 17 ++-
src/lib/bootblock.ld | 49 +++++++++
src/lib/cbfs_spi.c | 5 +-
src/lib/cbmem_console.c | 9 +-
src/lib/loaders/load_and_run_payload.c | 1 +
src/lib/ramstage.ld | 116 ++++++++++++++++++++
src/lib/rmodule.ld | 10 +-
src/lib/romstage.ld | 58 ++++++++++
src/lib/selfboot.c | 9 +-
src/mainboard/cubietech/cubieboard/Makefile.inc | 4 +
src/mainboard/cubietech/cubieboard/memlayout.ld | 36 +++++++
src/mainboard/emulation/qemu-armv7/Kconfig | 35 -------
src/mainboard/emulation/qemu-armv7/Makefile.inc | 4 +
src/mainboard/emulation/qemu-armv7/cbmem.c | 3 +-
src/mainboard/emulation/qemu-armv7/media.c | 3 +-
src/mainboard/emulation/qemu-armv7/memlayout.ld | 47 +++++++++
src/mainboard/emulation/qemu-riscv/Kconfig | 24 -----
src/mainboard/emulation/qemu-riscv/Makefile.inc | 4 +
src/mainboard/emulation/qemu-riscv/memlayout.ld | 33 ++++++
src/mainboard/google/daisy/Makefile.inc | 4 +
src/mainboard/google/daisy/mainboard.c | 14 ++-
src/mainboard/google/daisy/memlayout.ld | 1 +
src/mainboard/google/nyan/Kconfig | 8 --
src/mainboard/google/nyan/Makefile.inc | 4 +
src/mainboard/google/nyan/mainboard.c | 5 +-
src/mainboard/google/nyan/memlayout.ld | 1 +
src/mainboard/google/nyan/romstage.c | 24 +++--
src/mainboard/google/nyan_big/Kconfig | 8 --
src/mainboard/google/nyan_big/Makefile.inc | 4 +
src/mainboard/google/nyan_big/mainboard.c | 5 +-
src/mainboard/google/nyan_big/memlayout.ld | 1 +
src/mainboard/google/nyan_big/romstage.c | 24 +++--
src/mainboard/google/nyan_blaze/Kconfig | 8 --
src/mainboard/google/nyan_blaze/Makefile.inc | 5 +
src/mainboard/google/nyan_blaze/mainboard.c | 5 +-
src/mainboard/google/nyan_blaze/memlayout.ld | 1 +
src/mainboard/google/nyan_blaze/romstage.c | 24 +++--
src/mainboard/google/peach_pit/Makefile.inc | 4 +
src/mainboard/google/peach_pit/mainboard.c | 14 ++-
src/mainboard/google/peach_pit/memlayout.ld | 1 +
src/mainboard/google/rush/Makefile.inc | 4 +
src/mainboard/google/rush/memlayout.ld | 1 +
src/mainboard/google/rush_ryu/Makefile.inc | 4 +
src/mainboard/google/rush_ryu/memlayout.ld | 1 +
src/mainboard/google/storm/Kconfig | 8 --
src/mainboard/google/storm/Makefile.inc | 4 +
src/mainboard/google/storm/mainboard.c | 11 +-
src/mainboard/google/storm/memlayout.ld | 1 +
src/mainboard/google/urara/Kconfig | 4 -
src/mainboard/google/urara/Makefile.inc | 3 +
src/mainboard/google/urara/memlayout.ld | 1 +
src/mainboard/google/veyron_pinky/Kconfig | 8 --
src/mainboard/google/veyron_pinky/Makefile.inc | 5 +
src/mainboard/google/veyron_pinky/mainboard.c | 5 +-
src/mainboard/google/veyron_pinky/memlayout.ld | 1 +
src/mainboard/google/veyron_pinky/romstage.c | 19 ++--
src/mainboard/ti/beaglebone/Makefile.inc | 4 +
src/mainboard/ti/beaglebone/memlayout.ld | 1 +
src/soc/imgtec/pistachio/Kconfig | 31 ------
src/soc/imgtec/pistachio/Makefile.inc | 2 +-
src/soc/imgtec/pistachio/cbmem.c | 3 +-
src/soc/imgtec/pistachio/memlayout.ld | 38 +++++++
src/soc/nvidia/tegra124/Kconfig | 87 ---------------
src/soc/nvidia/tegra124/Makefile.inc | 2 +-
src/soc/nvidia/tegra124/bootblock_asm.S | 20 +---
src/soc/nvidia/tegra124/cbfs.c | 4 +-
src/soc/nvidia/tegra124/clock.c | 3 +-
src/soc/nvidia/tegra124/memlayout.ld | 48 +++++++++
src/soc/nvidia/tegra124/sdram.c | 3 +-
src/soc/nvidia/tegra124/soc.c | 7 +-
src/soc/nvidia/tegra124/verstage.c | 7 +-
src/soc/nvidia/tegra132/Kconfig | 44 --------
src/soc/nvidia/tegra132/Makefile.inc | 2 +-
src/soc/nvidia/tegra132/addressmap.c | 3 +-
src/soc/nvidia/tegra132/bootblock_asm.S | 14 +--
src/soc/nvidia/tegra132/cbfs.c | 4 +-
src/soc/nvidia/tegra132/memlayout.ld | 44 ++++++++
src/soc/nvidia/tegra132/romstage_asm.S | 14 +--
src/soc/nvidia/tegra132/stack.S | 18 ++--
src/soc/qualcomm/ipq806x/Kconfig | 40 -------
src/soc/qualcomm/ipq806x/Makefile.inc | 2 +-
src/soc/qualcomm/ipq806x/cbmem.c | 4 +-
src/soc/qualcomm/ipq806x/memlayout.ld | 40 +++++++
src/soc/qualcomm/ipq806x/soc.c | 7 +-
src/soc/rockchip/rk3288/Kconfig | 73 -------------
src/soc/rockchip/rk3288/media.c | 15 +--
src/soc/rockchip/rk3288/memlayout.ld | 48 +++++++++
src/soc/rockchip/rk3288/soc.h | 3 +-
src/soc/samsung/exynos5250/Kconfig | 55 ----------
src/soc/samsung/exynos5250/alternate_cbfs.c | 28 ++---
src/soc/samsung/exynos5250/alternate_cbfs.h | 12 ---
src/soc/samsung/exynos5250/cpu.h | 3 +-
src/soc/samsung/exynos5250/memlayout.ld | 46 ++++++++
src/soc/samsung/exynos5420/Kconfig | 74 -------------
src/soc/samsung/exynos5420/alternate_cbfs.c | 28 ++---
src/soc/samsung/exynos5420/alternate_cbfs.h | 12 ---
src/soc/samsung/exynos5420/cpu.h | 3 +-
src/soc/samsung/exynos5420/memlayout.ld | 49 +++++++++
src/vendorcode/google/chromeos/Makefile.inc | 2 +
src/vendorcode/google/chromeos/chromeos.c | 3 +-
src/vendorcode/google/chromeos/memlayout.h | 47 +++++++++
src/vendorcode/google/chromeos/symbols.h | 32 ++++++
src/vendorcode/google/chromeos/verstage.ld | 58 ++++++++++
src/vendorcode/google/chromeos/verstub.c | 7 +-
162 files changed, 1645 insertions(+), 2207 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index ea2553f..2544efd 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -456,6 +456,11 @@ tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/cbfstool/
# Common recipes for all stages
###########################################################################
+# loadaddr can determine the load address of a stage, which may be needed for
+# platform-specific image headers (only works *after* the stage has been built)
+loadaddr = $(shell $(OBJDUMP_$(1)) -p $(objcbfs)/$(1).debug | \
+ sed -ne '/LOAD/s/^.*vaddr 0x\([0-9a-fA-F]\{8\}\).*$$/0x\1/p')
+
# find-substr is required for stages like romstage_null and romstage_xip to
# eliminate the _* part of the string
find-substr = $(word 1,$(subst _, ,$(1)))
diff --git a/src/arch/arm/Makefile.inc b/src/arch/arm/Makefile.inc
index cd6c4a4..4b8b473 100644
--- a/src/arch/arm/Makefile.inc
+++ b/src/arch/arm/Makefile.inc
@@ -63,11 +63,9 @@ bootblock-y += memmove.S
bootblock-y += div0.c
bootblock-y += clock.c
-bootblock-y += bootblock.ld
-
-$(objcbfs)/bootblock.debug: $(obj)/arch/arm/bootblock.bootblock.ld $$(bootblock-objs) $$(VERSTAGE_LIB)
+$(objcbfs)/bootblock.debug: $$(bootblock-objs) $$(VERSTAGE_LIB)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/arm/bootblock.bootblock.ld --start-group $(bootblock-objs) --end-group
+ $(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group
endif # CONFIG_ARCH_BOOTBLOCK_ARM
@@ -75,9 +73,9 @@ endif # CONFIG_ARCH_BOOTBLOCK_ARM
# verification stage
###############################################################################
-$(objcbfs)/verstage.debug: $$(verstage-objs) $(obj)/arch/arm/verstage.verstage.ld $$(VB2_LIB)
+$(objcbfs)/verstage.debug: $$(verstage-objs) $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld $$(VB2_LIB)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_verstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/arm/verstage.verstage.ld --start-group $(verstage-objs) --end-group
+ $(LD_verstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.verstage.ld --start-group $(verstage-objs) --end-group
verstage-y += div0.c
verstage-y += eabi_compat.c
@@ -86,8 +84,6 @@ verstage-y += memcpy.S
verstage-y += memmove.S
verstage-y += stages.c
-verstage-y += verstage.ld
-
###############################################################################
# romstage
###############################################################################
@@ -107,13 +103,11 @@ rmodules_arm-y += memcpy.S
rmodules_arm-y += memmove.S
rmodules_arm-y += eabi_compat.c
-romstage-y += romstage.ld
-
VBOOT_STUB_DEPS += $(obj)/arch/arm/eabi_compat.rmodules_arm.o
-$(objcbfs)/romstage.debug: $$(romstage-objs) $(obj)/arch/arm/romstage.romstage.ld
+$(objcbfs)/romstage.debug: $$(romstage-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_romstage) -nostdlib --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/arm/romstage.romstage.ld --start-group $(romstage-objs) --end-group
+ $(LD_romstage) -nostdlib --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.romstage.ld --start-group $(filter-out %.ld,$(romstage-objs)) --end-group
endif # CONFIG_ARCH_ROMSTAGE_ARM
@@ -133,20 +127,15 @@ ramstage-y += memset.S
ramstage-y += memcpy.S
ramstage-y += memmove.S
ramstage-y += clock.c
+
rmodules_arm-y += memset.S
rmodules_arm-y += memcpy.S
rmodules_arm-y += memmove.S
rmodules_arm-y += eabi_compat.c
ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
-ramstage-y += ramstage.ld
-
-$(objcbfs)/ramstage.debug: $$(ramstage-objs) $(obj)/arch/arm/ramstage.ramstage.ld
- @printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) -nostdlib --gc-sections -o $@ -L$(obj) -T $(obj)/arch/arm/ramstage.ramstage.ld --start-group $(ramstage-objs) --end-group
-
-$(objgenerated)/ramstage.o: $(stages_o) $$(ramstage-objs)
+$(objcbfs)/ramstage.debug: $$(ramstage-objs)
@printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) -nostdlib --gc-sections -r -o $@ --start-group $(ramstage-objs) --end-group
+ $(LD_ramstage) -nostdlib --gc-sections -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.ramstage.ld --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group
endif # CONFIG_ARCH_RAMSTAGE_ARM
diff --git a/src/arch/arm/armv4/bootblock.S b/src/arch/arm/armv4/bootblock.S
index e4d4302..1a30dda 100644
--- a/src/arch/arm/armv4/bootblock.S
+++ b/src/arch/arm/armv4/bootblock.S
@@ -44,10 +44,8 @@ ENTRY(_start)
* Initialize the stack to a known value. This is used to check for
* stack overflow later in the boot process.
*/
- ldr r0, .Stack
- ldr r1, .Stack_size
- sub r0, r0, r1
- ldr r1, .Stack
+ ldr r0, =_stack
+ ldr r1, =_estack
ldr r2, =0xdeadbeef
init_stack_loop:
str r2, [r0]
@@ -57,7 +55,7 @@ init_stack_loop:
/* Set stackpointer in internal RAM to call bootblock main() */
call_bootblock:
- ldr sp, .Stack /* Set up stack pointer */
+ ldr sp, =_estack /* Set up stack pointer */
ldr r0,=0x00000000
/*
* The current design of cpu_info places the
@@ -75,15 +73,3 @@ call_bootblock:
*/
bl main
ENDPROC(_start)
-
-/* we do it this way because it's a 32-bit constant and
- * in some cases too far away to be loaded as just an offset
- * from IP
- */
-.align 2
-.Stack:
- .word CONFIG_STACK_TOP
-.align 2
-/* create this size the same way we do in coreboot_ram.ld: top-bottom */
-.Stack_size:
- .word CONFIG_STACK_TOP - CONFIG_STACK_BOTTOM
diff --git a/src/arch/arm/armv7/bootblock.S b/src/arch/arm/armv7/bootblock.S
index a15d167..b468e15 100644
--- a/src/arch/arm/armv7/bootblock.S
+++ b/src/arch/arm/armv7/bootblock.S
@@ -62,10 +62,8 @@ ENTRY(_thumb_start)
* Initialize the stack to a known value. This is used to check for
* stack overflow later in the boot process.
*/
- ldr r0, .Stack
- ldr r1, .Stack_size
- sub r0, r0, r1
- ldr r1, .Stack
+ ldr r0, =_stack
+ ldr r1, =_estack
ldr r2, =0xdeadbeef
init_stack_loop:
str r2, [r0]
@@ -75,7 +73,7 @@ init_stack_loop:
/* Set stackpointer in internal RAM to call bootblock main() */
call_bootblock:
- ldr sp, .Stack /* Set up stack pointer */
+ ldr sp, =_estack /* Set up stack pointer */
ldr r0,=0x00000000
/*
* The current design of cpu_info places the struct at the top of the
@@ -89,15 +87,3 @@ wait_for_interrupt:
wfi
mov pc, lr @ back to my caller
ENDPROC(_thumb_start)
-
-/* we do it this way because it's a 32-bit constant and
- * in some cases too far away to be loaded as just an offset
- * from IP
- */
-.align 2
-.Stack:
- .word CONFIG_STACK_TOP
-.align 2
-/* create this size the same way we do in coreboot_ram.ld: top-bottom */
-.Stack_size:
- .word CONFIG_STACK_TOP - CONFIG_STACK_BOTTOM
diff --git a/src/arch/arm/armv7/mmu.c b/src/arch/arm/armv7/mmu.c
index bd12946..e9c6815 100644
--- a/src/arch/arm/armv7/mmu.c
+++ b/src/arch/arm/armv7/mmu.c
@@ -31,6 +31,7 @@
#include <config.h>
#include <stdlib.h>
#include <stdint.h>
+#include <symbols.h>
#include <cbmem.h>
#include <console/console.h>
@@ -90,7 +91,7 @@ typedef uint32_t pmd_t;
static const unsigned int denom = 1;
#endif /* CONFIG_ARM_LPAE */
-static pmd_t *const ttb_buff = (pmd_t *)CONFIG_TTB_BUFFER;
+static pmd_t *const ttb_buff = (pmd_t *)_ttb;
/*
* mask/shift/size for pages and blocks
@@ -186,7 +187,7 @@ void mmu_config_range(unsigned long start_mb, unsigned long size_mb,
void mmu_init(void)
{
if (CONFIG_ARM_LPAE) {
- pgd_t *const pgd_buff = (pgd_t*)(CONFIG_TTB_BUFFER + 16*KiB);
+ pgd_t *const pgd_buff = (pgd_t*)(_ttb + 16*KiB);
pmd_t *pmd = ttb_buff;
int i;
diff --git a/src/arch/arm/bootblock.ld b/src/arch/arm/bootblock.ld
deleted file mode 100644
index 091e3eb..0000000
--- a/src/arch/arm/bootblock.ld
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2010 coresystems GmbH
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-ENTRY(_start)
-SECTIONS
-{
- . = CONFIG_BOOTBLOCK_BASE;
-
- .bootblock . : {
- *(.text._start);
- KEEP(*(.id));
- *(.text);
- *(.text.*);
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- *(.bss);
- *(.bss.*);
- *(.sbss);
- *(.sbss.*);
- _end = .;
- } : to_load = 0xff
-
- preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.ARM.*)
- }
-}
diff --git a/src/arch/arm/include/arch/header.ld b/src/arch/arm/include/arch/header.ld
new file mode 100644
index 0000000..2138c77
--- /dev/null
+++ b/src/arch/arm/include/arch/header.ld
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+#ifdef __BOOTBLOCK__
+ENTRY(_start)
+#else
+ENTRY(stage_entry)
+#endif
diff --git a/src/arch/arm/include/arch/memlayout.h b/src/arch/arm/include/arch/memlayout.h
new file mode 100644
index 0000000..9f5b383
--- /dev/null
+++ b/src/arch/arm/include/arch/memlayout.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __ARCH_MEMLAYOUT_H
+#define __ARCH_MEMLAYOUT_H
+
+#define TTB(addr, size) \
+ REGION(ttb, addr, size, 16K) \
+ _ = ASSERT(size >= 16K + IS_ENABLED(CONFIG_ARM_LPAE) * 32, \
+ "TTB must be 16K (+ 32 for LPAE)!");
+
+/* ARM stacks need 8-byte alignment and stay in one place through ramstage. */
+#define STACK(addr, size) REGION(stack, addr, size, 8)
+
+#define DMA_COHERENT(addr, size) \
+ REGION(dma_coherent, addr, size, (1 + IS_ENABLED(CONFIG_ARM_LPAE)) * 1M) \
+ _ = ASSERT(size % ((1 + IS_ENABLED(CONFIG_ARM_LPAE)) * 1M) == 0, \
+ "DMA coherency buffer must fit exactly in full superpages!");
+
+#endif /* __ARCH_MEMLAYOUT_H */
diff --git a/src/arch/arm/include/arch/stages.h b/src/arch/arm/include/arch/stages.h
index 39fed99..1a0dcc1 100644
--- a/src/arch/arm/include/arch/stages.h
+++ b/src/arch/arm/include/arch/stages.h
@@ -22,7 +22,7 @@
extern void main(void);
-void stage_entry(void) __attribute__((section(".text.stage_entry.arm")));
+void stage_entry(void);
void stage_exit(void *);
#endif
diff --git a/src/arch/arm/ramstage.ld b/src/arch/arm/ramstage.ld
deleted file mode 100644
index 7daa8cb..0000000
--- a/src/arch/arm/ramstage.ld
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_RAMSTAGE_BASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- * : stack
- * : heap
- */
-/*
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
-ENTRY(stage_entry)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-SECTIONS
-{
- . = CONFIG_RAMSTAGE_BASE;
- /* First we place the code and read only data (typically const declared).
- * This could theoretically be placed in rom.
- */
- .text : {
- _text = .;
- _start = .;
- *(.text.stage_entry.arm);
- *(.text);
- *(.text.*);
- . = ALIGN(16);
- _etext = .;
- } : to_load
-
- .ctors : {
- . = ALIGN(0x100);
- __CTOR_LIST__ = .;
- KEEP(*(.ctors));
- LONG(0);
- __CTOR_END__ = .;
- }
-
- .rodata : {
- _rodata = .;
- . = ALIGN(4);
- pci_drivers = . ;
- KEEP(*(.rodata.pci_driver));
- epci_drivers = . ;
- cpu_drivers = . ;
- KEEP(*(.rodata.cpu_driver));
- ecpu_drivers = . ;
- _bs_init_begin = .;
- KEEP(*(.bs_init));
- LONG(0);
- _bs_init_end = .;
- *(.rodata)
- *(.rodata.*)
- /* kevinh/Ispiri - Added an align, because the objcopy tool
- * incorrectly converts sections that are not long word aligned.
- */
- . = ALIGN(4);
-
- _erodata = .;
- }
- /* After the code we place initialized data (typically initialized
- * global variables). This gets copied into ram by startup code.
- * __data_start and __data_end shows where in ram this should be placed,
- * whereas __data_loadstart and __data_loadend shows where in rom to
- * copy from.
- */
- .data : {
- _data = .;
- *(.data)
- *(.data.*)
- _edata = .;
- }
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- * crt0.S fills between _bss and _ebss with zeroes.
- */
- .bss . : {
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- }
- _end = .;
-
- /* coreboot really "ends" here. Only heap and stack are placed after
- * this line.
- */
-
- .heap . : {
- _heap = .;
- /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
- . = CONFIG_HEAP_SIZE ;
- . = ALIGN(4);
- _eheap = .;
- }
-
- /* The ram segment. This includes all memory used by the memory
- * resident copy of coreboot, except the tables that are produced on
- * the fly, but including stack and heap.
- */
- _ram_seg = _text;
- _eram_seg = _eheap;
-
- /* The stack lives in SRAM in a different location, so keep
- * it out of ram_seg
- */
- _stack = CONFIG_STACK_BOTTOM;
- _estack = CONFIG_STACK_TOP;
-
- /* Discard the sections we don't need/want */
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.note.*)
- }
-}
diff --git a/src/arch/arm/romstage.ld b/src/arch/arm/romstage.ld
deleted file mode 100644
index d107687..0000000
--- a/src/arch/arm/romstage.ld
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_ROMSTAGE_BASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- * : stack
- * : heap
- */
-/*
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-
-ENTRY(stage_entry)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-SECTIONS
-{
- . = CONFIG_ROMSTAGE_BASE;
-
- .romtext . : {
- _start = .;
- *(.text.stage_entry.arm);
- *(.text.startup);
- *(.text);
- *(.text.*);
- } : to_load
-
- .romdata . : {
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- . = ALIGN(8);
- }
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- * crt0.S fills between _bss and _ebss with zeroes.
- */
- .bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- }
-
- _end = .;
-
- preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
-
- /* Discard the sections we don't need/want */
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
- }
-}
diff --git a/src/arch/arm/stages.c b/src/arch/arm/stages.c
index 47f13fa..11acc9b 100644
--- a/src/arch/arm/stages.c
+++ b/src/arch/arm/stages.c
@@ -22,10 +22,10 @@
* execution (bootblock entry and ramstage exit will depend on external
* loading).
*
- * Entry points must be placed at the location the previous stage jumps
- * to (the lowest address in the stage image). This is done by giving
- * stage_entry() its own section in .text and placing it first in the
- * linker script.
+ * Entry points should be set in the linker script and honored by CBFS,
+ * so text section layout shouldn't matter. Still, it doesn't hurt to put
+ * stage_entry first (which XXXstage.ld will do automatically through the
+ * .text.stage_entry section created by -ffunction-sections).
*/
#include <arch/stages.h>
diff --git a/src/arch/arm/verstage.ld b/src/arch/arm/verstage.ld
deleted file mode 100644
index 88d4bc8..0000000
--- a/src/arch/arm/verstage.ld
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_VERSTAGE_BASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-ENTRY(stage_entry)
-
-SECTIONS
-{
- . = CONFIG_VERSTAGE_BASE;
-
- .romtext . : {
- _start = .;
- *(.text.stage_entry.arm);
- *(.text.startup);
- *(.text);
- *(.text.*);
- } : to_load
-
- .romdata . : {
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- . = ALIGN(8);
- }
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- */
- .bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- }
-
- _end = .;
-
- preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
-
- /* Discard the sections we don't need/want */
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
- }
-}
diff --git a/src/arch/arm64/Makefile.inc b/src/arch/arm64/Makefile.inc
index a9fbde5..b2b627c 100644
--- a/src/arch/arm64/Makefile.inc
+++ b/src/arch/arm64/Makefile.inc
@@ -68,13 +68,11 @@ bootblock-y += ../../lib/memset.c
bootblock-y += ../../lib/memcpy.c
bootblock-y += ../../lib/memmove.c
-bootblock-y += bootblock.ld
-
# Build the bootblock
-$(objcbfs)/bootblock.debug: $(obj)/arch/arm64/bootblock.bootblock.ld $$(bootblock-objs) $(obj)/config.h
+$(objcbfs)/bootblock.debug: $$(bootblock-objs) $(obj)/config.h
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_bootblock) --gc-sections -static -o $@ -L$(obj) --start-group $(bootblock-objs) --end-group -T $(obj)/arch/arm64/bootblock.bootblock.ld
+ $(LD_bootblock) --gc-sections -static -o $@ -L$(obj) --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld
endif # CONFIG_ARCH_BOOTBLOCK_ARM64
@@ -96,8 +94,6 @@ romstage-y += ../../lib/memmove.c
romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
romstage-y += transition.c transition_asm.S
-romstage-y += romstage.ld
-
rmodules_arm64-y += ../../lib/memset.c
rmodules_arm64-y += ../../lib/memcpy.c
rmodules_arm64-y += ../../lib/memmove.c
@@ -106,9 +102,9 @@ rmodules_arm64-y += eabi_compat.c
# Build the romstage
VBOOT_STUB_DEPS += $(obj)/arch/arm/eabi_compat.rmodules_arm64.o
-$(objcbfs)/romstage.debug: $$(romstage-objs) $(obj)/arch/arm64/romstage.romstage.ld
+$(objcbfs)/romstage.debug: $$(romstage-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_romstage) -nostdlib --gc-sections -static -o $@ -L$(obj) --start-group $(romstage-objs) --end-group -T $(obj)/arch/arm64/romstage.romstage.ld
+ $(LD_romstage) -nostdlib --gc-sections -static -o $@ -L$(obj) --start-group $(filter-out %.ld,$(romstage-objs)) --end-group -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.romstage.ld
endif # CONFIG_ARCH_ROMSTAGE_ARM64
@@ -144,18 +140,13 @@ secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += ../../lib/memcmp.c
secmon-$(CONFIG_ARCH_USE_SECURE_MONITOR) += ../../lib/memcpy.c
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
-ramstage-y += ramstage.ld
ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
# Build the ramstage
-$(objcbfs)/ramstage.debug: $$(ramstage-objs) $(obj)/arch/arm64/ramstage.ramstage.ld
- @printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) -nostdlib --gc-sections -o $@ -L$(obj) --start-group $(ramstage-objs) --end-group -T $(obj)/arch/arm64/ramstage.ramstage.ld
-
-$(objgenerated)/ramstage.o: $(stages_o) $$(ramstage-objs)
+$(objcbfs)/ramstage.debug: $$(ramstage-objs)
@printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) -nostdlib --gc-sections -r -o $@ --start-group $(ramstage-objs) --end-group
+ $(LD_ramstage) -nostdlib --gc-sections -o $@ -L$(obj) --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.ramstage.ld
endif # CONFIG_ARCH_RAMSTAGE_ARM64
diff --git a/src/arch/arm64/bootblock.ld b/src/arch/arm64/bootblock.ld
deleted file mode 100644
index 98c6454..0000000
--- a/src/arch/arm64/bootblock.ld
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2010 coresystems GmbH
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
-OUTPUT_ARCH(aarch64)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-ENTRY(stage_entry)
-TARGET(binary)
-SECTIONS
-{
- . = CONFIG_BOOTBLOCK_BASE;
-
- .bootblock . : {
- *(.text.stage_entry);
- KEEP(*(.id));
- *(.text);
- *(.text.*);
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- *(.bss);
- *(.bss.*);
- *(.sbss);
- *(.sbss.*);
- } : to_load = 0xff
-
- /* arm64 chipsets need to define CONFIG_BOOTBLOCK_STACK_(TOP|BOTTOM) */
- _stack = CONFIG_BOOTBLOCK_STACK_BOTTOM;
- _estack = CONFIG_BOOTBLOCK_STACK_TOP;
-
- preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.ARM.*)
- }
-}
diff --git a/src/arch/arm64/include/arch/header.ld b/src/arch/arm64/include/arch/header.ld
new file mode 100644
index 0000000..bb32a93
--- /dev/null
+++ b/src/arch/arm64/include/arch/header.ld
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+#ifdef __BOOTBLOCK__
+TARGET(binary)
+#endif
+ENTRY(stage_entry)
diff --git a/src/arch/arm64/include/arch/memlayout.h b/src/arch/arm64/include/arch/memlayout.h
new file mode 100644
index 0000000..328156b
--- /dev/null
+++ b/src/arch/arm64/include/arch/memlayout.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __ARCH_MEMLAYOUT_H
+#define __ARCH_MEMLAYOUT_H
+
+/* TODO: add SRAM TTB region and figure out the correct size/alignment for it */
+
+/* ARM64 stacks need 16-byte alignment. The ramstage will set up its own stacks
+ * in BSS, so this is only used for the SRAM stages. */
+#ifdef __PRE_RAM__
+#define STACK(addr, size) REGION(stack, addr, size, 16)
+#else
+#define STACK(addr, size) REGION(preram_stack, addr, size, 16)
+#endif
+
+#endif /* __ARCH_MEMLAYOUT_H */
diff --git a/src/arch/arm64/ramstage.ld b/src/arch/arm64/ramstage.ld
deleted file mode 100644
index 7022e4f..0000000
--- a/src/arch/arm64/ramstage.ld
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_RAMBASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- * : stack
- * : heap
- */
-/*
- * Copyright 2013 Google Inc.
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
-ENTRY(stage_entry)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-SECTIONS
-{
- . = CONFIG_RAMSTAGE_BASE;
-
- .text : {
- _text = .;
- _start = .;
- *(.text.stage_entry);
- *(.text);
- *(.text.*);
- . = ALIGN(16);
- _etext = .;
- } : to_load
-
- .ctors : {
- . = ALIGN(0x100);
- __CTOR_LIST__ = .;
- KEEP(*(.ctors));
- LONG(0);
- LONG(0);
- __CTOR_END__ = .;
- }
-
- .rodata : {
- . = ALIGN(64);
- _rodata = .;
- console_drivers = .;
- KEEP(*(.rodata.console_drivers));
- econsole_drivers = . ;
- . = ALIGN(64);
- pci_drivers = . ;
- KEEP(*(.rodata.pci_driver));
- epci_drivers = . ;
- cpu_drivers = . ;
- KEEP(*(.rodata.cpu_driver));
- ecpu_drivers = . ;
- _bs_init_begin = .;
- KEEP(*(.bs_init));
- LONG(0);
- LONG(0);
- _bs_init_end = .;
- . = ALIGN(64);
- *(.rodata)
- *(.rodata.*)
- _erodata = .;
- }
-
- .data : {
- . = ALIGN(64);
- _data = .;
- *(.data)
- *(.data.*)
- . = ALIGN(64);
- _edata = .;
- }
-
- .bss : {
- . = ALIGN(64);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss.*)
- *(COMMON)
- . = ALIGN(64);
- _ebss = .;
- }
-
- .heap : {
- _heap = .;
- /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
- . = . + CONFIG_HEAP_SIZE ;
- . = ALIGN(64);
- _eheap = .;
- }
-
- /* The ram segment. This includes all memory used by the memory
- * resident copy of coreboot, except the tables that are produced on
- * the fly, but including stack and heap.
- */
- _ram_seg = _text;
- _eram_seg = _eheap;
-
- /* Discard the sections we don't need/want */
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.note.*)
- }
-}
diff --git a/src/arch/arm64/romstage.ld b/src/arch/arm64/romstage.ld
deleted file mode 100644
index fef2ac5..0000000
--- a/src/arch/arm64/romstage.ld
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_ROMSTAGE_BASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- * : stack
- * : heap
- */
-/*
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
-OUTPUT_ARCH(aarch64)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-ENTRY(stage_entry)
-
-SECTIONS
-{
- . = CONFIG_ROMSTAGE_BASE;
-
- .romtext . : {
- _start = .;
- *(.text.stage_entry);
- *(.text.startup);
- *(.text);
- *(.text.*);
- } : to_load
-
- .romdata . : {
- *(.rodata);
- *(.rodata.*);
- *(.machine_param);
- *(.data);
- *(.data.*);
- . = ALIGN(8);
- _erom = .;
- }
-
- __image_copy_end = .;
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- * crt0.S fills between _bss and _ebss with zeroes.
- */
- .bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- }
-
- _end = .;
-
- /* arm64 chipsets need to define CONFIG_ROMSTAGE_STACK_(TOP|BOTTOM) */
- _stack = CONFIG_ROMSTAGE_STACK_BOTTOM;
- _estack = CONFIG_ROMSTAGE_STACK_TOP;
-
- preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
-
- /* Discard the sections we don't need/want */
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
- }
-}
diff --git a/src/arch/mips/Makefile.inc b/src/arch/mips/Makefile.inc
index 969a03d..9e88ba8 100644
--- a/src/arch/mips/Makefile.inc
+++ b/src/arch/mips/Makefile.inc
@@ -43,17 +43,15 @@ bootblock-y += ../../lib/memcpy.c
bootblock-y += ../../lib/memmove.c
bootblock-y += ../../lib/memset.c
-bootblock-y += bootblock.ld
-
# Much of the assembly code is generated by the compiler, and may contain
# terms which the preprocessor will happily go on to replace. For example
# "mips" would be replaced with "1". Clear all the built in definitions to
# prevent that.
bootblock-S-ccopts += -undef
-$(objcbfs)/bootblock.debug: $(obj)/arch/mips/bootblock.bootblock.ld $$(bootblock-objs) $(obj)/config.h
+$(objcbfs)/bootblock.debug: $$(bootblock-objs) $(obj)/config.h
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/mips/bootblock.bootblock.ld --start-group $(bootblock-objs) --end-group
+ $(LD_bootblock) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group
endif # CONFIG_ARCH_BOOTBLOCK_MIPS
@@ -71,11 +69,9 @@ romstage-y += ../../lib/memcpy.c
romstage-y += ../../lib/memmove.c
romstage-y += ../../lib/memset.c
-romstage-y += romstage.ld
-
-$(objcbfs)/romstage.debug: $$(romstage-objs) $(obj)/arch/mips/romstage.romstage.ld
+$(objcbfs)/romstage.debug: $$(romstage-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_romstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/mips/romstage.romstage.ld --start-group $(romstage-objs) --end-group
+ $(LD_romstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.romstage.ld --start-group $(filter-out %.ld,$(romstage-objs)) --end-group
endif # CONFIG_ARCH_ROMSTAGE_MIPS
@@ -93,12 +89,11 @@ ramstage-y += timer.c
ramstage-y += ../../lib/memcpy.c
ramstage-y += ../../lib/memmove.c
ramstage-y += ../../lib/memset.c
-ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
-ramstage-y += ramstage.ld
+ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
-$(objcbfs)/ramstage.debug: $$(ramstage-objs) $(obj)/arch/mips/ramstage.ramstage.ld
+$(objcbfs)/ramstage.debug: $$(ramstage-objs)
@printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/mips/ramstage.ramstage.ld --start-group $(ramstage-objs) --end-group
+ $(LD_ramstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.ramstage.ld --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group
endif # CONFIG_ARCH_RAMSTAGE_MIPS
diff --git a/src/arch/mips/bootblock.S b/src/arch/mips/bootblock.S
index f369e00..8899fe0 100644
--- a/src/arch/mips/bootblock.S
+++ b/src/arch/mips/bootblock.S
@@ -19,17 +19,17 @@
.set noreorder /* Prevent assembler from "optimizing" this code. */
-.section ".start", "ax", %progbits
+.section ".text._start", "ax", %progbits
.globl _start
_start:
/* Set the stack pointer */
- li $sp, CONFIG_BOOTBLOCK_STACK_TOP
+ la $sp, _estack
/*
* Initialise the stack to a known value, used later to check for
* overflow.
*/
- li $t0, CONFIG_BOOTBLOCK_STACK_BOTTOM
+ la $t0, _stack
addi $t1, $sp, -4
li $t2, 0xdeadbeef
1: sw $t2, 0($t0)
diff --git a/src/arch/mips/bootblock.ld b/src/arch/mips/bootblock.ld
deleted file mode 100644
index 3721f85..0000000
--- a/src/arch/mips/bootblock.ld
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2010 coresystems GmbH
- * Copyright (C) 2014 Imagination Technologies
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-OUTPUT_ARCH(mips)
-
-ENTRY(_start)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE;
-
-SECTIONS
-{
- . = CONFIG_BOOTBLOCK_BASE;
-
- /* This section might be better named .setup */
- .rom : {
- _rom = .;
- *(.start);
- *(.id);
- *(.text);
- *(.text.*);
- *(.rom.text);
- *(.rom.data);
- *(.rom.data.*);
- *(.rodata.*);
- _erom = .;
- } : to_load = 0xff
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- }
-}
diff --git a/src/arch/mips/include/arch/header.ld b/src/arch/mips/include/arch/header.ld
new file mode 100644
index 0000000..0c7d7a1
--- /dev/null
+++ b/src/arch/mips/include/arch/header.ld
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_ARCH(mips)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+#ifdef __BOOTBLOCK__
+ENTRY(_start)
+#else
+ENTRY(stage_entry)
+#endif
diff --git a/src/arch/mips/include/arch/memlayout.h b/src/arch/mips/include/arch/memlayout.h
new file mode 100644
index 0000000..4cbbe1d
--- /dev/null
+++ b/src/arch/mips/include/arch/memlayout.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __ARCH_MEMLAYOUT_H
+#define __ARCH_MEMLAYOUT_H
+
+/* MIPS stacks need 8-byte alignment and stay in one place through ramstage. */
+/* TODO: Double-check that that's the correct alignment for our ABI. */
+#define STACK(addr, size) REGION(stack, addr, size, 8)
+
+/* TODO: Need to add DMA_COHERENT region like on ARM? */
+
+#endif /* __ARCH_MEMLAYOUT_H */
diff --git a/src/arch/mips/ramstage.ld b/src/arch/mips/ramstage.ld
deleted file mode 100644
index 4052444..0000000
--- a/src/arch/mips/ramstage.ld
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Imagination Technologies
- *
- * Based on src/arch/arm/ramstage.ld:
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- *
- * 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., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-OUTPUT_ARCH(mips)
-
-ENTRY(stage_entry)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-SECTIONS
-{
- . = CONFIG_SYS_SDRAM_BASE;
-
- .text : {
- _text = .;
- _start = .;
- *(.text.stage_entry.mips);
- *(.text);
- *(.text.*);
- . = ALIGN(16);
- _etext = .;
- } : to_load
-
- .ctors : {
- . = ALIGN(0x100);
- __CTOR_LIST__ = .;
- *(.ctors);
- LONG(0);
- __CTOR_END__ = .;
- }
-
- .rodata : {
- _rodata = .;
- . = ALIGN(4);
- console_drivers = .;
- KEEP(*(.rodata.console_drivers));
- econsole_drivers = . ;
- . = ALIGN(4);
- pci_drivers = . ;
- KEEP(*(.rodata.pci_driver));
- epci_drivers = . ;
- cpu_drivers = . ;
- KEEP(*(.rodata.cpu_driver));
- ecpu_drivers = . ;
- _bs_init_begin = .;
- KEEP(*(.bs_init));
- _bs_init_end = .;
- *(.rodata)
- *(.rodata.*)
- . = ALIGN(4);
- _erodata = .;
- }
-
- .data : {
- _data = .;
- *(.data)
- _edata = .;
- }
-
- /* bss will be cleared by cbfs_load_stage */
- _bss = .;
- .bss . : {
- *(.bss)
- *(.sbss)
- *(COMMON)
- }
- _ebss = .;
- _end = .;
-
- /*
- * coreboot from the perspective of the loader really "ends"
- * here. Only symbols are placed after this.
- */
-
- _heap = .;
- _eheap = . + CONFIG_HEAP_SIZE;
-
- _stack = CONFIG_STACK_BOTTOM;
- _estack = CONFIG_STACK_TOP;
-
- /*
- * The ram segment. This includes all memory used by the memory
- * resident copy of coreboot, except the tables that are produced on
- * the fly, but including stack and heap.
- */
- _ram_seg = _text;
- _eram_seg = _eheap;
-
- /* Discard the sections we don't need/want */
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.note.*)
- }
-}
diff --git a/src/arch/mips/romstage.ld b/src/arch/mips/romstage.ld
deleted file mode 100644
index 8964285..0000000
--- a/src/arch/mips/romstage.ld
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2014 Imagination Technologies
- *
- * 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., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-OUTPUT_ARCH(mips)
-
-ENTRY(stage_entry)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-preram_cbmem_console = CONFIG_CBMEM_CONSOLE_PRERAM_BASE;
-
-SECTIONS
-{
- . = CONFIG_ROMSTAGE_BASE;
-
- .romtext . : {
- _rom = .;
- _start = .;
- *(.text.stage_entry.mips);
- *(.text.startup);
- *(.text);
- } : to_load
-
- .romdata . : {
- *(.rodata);
- *(.data);
- . = ALIGN(16);
- _erom = .;
- }
-
- /* bss will be cleared by cbfs_load_stage */
- .bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.sbss)
- *(COMMON)
- }
-
- _ebss = .;
- _end = .;
-
- /* Discard the sections we don't need/want */
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
- }
-}
diff --git a/src/arch/mips/stages.c b/src/arch/mips/stages.c
index ae10594..79b2ea4 100644
--- a/src/arch/mips/stages.c
+++ b/src/arch/mips/stages.c
@@ -20,7 +20,7 @@
#include <arch/stages.h>
#include <arch/cache.h>
- __attribute__((section(".text.stage_entry.mips"))) void stage_entry(void)
+void stage_entry(void)
{
main();
}
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
index 643facf..7f55e1f 100644
--- a/src/arch/riscv/Makefile.inc
+++ b/src/arch/riscv/Makefile.inc
@@ -38,12 +38,10 @@ bootblock-y += \
$(top)/src/lib/memmove.c \
$(top)/src/lib/memset.c
-bootblock-y += bootblock.ld
-
-$(objcbfs)/bootblock.debug: $(obj)/arch/riscv/bootblock.bootblock.ld $$(bootblock-objs)
+$(objcbfs)/bootblock.debug: $$(bootblock-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
$(LD_bootblock) --gc-sections -static -o $@ -L$(obj) \
- -T $(obj)/arch/riscv/bootblock.bootblock.ld --start-group $(bootblock-objs) \
+ -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.bootblock.ld --start-group $(filter-out %.ld,$(bootblock-objs)) \
$(LIBGCC_FILE_NAME_bootblock) --end-group
endif
@@ -65,13 +63,11 @@ romstage-y += \
romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
-romstage-y += romstage.ld
-
# Build the romstage
-$(objcbfs)/romstage.debug: $$(romstage-objs) $(obj)/arch/riscv/romstage.romstage.ld
+$(objcbfs)/romstage.debug: $$(romstage-objs)
@printf " LINK $(subst $(obj)/,,$(@))\n"
- $(LD_romstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/riscv/romstage.romstage.ld --start-group $(romstage-objs) --end-group
+ $(LD_romstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.romstage.ld --start-group $(filter-out %.ld,$(romstage-objs)) --end-group
romstage-c-ccopts += $(riscv_flags)
romstage-S-ccopts += $(riscv_asm_flags)
@@ -103,15 +99,13 @@ $(eval $(call create_class_compiler,rmodules,riscv))
ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
-ramstage-y += ramstage.ld
-
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
# Build the ramstage
-$(objcbfs)/ramstage.debug: $$(ramstage-objs) $(obj)/arch/riscv/ramstage.ramstage.ld
+$(objcbfs)/ramstage.debug: $$(ramstage-objs)
@printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/arch/riscv/ramstage.ramstage.ld --start-group $(ramstage-objs) --end-group
+ $(LD_ramstage) --gc-sections -static -o $@ -L$(obj) -T $(obj)/mainboard/$(MAINBOARDDIR)/memlayout.ramstage.ld --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group
ramstage-c-ccopts += $(riscv_flags)
ramstage-S-ccopts += $(riscv_asm_flags)
diff --git a/src/arch/riscv/bootblock.S b/src/arch/riscv/bootblock.S
index 00962c4..1461a9c 100644
--- a/src/arch/riscv/bootblock.S
+++ b/src/arch/riscv/bootblock.S
@@ -21,7 +21,7 @@
// See LICENSE for license details. relating to the _start code in this file.
#include <arch/encoding.h>
-.section ".start", "ax", %progbits
+.section ".text._start", "ax", %progbits
// Maybe there's a better way.
.space 0x2000
.globl _start
diff --git a/src/arch/riscv/bootblock.ld b/src/arch/riscv/bootblock.ld
deleted file mode 100644
index e5cb851..0000000
--- a/src/arch/riscv/bootblock.ld
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2010 coresystems GmbH
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
-OUTPUT_ARCH(riscv)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-ENTRY(_start)
-SECTIONS
-{
- . = CONFIG_BOOTBLOCK_BASE;
-
- .bootblock . : {
- *(.start);
- KEEP(*(.id));
- *(.text);
- *(.text.*);
- *(.rodata);
- *(.rodata.*);
- *(.data);
- *(.data.*);
- *(.bss);
- *(.bss.*);
- *(.sbss);
- *(.sbss.*);
- } : to_load = 0xff
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- }
-}
diff --git a/src/arch/riscv/include/arch/header.ld b/src/arch/riscv/include/arch/header.ld
new file mode 100644
index 0000000..3c42099
--- /dev/null
+++ b/src/arch/riscv/include/arch/header.ld
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* We use ELF as output format. So that we can debug the code in some form. */
+OUTPUT_ARCH(riscv)
+
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
+#ifdef __BOOTBLOCK__
+ENTRY(_start)
+#else
+ENTRY(stage_entry)
+#endif
+
diff --git a/src/arch/riscv/include/arch/memlayout.h b/src/arch/riscv/include/arch/memlayout.h
new file mode 100644
index 0000000..b6f4cba
--- /dev/null
+++ b/src/arch/riscv/include/arch/memlayout.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __ARCH_MEMLAYOUT_H
+#define __ARCH_MEMLAYOUT_H
+
+/* TODO: Double-check that that's the correct alignment for our ABI. */
+#define STACK(addr, size) REGION(stack, addr, size, 8)
+
+/* TODO: Need to add DMA_COHERENT region like on ARM? */
+
+#endif /* __ARCH_MEMLAYOUT_H */
+
diff --git a/src/arch/riscv/include/arch/stages.h b/src/arch/riscv/include/arch/stages.h
index 2d1192a..3b8543d 100644
--- a/src/arch/riscv/include/arch/stages.h
+++ b/src/arch/riscv/include/arch/stages.h
@@ -22,7 +22,7 @@
extern void main(void);
-void stage_entry(void) __attribute__((section(".text.stage_entry.riscv")));
+void stage_entry(void) __attribute__((section(".text.stage_entry")));
void stage_exit(void *);
void jmp_to_elf_entry(void *entry, unsigned long buffer, unsigned long size);
diff --git a/src/arch/riscv/ramstage.ld b/src/arch/riscv/ramstage.ld
deleted file mode 100644
index 21c9638..0000000
--- a/src/arch/riscv/ramstage.ld
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_RAMBASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- * : stack
- * : heap
- */
-/*
- * Copyright 2013 Google Inc.
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
-ENTRY(stage_entry)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-SECTIONS
-{
- . = 0x100000; /*CONFIG_SYS_SDRAM_BASE;*/
- /* First we place the code and read only data (typically const declared).
- * This could theoretically be placed in rom.
- */
- .text : {
- _text = .;
- _start = .;
- *(.text.stage_entry.riscv);
- *(.text);
- *(.text.*);
- . = ALIGN(16);
- _etext = .;
- } : to_load
-
- .ctors : {
- . = ALIGN(0x100);
- __CTOR_LIST__ = .;
- *(.ctors);
- LONG(0);
- __CTOR_END__ = .;
- }
-
- .rodata : {
- _rodata = .;
- . = ALIGN(4);
- console_drivers = .;
- *(.rodata.console_drivers)
- econsole_drivers = . ;
- . = ALIGN(4);
- pci_drivers = . ;
- *(.rodata.pci_driver)
- epci_drivers = . ;
- cpu_drivers = . ;
- *(.rodata.cpu_driver)
- ecpu_drivers = . ;
- _bs_init_begin = .;
- *(.bs_init)
- LONG(0);
- _bs_init_end = .;
- *(.rodata)
- *(.rodata.*)
- /* kevinh/Ispiri - Added an align, because the objcopy tool
- * incorrectly converts sections that are not long word aligned.
- */
- . = ALIGN(4);
-
- _erodata = .;
- }
- /* After the code we place initialized data (typically initialized
- * global variables). This gets copied into ram by startup code.
- * __data_start and __data_end shows where in ram this should be placed,
- * whereas __data_loadstart and __data_loadend shows where in rom to
- * copy from.
- */
- .data : {
- _data = .;
- *(.data)
- _edata = .;
- }
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- * crt0.S fills between _bss and _ebss with zeroes.
- */
- _bss = .;
- .bss . : {
- *(.bss)
- *(.sbss)
- *(COMMON)
- }
- _ebss = .;
- _end = .;
-
- /* coreboot really "ends" here. Only heap and stack are placed after
- * this line.
- */
-
- _heap = .;
- .heap . : {
- /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
- . = CONFIG_HEAP_SIZE ;
- . = ALIGN(4);
- }
- _eheap = .;
-
- _stack = CONFIG_STACK_BOTTOM;
- _estack = CONFIG_STACK_TOP;
-
- /* The ram segment. This includes all memory used by the memory
- * resident copy of coreboot, except the tables that are produced on
- * the fly, but including stack and heap.
- */
- _ram_seg = _text;
- _eram_seg = _eheap;
-
- /* Discard the sections we don't need/want */
-
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.note.*)
- }
-}
diff --git a/src/arch/riscv/romstage.ld b/src/arch/riscv/romstage.ld
deleted file mode 100644
index e49d1c1..0000000
--- a/src/arch/riscv/romstage.ld
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Memory map:
- *
- * CONFIG_ROMSTAGE_BASE : text segment
- * : rodata segment
- * : data segment
- * : bss segment
- * : stack
- * : heap
- */
-/*
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
-/* We use ELF as output format. So that we can debug the code in some form. */
-OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
-OUTPUT_ARCH(riscv)
-
-PHDRS
-{
- to_load PT_LOAD;
-}
-
-ENTRY(stage_entry)
-
-SECTIONS
-{
- . = CONFIG_ROMSTAGE_BASE;
-
- .romtext . : {
- _start = .;
- *(.text.stage_entry.riscv);
- *(.text.startup);
- *(.text);
- *(.text.*);
- } : to_load
-
- .romdata . : {
- *(.rodata);
- *(.rodata.*);
- *(.machine_param);
- *(.data);
- *(.data.*);
- . = ALIGN(8);
- _erom = .;
- }
-
- __image_copy_end = .;
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- * crt0.S fills between _bss and _ebss with zeroes.
- */
- .bss . : {
- . = ALIGN(8);
- _bss = .;
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- _ebss = .;
- }
-
- _end = .;
-
- preram_cbmem_console = CONFIG_CONSOLE_PRERAM_BUFFER_BASE;
-
- /* Discard the sections we don't need/want */
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.comment.*)
- *(.note.*)
- *(.eh_frame);
- }
-}
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 065b777..e48913c 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -303,7 +303,7 @@ ramstage-srcs += $(src)/arch/x86/ramstage.ld
$(objcbfs)/ramstage.debug: $(objgenerated)/ramstage.o $(obj)/arch/x86/ramstage.ramstage.ld
@printf " CC $(subst $(obj)/,,$(@))\n"
- $(LD_ramstage) --gc-sections -o $@ -L$(obj) $< -T $(obj)/arch/x86/ramstage.ramstage.ld
+ $(LD_ramstage) $(CPPFLAGS) --gc-sections -o $@ -L$(obj) $< -T $(obj)/arch/x86/ramstage.ramstage.ld
endif
diff --git a/src/arch/x86/boot/boot.c b/src/arch/x86/boot/boot.c
index 08fabcf..0ff8a6c 100644
--- a/src/arch/x86/boot/boot.c
+++ b/src/arch/x86/boot/boot.c
@@ -3,6 +3,7 @@
#include <program_loading.h>
#include <ip_checksum.h>
#include <string.h>
+#include <symbols.h>
/* When the ramstage is relocatable the elf loading ensures an elf image cannot
* be loaded over the ramstage code. */
@@ -25,11 +26,10 @@ static void jmp_payload_no_bounce_buffer(void *entry)
static void jmp_payload(void *entry, unsigned long buffer, unsigned long size)
{
- extern unsigned char _ram_seg, _eram_seg;
unsigned long lb_start, lb_size;
- lb_start = (unsigned long)&_ram_seg;
- lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
+ lb_start = (unsigned long)&_program;
+ lb_size = _program_size;
printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
diff --git a/src/arch/x86/init/romstage.ld b/src/arch/x86/init/romstage.ld
index 40ed354..2ae96ac 100644
--- a/src/arch/x86/init/romstage.ld
+++ b/src/arch/x86/init/romstage.ld
@@ -60,12 +60,12 @@ SECTIONS
*(.car.global_data);
_car_data_end = .;
/* The preram cbmem console area comes last to take advantage
- * of a zero-sized array to hold the memconsole contents that
- * grows to a bound of CONFIG_CONSOLE_PRERAM_BUFFER_SIZE.
+ * of a zero-sized array to hold the memconsole contents.
* However, collisions within the cache-as-ram region cannot be
* statically checked because the cache-as-ram region usage is
* cpu/chipset dependent. */
- preram_cbmem_console = .;
+ _preram_cbmem_console = .;
+ _epreram_cbmem_console = . + 0xc00;
}
/* Global variables are not allowed in romstage
@@ -83,5 +83,5 @@ SECTIONS
*(.sbss.*)
}
- _bogus = ASSERT((SIZEOF(.car.data) + CONFIG_CONSOLE_PRERAM_BUFFER_SIZE <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
+ _bogus = ASSERT((CONFIG_DCACHE_RAM_SIZE == 0) || (SIZEOF(.car.data) + 0xc00 <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
}
diff --git a/src/arch/x86/lib/c_start.S b/src/arch/x86/lib/c_start.S
index 675a09c..dbed123 100644
--- a/src/arch/x86/lib/c_start.S
+++ b/src/arch/x86/lib/c_start.S
@@ -16,7 +16,7 @@ thread_stacks:
.space CONFIG_STACK_SIZE*CONFIG_NUM_THREADS
#endif
- .section ".textfirst", "ax", @progbits
+ .section ".text._start", "ax", @progbits
.code32
.globl _start
.globl __rmodule_entry
diff --git a/src/arch/x86/ramstage.ld b/src/arch/x86/ramstage.ld
index f765cbe..5fcbbb6 100644
--- a/src/arch/x86/ramstage.ld
+++ b/src/arch/x86/ramstage.ld
@@ -8,121 +8,18 @@
* : stack
* : heap
*/
-/*
- * Bootstrap code for the STPC Consumer
- * Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
- */
-
-/*
- * Written by Johan Rydberg, based on work by Daniel Kahlin.
- * Rewritten by Eric Biederman
- * 2005.12 yhlu add ramstage cross the vga font buffer handling
- */
-
ENTRY(_start)
+PHDRS
+{
+ to_load PT_LOAD;
+}
+
SECTIONS
{
. = CONFIG_RAMBASE;
- /* First we place the code and read only data (typically const declared).
- * This could theoretically be placed in rom.
- */
- .text : {
- _text = .;
- *(.textfirst);
- *(.text);
- *(.text.*);
- . = ALIGN(16);
- _etext = .;
- }
-
- .ctors : {
- . = ALIGN(0x100);
- __CTOR_LIST__ = .;
- KEEP(*(.ctors));
- LONG(0);
- __CTOR_END__ = .;
- }
-
- .rodata : {
- _rodata = .;
- . = ALIGN(4);
-
- /* If any changes are made to the driver start/symbols or the
- * section names the equivalent changes need to made to
- * rmodule.ld. */
- pci_drivers = . ;
- KEEP(*(.rodata.pci_driver));
- epci_drivers = . ;
- cpu_drivers = . ;
- KEEP(*(.rodata.cpu_driver));
- ecpu_drivers = . ;
- _bs_init_begin = .;
- KEEP(*(.bs_init));
- LONG(0);
- _bs_init_end = .;
-
- *(.rodata)
- *(.rodata.*)
- /* kevinh/Ispiri - Added an align, because the objcopy tool
- * incorrectly converts sections that are not long word aligned.
- */
- . = ALIGN(4);
-
- _erodata = .;
- }
- /* After the code we place initialized data (typically initialized
- * global variables). This gets copied into ram by startup code.
- * __data_start and __data_end shows where in ram this should be placed,
- * whereas __data_loadstart and __data_loadend shows where in rom to
- * copy from.
- */
- .data : {
- _data = .;
- *(.data)
- *(.data.*)
- _edata = .;
- }
-
- /* bss does not contain data, it is just a space that should be zero
- * initialized on startup. (typically uninitialized global variables)
- * crt0.S fills between _bss and _ebss with zeroes.
- */
- _bss = .;
- .bss . : {
- *(.bss)
- *(.bss.*)
- *(.sbss)
- *(.sbss.*)
- *(COMMON)
- }
- _ebss = .;
-
- _heap = .;
- .heap . : {
- /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
- . = CONFIG_HEAP_SIZE ;
- . = ALIGN(4);
- }
- _eheap = .;
-
- /* The ram segment. This includes all memory used by the memory
- * resident copy of coreboot, except the tables that are produced on
- * the fly, but including stack and heap.
- */
- _ram_seg = _text;
- _eram_seg = _eheap;
-
- /* CONFIG_RAMTOP is the upper address of cached memory (among other
- * things). We must not exceed beyond that address, there be dragons.
- */
- _bogus = ASSERT( ( _eram_seg < (CONFIG_RAMTOP)) , "Please increase CONFIG_RAMTOP");
- /* Discard the sections we don't need/want */
+ INCLUDE "lib/ramstage.ramstage.ld"
- /DISCARD/ : {
- *(.comment)
- *(.note)
- *(.note.*)
- }
+ _ = ASSERT( ( _eprogram < (CONFIG_RAMTOP)) , "Please increase CONFIG_RAMTOP");
}
diff --git a/src/console/Kconfig b/src/console/Kconfig
index 0a0e069..09cfb39 100644
--- a/src/console/Kconfig
+++ b/src/console/Kconfig
@@ -189,16 +189,6 @@ config CONSOLE_PRERAM_BUFFER_BASE
default 0xabadbeef if !CACHE_AS_RAM || LATE_CBMEM_INIT
default 0x0
-config CONSOLE_PRERAM_BUFFER_SIZE
- hex
- default 0x0 if CONSOLE_PRERAM_BUFFER_BASE = 0xabadbeef
- default 0xc00
- help
- Console is used before RAM is initialized. This is the room reserved
- in the DCACHE based RAM, SRAM, etc. to keep console output before it
- can be saved in a CBMEM buffer. 3K bytes should be enough even for
- the BIOS_SPEW level.
-
endif
config CONSOLE_QEMU_DEBUGCON
diff --git a/src/cpu/allwinner/a10/Kconfig b/src/cpu/allwinner/a10/Kconfig
index e38227b..191e45d 100644
--- a/src/cpu/allwinner/a10/Kconfig
+++ b/src/cpu/allwinner/a10/Kconfig
@@ -15,11 +15,6 @@ config CPU_SPECIFIC_OPTIONS
select BOOTBLOCK_CONSOLE
select CPU_HAS_BOOTBLOCK_INIT
-# The "eGON.BT0" header takes 32 bytes
-config BOOTBLOCK_BASE
- hex
- default 0x20
-
config BOOTBLOCK_ROM_OFFSET
hex
default 0x00
@@ -36,41 +31,10 @@ config CBFS_HEADER_ROM_OFFSET
config CBFS_ROM_OFFSET
default 0x5fc0
-# Arbitrarily chosen to be at the base of SDRAM
-config RAMSTAGE_BASE
- hex
- default SYS_SDRAM_BASE
-
-# 16 MiB above ramstage, so there is no overlap
-config ROMSTAGE_BASE
- hex
- default 0x41000000
-
-# Keep the stack in SRAM block A2.
-# SRAM blocks A1 (0-16KiB) and A2 (16KiB-32KiB) are always accessible to the
-# CPU. This gives us 32KiB of SRAM to boot with. The BROM bootloader will use up
-# to 24KiB to load our bootblock, which leaves us the area from 24KiB to 32KiB
-# to use however we see fit.
-config STACK_TOP
- hex
- default 0x00008000
-
-config STACK_BOTTOM
- hex
- default 0x00006000
-
-config STACK_SIZE
- hex
- default 0x00002000
-
## TODO Change this to some better address not overlapping bootblock when
## cbfstool supports creating header in arbitrary location.
config CBFS_HEADER_ROM_OFFSET
hex "offset of master CBFS header in ROM"
default 0x40
-config SYS_SDRAM_BASE
- hex
- default 0x40000000
-
endif # if CPU_ALLWINNER_A10
diff --git a/src/cpu/allwinner/a10/cpu.c b/src/cpu/allwinner/a10/cpu.c
index 3159f20..c2cbc2f 100644
--- a/src/cpu/allwinner/a10/cpu.c
+++ b/src/cpu/allwinner/a10/cpu.c
@@ -9,11 +9,12 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cbmem.h>
+#include <symbols.h>
static void cpu_enable_resources(struct device *dev)
{
- ram_resource(dev, 0, CONFIG_SYS_SDRAM_BASE >> 10,
+ ram_resource(dev, 0, (uintptr_t)_dram/KiB,
CONFIG_DRAM_SIZE_MB << 10);
/* TODO: Declare CBFS cache as reserved? There's no guarantee we won't
* overwrite it. It seems to stay intact, being so high in RAM
diff --git a/src/cpu/allwinner/a10/ram_segs.h b/src/cpu/allwinner/a10/ram_segs.h
index 45141fe..26944e4 100644
--- a/src/cpu/allwinner/a10/ram_segs.h
+++ b/src/cpu/allwinner/a10/ram_segs.h
@@ -6,13 +6,14 @@
*/
#include <config.h>
+#include <symbols.h>
/*
* Put CBMEM at top of RAM
*/
static inline void *a1x_get_cbmem_top(void)
{
- return (void *)CONFIG_SYS_SDRAM_BASE + (CONFIG_DRAM_SIZE_MB << 20);
+ return _dram + (CONFIG_DRAM_SIZE_MB << 20);
}
/*
diff --git a/src/cpu/ti/am335x/Kconfig b/src/cpu/ti/am335x/Kconfig
index b2c692b..c0554b8 100644
--- a/src/cpu/ti/am335x/Kconfig
+++ b/src/cpu/ti/am335x/Kconfig
@@ -12,46 +12,14 @@ config CPU_TI_AM335X
if CPU_TI_AM335X
-config BOOTBLOCK_BASE
- hex
- default 0x402f0400
-
config CBFS_ROM_OFFSET
# Calculated by BL1 + max bootblock size.
default 0x4c00
-# We need to leave a gap between the bootblock and the ROM stage so that when
-# it is "loaded" to a slightly different place in on chip memory, it doesn't
-# clobber the metadata needed to actually enter it.
-config ROMSTAGE_BASE
- hex
- default 0x402f5400
-
-# Stack may reside in either IRAM or DRAM. We will define it to live
-# at the top of IRAM for now.
-#
-# Stack grows downward, push operation stores register contents in
-# consecutive memory locations ending just below SP
-config STACK_TOP
- hex
- default 0x4030ce00
-
-config STACK_BOTTOM
- hex
- default 0x4030be00
-
-config STACK_SIZE
- hex
- default 0x1000
-
## TODO Change this to some better address not overlapping bootblock when
## cbfstool supports creating header in arbitrary location.
config CBFS_HEADER_ROM_OFFSET
hex "offset of master CBFS header in ROM"
default 0x40
-config SYS_SDRAM_BASE
- hex
- default 0x40000000
-
endif
diff --git a/src/cpu/ti/am335x/Makefile.inc b/src/cpu/ti/am335x/Makefile.inc
index 45188ce..1dbadae 100644
--- a/src/cpu/ti/am335x/Makefile.inc
+++ b/src/cpu/ti/am335x/Makefile.inc
@@ -23,14 +23,14 @@ $(eval $(call create_class_compiler,omap-header,arm))
real-target: $(obj)/MLO
-header_ld = $(src)/cpu/ti/am335x/header.ld
+header_ld = $(obj)/cpu/ti/am335x/header.omap-header.ld
get_header_size= \
$(eval omap_header_info=$(shell $(CBFSTOOL) $(1) print | grep $(2))) \
$(shell echo $$(($(word 2,$(omap_header_info)) + \
$(word 4,$(omap_header_info)))))
-$(obj)/omap-header.bin: $$(omap-header-objs) $$(header_ld) $(obj)/coreboot.rom
+$(obj)/omap-header.bin: $$(omap-header-objs) $(obj)/coreboot.rom
@printf " CC $(subst $(obj)/,,$(@))\n"
$(CC_omap-header) -nostdlib -nostartfiles -static -include $(obj)/config.h \
-Wl,--defsym,header_load_size=$(strip \
@@ -46,3 +46,9 @@ $(obj)/MLO: $(obj)/coreboot.rom $(obj)/omap-header.bin
$(Q)cat $(obj)/omap-header.bin $(obj)/coreboot.rom > $@
omap-header-y += header.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
+omap-header-y += memlayout.ld
+omap-header-y += header.ld
diff --git a/src/cpu/ti/am335x/bootblock_media.c b/src/cpu/ti/am335x/bootblock_media.c
index 553fe42..93a2d18 100644
--- a/src/cpu/ti/am335x/bootblock_media.c
+++ b/src/cpu/ti/am335x/bootblock_media.c
@@ -20,6 +20,7 @@
#include <cbfs.h>
#include <console/console.h>
#include <string.h>
+#include <symbols.h>
static int dummy_open(struct cbfs_media *media)
{
@@ -34,7 +35,7 @@ static int dummy_close(struct cbfs_media *media)
static void * on_chip_memory_map(struct cbfs_media *media, size_t offset,
size_t count)
{
- return (void *)((uintptr_t)CONFIG_BOOTBLOCK_BASE + offset);
+ return _dram + offset;
}
static void * dummy_unmap(struct cbfs_media *media, const void *address)
@@ -54,8 +55,7 @@ static size_t on_chip_memory_read(struct cbfs_media *media, void *dest,
int init_default_cbfs_media(struct cbfs_media *media)
{
struct cbfs_header *header =
- (struct cbfs_header *)((uintptr_t)CONFIG_BOOTBLOCK_BASE +
- CONFIG_CBFS_HEADER_ROM_OFFSET);
+ (struct cbfs_header *)(_dram + CONFIG_CBFS_HEADER_ROM_OFFSET);
if (CBFS_HEADER_MAGIC != ntohl(header->magic)) {
printk(BIOS_ERR, "Invalid CBFS master header at %p\n", header);
diff --git a/src/cpu/ti/am335x/cbmem.c b/src/cpu/ti/am335x/cbmem.c
index 84f88cf..af662c0 100644
--- a/src/cpu/ti/am335x/cbmem.c
+++ b/src/cpu/ti/am335x/cbmem.c
@@ -17,8 +17,9 @@
#include <stddef.h>
#include <cbmem.h>
+#include <symbols.h>
void *cbmem_top(void)
{
- return (void *)CONFIG_SYS_SDRAM_BASE + (CONFIG_DRAM_SIZE_MB << 20);
+ return _dram + (CONFIG_DRAM_SIZE_MB << 20);
}
diff --git a/src/cpu/ti/am335x/header.c b/src/cpu/ti/am335x/header.c
index 5ed943e..9fa8d68 100644
--- a/src/cpu/ti/am335x/header.c
+++ b/src/cpu/ti/am335x/header.c
@@ -20,6 +20,7 @@
#include <config.h>
#include <stddef.h>
#include <stdint.h>
+#include <symbols.h>
#include "header.h"
@@ -70,6 +71,6 @@ struct omap_image_headers headers __attribute__((section(".header"))) = {
},
.image_header = {
.size = (uintptr_t)&header_load_size,
- .destination = CONFIG_BOOTBLOCK_BASE
+ .destination = (uintptr_t)_dram
}
};
diff --git a/src/cpu/ti/am335x/header.ld b/src/cpu/ti/am335x/header.ld
index 33c10e1..559c497 100644
--- a/src/cpu/ti/am335x/header.ld
+++ b/src/cpu/ti/am335x/header.ld
@@ -21,14 +21,5 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
-TARGET(binary)
-SECTIONS
-{
- .header : {
- *(.header);
- }
-
- /DISCARD/ : {
- *(*)
- }
-}
+#define OMAP_HEADER 1
+#include "memlayout.ld"
diff --git a/src/cpu/ti/am335x/memlayout.ld b/src/cpu/ti/am335x/memlayout.ld
new file mode 100644
index 0000000..f87f000
--- /dev/null
+++ b/src/cpu/ti/am335x/memlayout.ld
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+SECTIONS
+{
+ DRAM_START(0x40000000)
+ BOOTBLOCK(0x402f0400, 20K)
+ ROMSTAGE(0x402f5400, 90K)
+ STACK(0x4030be00, 4K)
+ RAMSTAGE(0x80200000, 192K)
+
+#ifdef OMAP_HEADER
+ .header : {
+ *(.header);
+ } : to_load
+
+ /DISCARD/ : {
+ *(*)
+ }
+#endif
+}
+
diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c
index 472d6ed..d4a9884 100644
--- a/src/cpu/x86/lapic/lapic_cpu_init.c
+++ b/src/cpu/x86/lapic/lapic_cpu_init.c
@@ -27,6 +27,7 @@
#include <halt.h>
#include <lib.h>
#include <string.h>
+#include <symbols.h>
#include <console/console.h>
#include <device/device.h>
#include <device/path.h>
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c
index 3e293f6..a5bbb98 100644
--- a/src/cpu/x86/mp_init.c
+++ b/src/cpu/x86/mp_init.c
@@ -39,6 +39,7 @@
#include <lib.h>
#include <smp/atomic.h>
#include <smp/spinlock.h>
+#include <symbols.h>
#include <thread.h>
#define MAX_APIC_IDS 256
diff --git a/src/cpu/x86/smm/smm.ld b/src/cpu/x86/smm/smm.ld
index c198161..6d33fbe 100644
--- a/src/cpu/x86/smm/smm.ld
+++ b/src/cpu/x86/smm/smm.ld
@@ -11,6 +11,7 @@ SECTIONS
*/
. = 0xa0000;
.handler (.): {
+ _program = .;
/* Assembler stub */
*(.handler)
@@ -35,9 +36,10 @@ SECTIONS
*(.sbss)
*(.sbss.*)
- /* What is this? */
+ /* What is this? (Something we don't need with -fno-common.) */
*(COMMON)
. = ALIGN(4);
+ _eprogram = .;
}
/* We are using the ASEG interleaved to stuff the SMM handlers
diff --git a/src/cpu/x86/smm/smm_tseg.ld b/src/cpu/x86/smm/smm_tseg.ld
index b57461c..4dedd2c 100644
--- a/src/cpu/x86/smm/smm_tseg.ld
+++ b/src/cpu/x86/smm/smm_tseg.ld
@@ -31,6 +31,7 @@ SECTIONS
/* 16KB for the heap at 64KB */
. = 0x10000;
.heap : {
+ _program = .;
_heap = .;
. = 0x4000;
_eheap = .;
@@ -65,6 +66,7 @@ SECTIONS
. = ALIGN(4);
_smm_c_handler_end = .;
+ _eprogram = .;
}
/DISCARD/ : {
diff --git a/src/include/lib.h b/src/include/lib.h
index 0cb2c0c..aa8fe4d 100644
--- a/src/include/lib.h
+++ b/src/include/lib.h
@@ -45,11 +45,6 @@ int primitive_memtest(uintptr_t base, uintptr_t size);
/* Defined in src/lib/stack.c */
int checkstack(void *top_of_stack, int core);
-#ifndef __PRE_RAM__ // fails in bootblock compiled with romcc
-/* currently defined by a ldscript */
-extern unsigned char _estack[];
-#endif
-
/* Defined in src/lib/hexdump.c */
void hexdump(const void *memory, size_t length);
void hexdump32(char LEVEL, const void *d, size_t len);
diff --git a/src/include/memlayout.h b/src/include/memlayout.h
new file mode 100644
index 0000000..a80e03e
--- /dev/null
+++ b/src/include/memlayout.h
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __MEMLAYOUT_H
+#define __MEMLAYOUT_H
+
+#include <arch/memlayout.h>
+
+#define STR(x) #x
+
+#define SET_COUNTER(name, addr) \
+ _ = ASSERT(. <= addr, STR(name overlaps the previous region!)); \
+ . = addr;
+
+#define SYMBOL(name, addr) \
+ SET_COUNTER(name, addr) \
+ _##name = .;
+
+#define REGION(name, addr, size, expected_align) \
+ SYMBOL(name, addr) \
+ _ = ASSERT(. == ALIGN(expected_align), \
+ STR(name must be aligned to expected_align!)); \
+ SYMBOL(e##name, addr + size)
+
+/* Declare according to SRAM/DRAM ranges in SoC hardware-defined address map. */
+#define SRAM_START(addr) SYMBOL(sram, addr)
+
+#define SRAM_END(addr) SYMBOL(esram, addr)
+
+#define DRAM_START(addr) SYMBOL(dram, addr)
+
+#define PRERAM_CBMEM_CONSOLE(addr, size) \
+ REGION(preram_cbmem_console, addr, size, 4)
+
+/* Use either CBFS_CACHE (unified) or both (PRERAM|POSTRAM)_CBFS_CACHE */
+#define CBFS_CACHE(addr, size) REGION(cbfs_cache, addr, size, 4)
+
+/* TODO: This only works if you never access CBFS in romstage before RAM is up!
+ * If you need to change that assumption, you have some work ahead of you... */
+#if defined(__PRE_RAM__) && !defined(__ROMSTAGE__)
+ #define PRERAM_CBFS_CACHE(addr, size) CBFS_CACHE(addr, size)
+ #define POSTRAM_CBFS_CACHE(addr, size) \
+ REGION(unused_cbfs_cache, addr, size, 4)
+#else
+ #define PRERAM_CBFS_CACHE(addr, size) \
+ REGION(unused_cbfs_cache, addr, size, 4)
+ #define POSTRAM_CBFS_CACHE(addr, size) CBFS_CACHE(addr, size)
+#endif
+
+/* Careful: 'INCLUDE <filename>' must always be at the end of the output line */
+#ifdef __BOOTBLOCK__
+ #define BOOTBLOCK(addr, sz) \
+ SET_COUNTER(bootblock, addr) \
+ _ = ASSERT(_ebootblock - _bootblock <= sz, \
+ STR(Bootblock exceeded its allotted size! (sz))); \
+ INCLUDE "lib/bootblock.bootblock.ld"
+#else
+ #define BOOTBLOCK(addr, sz) \
+ SET_COUNTER(bootblock, addr) \
+ . += sz;
+#endif
+
+#ifdef __ROMSTAGE__
+ #define ROMSTAGE(addr, sz) \
+ SET_COUNTER(romstage, addr) \
+ _ = ASSERT(_eromstage - _romstage <= sz, \
+ STR(Romstage exceeded its allotted size! (sz))); \
+ INCLUDE "lib/romstage.romstage.ld"
+#else
+ #define ROMSTAGE(addr, sz) \
+ SET_COUNTER(romstage, addr) \
+ . += sz;
+#endif
+
+#ifdef __RAMSTAGE__
+ #define RAMSTAGE(addr, sz) \
+ SET_COUNTER(ramstage, addr) \
+ _ = ASSERT(_eramstage - _ramstage <= sz, \
+ STR(Ramstage exceeded its allotted size! (sz))); \
+ INCLUDE "lib/ramstage.ramstage.ld"
+#else
+ #define RAMSTAGE(addr, sz) \
+ SET_COUNTER(ramstage, addr) \
+ . += sz;
+#endif
+
+#endif /* __MEMLAYOUT_H */
diff --git a/src/include/symbols.h b/src/include/symbols.h
new file mode 100644
index 0000000..c343fd9
--- /dev/null
+++ b/src/include/symbols.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __SYMBOLS_H
+#define __SYMBOLS_H
+
+#include <types.h>
+
+extern u8 _sram[];
+extern u8 _esram[];
+#define _sram_size (_esram - _sram)
+
+extern u8 _dram[];
+
+extern u8 _preram_cbmem_console[];
+extern u8 _epreram_cbmem_console[];
+#define _preram_cbmem_console_size \
+ (_epreram_cbmem_console - _preram_cbmem_console)
+
+extern u8 _stack[];
+extern u8 _estack[];
+#define _stack_size (_estack - _stack)
+
+extern u8 _cbfs_cache[];
+extern u8 _ecbfs_cache[];
+#define _cbfs_cache_size (_ecbfs_cache - _cbfs_cache)
+
+extern u8 _payload[];
+extern u8 _epayload[];
+#define _payload_size (_epayload - _payload)
+
+/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */
+extern u8 _bootblock[];
+extern u8 _ebootblock[];
+#define _bootblock_size (_ebootblock - _bootblock)
+
+extern u8 _romstage[];
+extern u8 _eromstage[];
+#define _romstage_size (_eromstage - _romstage)
+
+extern u8 _ramstage[];
+extern u8 _eramstage[];
+#define _ramstage_size (_eramstage - _ramstage)
+
+/* "program" always refers to the current execution unit, except for x86 ROM. */
+extern u8 _program[];
+extern u8 _eprogram[];
+#define _program_size (_eprogram - _program)
+
+/* Arch-specific, move to <arch/symbols.h> if they become too many. */
+
+extern u8 _ttb[];
+extern u8 _ettb[];
+#define _ttb_size (_ettb - _ttb)
+
+extern u8 _dma_coherent[];
+extern u8 _edma_coherent[];
+#define _dma_coherent_size (_edma_coherent - _dma_coherent)
+
+#endif /* __SYMBOLS_H */
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 7d02934..f5b2afa 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -39,7 +39,8 @@ romstage-y += prog_ops.c
romstage-y += memchr.c
romstage-y += memcmp.c
$(foreach arch,$(ARCH_SUPPORTED),\
- $(eval rmodules_$(arch)-y += memcmp.c))
+ $(eval rmodules_$(arch)-y += memcmp.c) \
+ $(eval rmodules_$(arch)-y += rmodule.ld))
romstage-$(CONFIG_I2C_TPM) += delay.c
romstage-y += cbfs.c cbfs_core.c
@@ -122,12 +123,20 @@ ramstage-y += halt.c
smm-y += halt.c
secmon-y += halt.c
+ifneq ($(CONFIG_ARCH_X86),y)
+# X86 bootblock and romstage use custom ldscripts that are all glued together,
+# so we need to exclude it here or it would pick these up as well
+bootblock-y += bootblock.ld
+romstage-y += romstage.ld
+endif
+ramstage-y += ramstage.ld
+
ifeq ($(CONFIG_RELOCATABLE_MODULES),y)
ramstage-y += rmodule.c
romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += rmodule.c
RMODULE_LDSCRIPT := $(src)/lib/rmodule.ld
-RMODULE_LDFLAGS := -nostartfiles --gc-sections --emit-relocs -z defs -Bsymbolic -T$(RMODULE_LDSCRIPT)
+RMODULE_LDFLAGS := -nostartfiles --gc-sections --emit-relocs -z defs -Bsymbolic -T $(RMODULE_LDSCRIPT)
# rmodule_link_rules is a function that should be called with:
# (1) the object name to link
@@ -137,8 +146,8 @@ RMODULE_LDFLAGS := -nostartfiles --gc-sections --emit-relocs -z defs -Bsymbolic
# It will create the necessary Make rules to create a rmodule. The resulting
# rmdoule is named $(1).rmod
define rmodule_link
-$(strip $(1)): $(strip $(2)) $$(RMODULE_LDSCRIPT) $$(RMODTOOL)
- $$(LD_rmodules_$(4)) $$(RMODULE_LDFLAGS) --defsym=__heap_size=$(strip $(3)) -o $$@ --start-group $(strip $(2)) $$(COMPILER_RT_rmodules_$(4)) --end-group
+$(strip $(1)): $(strip $(2)) $$(COMPILER_RT_rmodules_$(4)) $(obj)/lib/rmodule.rmodules_$(4).ld | $$(RMODTOOL)
+ $$(LD_rmodules_$(4)) --gc-sections -static -T $(obj)/lib/rmodule.rmodules_$(4).ld --defsym=__heap_size=$(strip $(3)) -o $$@ --start-group $(filter-out %.ld,$(2)) --end-group
$$(NM_rmodules_$(4)) -n $$@ > $$(basename $$(a)).map
$(strip $(1)).rmod: $(strip $(1))
diff --git a/src/lib/bootblock.ld b/src/lib/bootblock.ld
new file mode 100644
index 0000000..9bd8a86
--- /dev/null
+++ b/src/lib/bootblock.ld
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file is included inside a SECTIONS block */
+
+.bootblock . : {
+ _program = .;
+ _bootblock = .;
+ *(.text._start);
+ *(.text.stage_entry);
+ KEEP(*(.id));
+ *(.text);
+ *(.text.*);
+ *(.rodata);
+ *(.rodata.*);
+ *(.data);
+ *(.data.*);
+ *(.bss);
+ *(.bss.*);
+ *(.sbss);
+ *(.sbss.*);
+ _ebootblock = .;
+ _eprogram = .;
+} : to_load = 0xff
+
+/DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.ARM.*)
+ *(.MIPS.*)
+}
diff --git a/src/lib/cbfs_spi.c b/src/lib/cbfs_spi.c
index 2b3728e..81e6ec3 100644
--- a/src/lib/cbfs_spi.c
+++ b/src/lib/cbfs_spi.c
@@ -25,6 +25,7 @@
#include <cbfs.h>
#include <spi_flash.h>
+#include <symbols.h>
/* SPI flash as CBFS media. */
struct cbfs_spi_context {
@@ -80,8 +81,8 @@ static int init_cbfs_media_context(void)
if (!spi_context.spi_flash_info)
return -1;
- spi_context.buffer.buffer = (void *)CONFIG_CBFS_CACHE_ADDRESS;
- spi_context.buffer.size = CONFIG_CBFS_CACHE_SIZE;
+ spi_context.buffer.buffer = (void *)_cbfs_cache;
+ spi_context.buffer.size = _cbfs_cache_size;
}
return 0;
diff --git a/src/lib/cbmem_console.c b/src/lib/cbmem_console.c
index 0c2722c..770c1d2 100644
--- a/src/lib/cbmem_console.c
+++ b/src/lib/cbmem_console.c
@@ -21,6 +21,7 @@
#include <console/cbmem_console.h>
#include <cbmem.h>
#include <arch/early_variables.h>
+#include <symbols.h>
#include <string.h>
/*
@@ -44,11 +45,9 @@ static void copy_console_buffer(struct cbmem_console *old_cons_p,
/*
* While running from ROM, before DRAM is initialized, some area in cache as
* ram space is used for the console buffer storage. The size and location of
- * the area are defined in the config.
+ * the area are defined by the linker script with _(e)preram_cbmem_console.
*/
-extern struct cbmem_console preram_cbmem_console;
-
#else
/*
@@ -112,8 +111,8 @@ void cbmemc_init(void)
if (IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE))
flags = 0;
- init_console_ptr(&preram_cbmem_console,
- CONFIG_CONSOLE_PRERAM_BUFFER_SIZE, flags);
+ init_console_ptr(_preram_cbmem_console,
+ _preram_cbmem_console_size, flags);
#else
/*
* Initializing before CBMEM is available, use static buffer to store
diff --git a/src/lib/loaders/load_and_run_payload.c b/src/lib/loaders/load_and_run_payload.c
index 6c42a58..0e08d88 100644
--- a/src/lib/loaders/load_and_run_payload.c
+++ b/src/lib/loaders/load_and_run_payload.c
@@ -24,6 +24,7 @@
#include <fallback.h>
#include <lib.h>
#include <program_loading.h>
+#include <symbols.h>
#include <timestamp.h>
extern const struct prog_loader_ops vboot_payload_loader;
diff --git a/src/lib/ramstage.ld b/src/lib/ramstage.ld
new file mode 100644
index 0000000..f12653e
--- /dev/null
+++ b/src/lib/ramstage.ld
@@ -0,0 +1,116 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file is included inside a SECTIONS block */
+
+/* First we place the code and read only data (typically const declared).
+ * This could theoretically be placed in rom.
+ */
+.text : {
+ _program = .;
+ _ramstage = .;
+ _text = .;
+ *(.text._start);
+ *(.text.stage_entry);
+ *(.text);
+ *(.text.*);
+ . = ALIGN(16);
+ _etext = .;
+} : to_load
+
+#ifdef CONFIG_COVERAGE
+.ctors : {
+ . = ALIGN(0x100);
+ __CTOR_LIST__ = .;
+ KEEP(*(.ctors));
+ LONG(0);
+ LONG(0);
+ __CTOR_END__ = .;
+}
+#endif
+
+/* TODO: align data sections to cache lines? (is that really useful?) */
+.rodata : {
+ _rodata = .;
+ . = ALIGN(8);
+
+ /* If any changes are made to the driver start/symbols or the
+ * section names the equivalent changes need to made to
+ * rmodule.ld. */
+ console_drivers = .;
+ KEEP(*(.rodata.console_drivers));
+ econsole_drivers = . ;
+ . = ALIGN(8);
+ pci_drivers = . ;
+ KEEP(*(.rodata.pci_driver));
+ epci_drivers = . ;
+ cpu_drivers = . ;
+ KEEP(*(.rodata.cpu_driver));
+ ecpu_drivers = . ;
+ _bs_init_begin = .;
+ KEEP(*(.bs_init));
+ LONG(0);
+ LONG(0);
+ _bs_init_end = .;
+
+ *(.rodata)
+ *(.rodata.*)
+ /* kevinh/Ispiri - Added an align, because the objcopy tool
+ * incorrectly converts sections that are not long word aligned.
+ */
+ . = ALIGN(8);
+
+ _erodata = .;
+}
+
+.data : {
+ /* Move to different cache line to avoid false sharing with .rodata. */
+ . = ALIGN(64); /* May not be actual line size, not that important. */
+ _data = .;
+ *(.data)
+ *(.data.*)
+ _edata = .;
+}
+
+.bss . : {
+ _bss = .;
+ *(.bss)
+ *(.bss.*)
+ *(.sbss)
+ *(.sbss.*)
+ _ebss = .;
+}
+
+.heap . : {
+ _heap = .;
+ /* Reserve CONFIG_HEAP_SIZE bytes for the heap */
+ . += CONFIG_HEAP_SIZE ;
+ . = ALIGN(4);
+ _eheap = .;
+ _eramstage = .;
+ _eprogram = .;
+}
+
+/* Discard the sections we don't need/want */
+
+/DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.note.*)
+}
diff --git a/src/lib/rmodule.ld b/src/lib/rmodule.ld
index 065b5b6..70a2d3d 100644
--- a/src/lib/rmodule.ld
+++ b/src/lib/rmodule.ld
@@ -22,18 +22,21 @@ SECTIONS
.payload : {
/* C code of the module. */
- _ram_seg = .;
- *(.textfirst);
+ _program = .;
+ *(.text._start);
+ *(.text.stage_entry);
*(.text);
*(.text.*);
/* C read-only data. */
. = ALIGN(16);
+#ifdef CONFIG_COVERAGE
__CTOR_LIST__ = .;
*(.ctors);
LONG(0);
LONG(0);
__CTOR_END__ = .;
+#endif
/* The driver sections are to allow linking coreboot's
* ramstage with the rmodule linker. Any changes made in
@@ -68,6 +71,7 @@ SECTIONS
. = ALIGN(8);
/* Data section. */
+ . = ALIGN(64); /* Mirror cache line alignment from ramstage. */
_sdata = .;
*(.data);
*(.data.*);
@@ -95,7 +99,7 @@ SECTIONS
_heap = .;
. = . + __heap_size;
_eheap = .;
- _eram_seg = .;
+ _eprogram = .;
}
/DISCARD/ : {
diff --git a/src/lib/romstage.ld b/src/lib/romstage.ld
new file mode 100644
index 0000000..c3a2643
--- /dev/null
+++ b/src/lib/romstage.ld
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file is included inside a SECTIONS block */
+
+.text . : {
+ _program = .;
+ _romstage = .;
+ *(.text._start);
+ *(.text.stage_entry);
+ *(.text);
+ *(.text.*);
+} : to_load
+
+.data . : {
+ *(.rodata);
+ *(.rodata.*);
+ *(.data);
+ *(.data.*);
+ . = ALIGN(8);
+}
+
+.bss . : {
+ . = ALIGN(8);
+ _bss = .;
+ *(.bss)
+ *(.bss.*)
+ *(.sbss)
+ *(.sbss.*)
+ _ebss = .;
+ _eromstage = .;
+ _eprogram = .;
+}
+
+/* Discard the sections we don't need/want */
+/DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.eh_frame);
+}
diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c
index bd4c169..d73b3f5 100644
--- a/src/lib/selfboot.c
+++ b/src/lib/selfboot.c
@@ -24,17 +24,14 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <symbols.h>
#include <cbfs.h>
#include <lib.h>
#include <bootmem.h>
#include <program_loading.h>
-/* from ramstage.ld: */
-extern unsigned char _ram_seg;
-extern unsigned char _eram_seg;
-
-static const unsigned long lb_start = (unsigned long)&_ram_seg;
-static const unsigned long lb_end = (unsigned long)&_eram_seg;
+static const unsigned long lb_start = (unsigned long)&_program;
+static const unsigned long lb_end = (unsigned long)&_eprogram;
struct segment {
struct segment *next;
diff --git a/src/mainboard/cubietech/cubieboard/Makefile.inc b/src/mainboard/cubietech/cubieboard/Makefile.inc
index 9bd0173..f3a6de2 100644
--- a/src/mainboard/cubietech/cubieboard/Makefile.inc
+++ b/src/mainboard/cubietech/cubieboard/Makefile.inc
@@ -1,2 +1,6 @@
bootblock-y += bootblock.c
romstage-y += romstage.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/cubietech/cubieboard/memlayout.ld b/src/mainboard/cubietech/cubieboard/memlayout.ld
new file mode 100644
index 0000000..ee3674d
--- /dev/null
+++ b/src/mainboard/cubietech/cubieboard/memlayout.ld
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 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; 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+SECTIONS
+{
+ SRAM_START(0x0)
+ /* eGON.BT0: 32 bytes */
+ BOOTBLOCK(0x20, 0x5fa0)
+ STACK(0x6000, 8K)
+ SRAM_END(0x8000)
+
+ DRAM_START(0x40000000)
+ RAMSTAGE(0x40000000, 16M)
+ ROMSTAGE(0x41000000, 108K)
+}
+
diff --git a/src/mainboard/emulation/qemu-armv7/Kconfig b/src/mainboard/emulation/qemu-armv7/Kconfig
index b275e88..c0e7095 100644
--- a/src/mainboard/emulation/qemu-armv7/Kconfig
+++ b/src/mainboard/emulation/qemu-armv7/Kconfig
@@ -49,45 +49,10 @@ config MAINBOARD_VENDOR
string
default "ARM Ltd."
-config SYS_SDRAM_BASE
- hex "SDRAM base address"
- default 0x01000000
-
config DRAM_SIZE_MB
int
default 1024
-# Memory map for qemu vexpress-a9:
-#
-# 0x0000_0000: jump instruction (by qemu)
-# 0x0001_0000: bootblock (entry of kernel / firmware)
-# 0x0002_0000: romstage, assume up to 128KB in size.
-# 0x0007_ff00: stack pointer
-# 0x0010_0000: CBFS header
-# 0x0011_0000: CBFS data
-# 0x0100_0000: reserved for ramstage
-# 0x1000_0000: I/O map address
-#
-config STACK_TOP
- hex
- default 0x00100000
-
-config STACK_BOTTOM
- hex
- default 0x0007FF00
-
-config BOOTBLOCK_BASE
- hex
- default 0x00010000
-
-config ROMSTAGE_BASE
- hex
- default 0x00020000
-
-config RAMSTAGE_BASE
- hex
- default SYS_SDRAM_BASE
-
config BOOTBLOCK_ROM_OFFSET
hex
default 0x0
diff --git a/src/mainboard/emulation/qemu-armv7/Makefile.inc b/src/mainboard/emulation/qemu-armv7/Makefile.inc
index 4119f93..d5742e1 100644
--- a/src/mainboard/emulation/qemu-armv7/Makefile.inc
+++ b/src/mainboard/emulation/qemu-armv7/Makefile.inc
@@ -28,3 +28,7 @@ ramstage-y += timer.c
bootblock-y += mmio.c
romstage-y += mmio.c
ramstage-y += mmio.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/emulation/qemu-armv7/cbmem.c b/src/mainboard/emulation/qemu-armv7/cbmem.c
index 84f88cf..af662c0 100644
--- a/src/mainboard/emulation/qemu-armv7/cbmem.c
+++ b/src/mainboard/emulation/qemu-armv7/cbmem.c
@@ -17,8 +17,9 @@
#include <stddef.h>
#include <cbmem.h>
+#include <symbols.h>
void *cbmem_top(void)
{
- return (void *)CONFIG_SYS_SDRAM_BASE + (CONFIG_DRAM_SIZE_MB << 20);
+ return _dram + (CONFIG_DRAM_SIZE_MB << 20);
}
diff --git a/src/mainboard/emulation/qemu-armv7/media.c b/src/mainboard/emulation/qemu-armv7/media.c
index 1168881..c3760ab 100644
--- a/src/mainboard/emulation/qemu-armv7/media.c
+++ b/src/mainboard/emulation/qemu-armv7/media.c
@@ -14,6 +14,7 @@
*/
#include <cbfs.h>
#include <string.h>
+#include <symbols.h>
#include <console/console.h>
/* Simple memory-mapped ROM emulation. */
@@ -25,7 +26,7 @@ static int emu_rom_open(struct cbfs_media *media)
static void *emu_rom_map(struct cbfs_media *media, size_t offset, size_t count)
{
- return (void*)(offset + CONFIG_BOOTBLOCK_BASE);
+ return (void*)offset;
}
static void *emu_rom_unmap(struct cbfs_media *media, const void *address)
diff --git a/src/mainboard/emulation/qemu-armv7/memlayout.ld b/src/mainboard/emulation/qemu-armv7/memlayout.ld
new file mode 100644
index 0000000..1485989
--- /dev/null
+++ b/src/mainboard/emulation/qemu-armv7/memlayout.ld
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+/*
+ * Memory map for qemu vexpress-a9:
+ *
+ * 0x0000_0000: jump instruction (by qemu)
+ * 0x0001_0000: bootblock (entry of kernel / firmware)
+ * 0x0002_0000: romstage, assume up to 128KB in size.
+ * 0x0007_ff00: stack pointer
+ * 0x0010_0000: CBFS header
+ * 0x0011_0000: CBFS data
+ * 0x0100_0000: reserved for ramstage
+ * 0x1000_0000: I/O map address
+ */
+
+SECTIONS
+{
+ /* TODO: does this thing emulate SRAM? */
+
+ BOOTBLOCK(0x10000, 64K)
+ ROMSTAGE(0x20000, 128K)
+ STACK(0x000FC000, 16K)
+
+ DRAM_START(0x01000000)
+ RAMSTAGE(0x01000000, 16M)
+}
diff --git a/src/mainboard/emulation/qemu-riscv/Kconfig b/src/mainboard/emulation/qemu-riscv/Kconfig
index d7d5cc9..5425ca5 100644
--- a/src/mainboard/emulation/qemu-riscv/Kconfig
+++ b/src/mainboard/emulation/qemu-riscv/Kconfig
@@ -54,18 +54,6 @@ config DRAM_SIZE_MB
# 0x0011_0000: CBFS data
# 0x0100_0000: reserved for ramstage
-config BOOTBLOCK_BASE
- hex
- default 0x00000000
-
-config ROMSTAGE_BASE
- hex
- default 0x00020000
-
-config RAMSTAGE_BASE
- hex
- default 0x100000
-
config BOOTBLOCK_ROM_OFFSET
hex
default 0x0
@@ -82,16 +70,4 @@ config RAMTOP
hex
default 0x1000000
-config STACK_TOP
- hex
- default 0x0007ff00
-
-config STACK_BOTTOM
- hex
- default 0x00040000
-
-config STACK_SIZE
- hex
- default 0x0003ff00
-
endif # BOARD_EMULATION_QEMU_UCB_RISCV
diff --git a/src/mainboard/emulation/qemu-riscv/Makefile.inc b/src/mainboard/emulation/qemu-riscv/Makefile.inc
index bc01d2f..e60e0c1 100644
--- a/src/mainboard/emulation/qemu-riscv/Makefile.inc
+++ b/src/mainboard/emulation/qemu-riscv/Makefile.inc
@@ -17,3 +17,7 @@ bootblock-y += uart.c
romstage-y += romstage.c
romstage-y += uart.c
ramstage-y += uart.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/emulation/qemu-riscv/memlayout.ld b/src/mainboard/emulation/qemu-riscv/memlayout.ld
new file mode 100644
index 0000000..082ac8a
--- /dev/null
+++ b/src/mainboard/emulation/qemu-riscv/memlayout.ld
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+SECTIONS
+{
+ DRAM_START(0x0)
+ BOOTBLOCK(0x0, 64K)
+ ROMSTAGE(0x20000, 128K)
+ STACK(0x40000, 0x3ff00)
+ PRERAM_CBMEM_CONSOLE(0x80000, 8K)
+ RAMSTAGE(0x100000, 16M)
+}
+
diff --git a/src/mainboard/google/daisy/Makefile.inc b/src/mainboard/google/daisy/Makefile.inc
index df9b797..1f041ab 100644
--- a/src/mainboard/google/daisy/Makefile.inc
+++ b/src/mainboard/google/daisy/Makefile.inc
@@ -26,3 +26,7 @@ romstage-y += chromeos.c
ramstage-y += mainboard.c
ramstage-y += chromeos.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/daisy/mainboard.c b/src/mainboard/google/daisy/mainboard.c
index 5840e51..138e498 100644
--- a/src/mainboard/google/daisy/mainboard.c
+++ b/src/mainboard/google/daisy/mainboard.c
@@ -36,20 +36,17 @@
#include <soc/samsung/exynos5250/dp.h>
#include <soc/samsung/exynos5250/periph.h>
#include <soc/samsung/exynos5250/usb.h>
+#include <symbols.h>
#include "exynos5250.h"
#define MMC0_GPIO_PIN (58)
/* convenient shorthand (in MB) */
-#define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20)
+#define DRAM_START ((uintptr_t)_dram/MiB)
#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
#define DRAM_END (DRAM_START + DRAM_SIZE) /* plus one... */
-/* Arbitrary range of DMA memory for depthcharge's drivers */
-#define DMA_START (0x77300000)
-#define DMA_SIZE (0x00100000)
-
static struct edid edid = {
.ha = 1366,
.va = 768,
@@ -333,7 +330,8 @@ static void mainboard_enable(device_t dev)
mmu_init();
mmu_config_range(0, DRAM_START, DCACHE_OFF);
mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
- mmu_config_range(DMA_START >> 20, DMA_SIZE >> 20, DCACHE_OFF);
+ mmu_config_range((uintptr_t)_dma_coherent/MiB,
+ _dma_coherent_size/MiB, DCACHE_OFF);
mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
dcache_mmu_enable();
@@ -359,6 +357,6 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = (intptr_t)DMA_START;
- dma->range_size = DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
diff --git a/src/mainboard/google/daisy/memlayout.ld b/src/mainboard/google/daisy/memlayout.ld
new file mode 100644
index 0000000..72c018e
--- /dev/null
+++ b/src/mainboard/google/daisy/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/samsung/exynos5250/memlayout.ld>
diff --git a/src/mainboard/google/nyan/Kconfig b/src/mainboard/google/nyan/Kconfig
index 864e577..082985d 100644
--- a/src/mainboard/google/nyan/Kconfig
+++ b/src/mainboard/google/nyan/Kconfig
@@ -42,14 +42,6 @@ config MAINBOARD_PART_NUMBER
string
default "Nyan"
-config DRAM_DMA_START
- hex
- default 0x90000000
-
-config DRAM_DMA_SIZE
- hex
- default 0x00200000
-
choice
prompt "BCT boot media"
default NYAN_BCT_CFG_SPI
diff --git a/src/mainboard/google/nyan/Makefile.inc b/src/mainboard/google/nyan/Makefile.inc
index 7ac11e8..6506aba 100644
--- a/src/mainboard/google/nyan/Makefile.inc
+++ b/src/mainboard/google/nyan/Makefile.inc
@@ -42,3 +42,7 @@ ramstage-y += reset.c
ramstage-y += boardid.c
ramstage-y += mainboard.c
ramstage-$(CONFIG_CHROMEOS) += chromeos.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/nyan/mainboard.c b/src/mainboard/google/nyan/mainboard.c
index b534ea9..e52db83 100644
--- a/src/mainboard/google/nyan/mainboard.c
+++ b/src/mainboard/google/nyan/mainboard.c
@@ -30,6 +30,7 @@
#include <soc/nvidia/tegra124/pmc.h>
#include <soc/nvidia/tegra124/spi.h>
#include <soc/nvidia/tegra/usb.h>
+#include <symbols.h>
#include <vendorcode/google/chromeos/chromeos.h>
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
@@ -268,6 +269,6 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = CONFIG_DRAM_DMA_START;
- dma->range_size = CONFIG_DRAM_DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
diff --git a/src/mainboard/google/nyan/memlayout.ld b/src/mainboard/google/nyan/memlayout.ld
new file mode 100644
index 0000000..33ce644
--- /dev/null
+++ b/src/mainboard/google/nyan/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/nvidia/tegra124/memlayout.ld>
diff --git a/src/mainboard/google/nyan/romstage.c b/src/mainboard/google/nyan/romstage.c
index 1ff500b..f2077bb 100644
--- a/src/mainboard/google/nyan/romstage.c
+++ b/src/mainboard/google/nyan/romstage.c
@@ -39,6 +39,7 @@
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <soc/display.h>
+#include <symbols.h>
#include <timestamp.h>
static void __attribute__((noinline)) romstage(void)
@@ -52,24 +53,25 @@ static void __attribute__((noinline)) romstage(void)
sdram_init(get_sdram_config());
/* used for MMU and CBMEM setup, in MB */
- u32 dram_start = (CONFIG_SYS_SDRAM_BASE >> 20);
- u32 dram_end = sdram_max_addressable_mb(); /* plus one... */
- u32 dram_size = dram_end - dram_start;
+ u32 dram_start_mb = (uintptr_t)_dram/MiB;
+ u32 dram_end_mb = sdram_max_addressable_mb();
+ u32 dram_size_mb = dram_end_mb - dram_start_mb;
configure_l2_cache();
mmu_init();
/* Device memory below DRAM is uncached. */
- mmu_config_range(0, dram_start, DCACHE_OFF);
- /* SRAM is cached. Round the size up to 2MB, the LPAE page size. */
- mmu_config_range(0x40000000 >> 20, 2, DCACHE_WRITEBACK);
+ mmu_config_range(0, dram_start_mb, DCACHE_OFF);
+ /* SRAM is cached. MMU code will round size up to page size. */
+ mmu_config_range((uintptr_t)_sram/MiB, div_round_up(_sram_size, MiB),
+ DCACHE_WRITEBACK);
/* DRAM is cached. */
- mmu_config_range(dram_start, dram_size, DCACHE_WRITEBACK);
+ mmu_config_range(dram_start_mb, dram_size_mb, DCACHE_WRITEBACK);
/* A window for DMA is uncached. */
- mmu_config_range(CONFIG_DRAM_DMA_START >> 20,
- CONFIG_DRAM_DMA_SIZE >> 20, DCACHE_OFF);
+ mmu_config_range((uintptr_t)_dma_coherent/MiB,
+ _dma_coherent_size/MiB, DCACHE_OFF);
/* The space above DRAM is uncached. */
- if (dram_end < 4096)
- mmu_config_range(dram_end, 4096 - dram_end, DCACHE_OFF);
+ if (dram_end_mb < 4096)
+ mmu_config_range(dram_end_mb, 4096 - dram_end_mb, DCACHE_OFF);
mmu_disable_range(0, 1);
dcache_mmu_enable();
diff --git a/src/mainboard/google/nyan_big/Kconfig b/src/mainboard/google/nyan_big/Kconfig
index 2968b01..7334472 100644
--- a/src/mainboard/google/nyan_big/Kconfig
+++ b/src/mainboard/google/nyan_big/Kconfig
@@ -44,14 +44,6 @@ config MAINBOARD_PART_NUMBER
string
default "Nyan Big"
-config DRAM_DMA_START
- hex
- default 0x90000000
-
-config DRAM_DMA_SIZE
- hex
- default 0x00200000
-
choice
prompt "BCT boot media"
default NYAN_BIG_BCT_CFG_SPI
diff --git a/src/mainboard/google/nyan_big/Makefile.inc b/src/mainboard/google/nyan_big/Makefile.inc
index 8ca495c..fddb44e 100644
--- a/src/mainboard/google/nyan_big/Makefile.inc
+++ b/src/mainboard/google/nyan_big/Makefile.inc
@@ -41,3 +41,7 @@ ramstage-y += reset.c
ramstage-y += boardid.c
ramstage-y += mainboard.c
ramstage-$(CONFIG_CHROMEOS) += chromeos.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/nyan_big/mainboard.c b/src/mainboard/google/nyan_big/mainboard.c
index 86d9fe3..05f6fae 100644
--- a/src/mainboard/google/nyan_big/mainboard.c
+++ b/src/mainboard/google/nyan_big/mainboard.c
@@ -30,6 +30,7 @@
#include <soc/nvidia/tegra124/pmc.h>
#include <soc/nvidia/tegra124/spi.h>
#include <soc/nvidia/tegra/usb.h>
+#include <symbols.h>
#include <vendorcode/google/chromeos/chromeos.h>
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
@@ -266,6 +267,6 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = CONFIG_DRAM_DMA_START;
- dma->range_size = CONFIG_DRAM_DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
diff --git a/src/mainboard/google/nyan_big/memlayout.ld b/src/mainboard/google/nyan_big/memlayout.ld
new file mode 100644
index 0000000..33ce644
--- /dev/null
+++ b/src/mainboard/google/nyan_big/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/nvidia/tegra124/memlayout.ld>
diff --git a/src/mainboard/google/nyan_big/romstage.c b/src/mainboard/google/nyan_big/romstage.c
index 1ff500b..f2077bb 100644
--- a/src/mainboard/google/nyan_big/romstage.c
+++ b/src/mainboard/google/nyan_big/romstage.c
@@ -39,6 +39,7 @@
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <soc/display.h>
+#include <symbols.h>
#include <timestamp.h>
static void __attribute__((noinline)) romstage(void)
@@ -52,24 +53,25 @@ static void __attribute__((noinline)) romstage(void)
sdram_init(get_sdram_config());
/* used for MMU and CBMEM setup, in MB */
- u32 dram_start = (CONFIG_SYS_SDRAM_BASE >> 20);
- u32 dram_end = sdram_max_addressable_mb(); /* plus one... */
- u32 dram_size = dram_end - dram_start;
+ u32 dram_start_mb = (uintptr_t)_dram/MiB;
+ u32 dram_end_mb = sdram_max_addressable_mb();
+ u32 dram_size_mb = dram_end_mb - dram_start_mb;
configure_l2_cache();
mmu_init();
/* Device memory below DRAM is uncached. */
- mmu_config_range(0, dram_start, DCACHE_OFF);
- /* SRAM is cached. Round the size up to 2MB, the LPAE page size. */
- mmu_config_range(0x40000000 >> 20, 2, DCACHE_WRITEBACK);
+ mmu_config_range(0, dram_start_mb, DCACHE_OFF);
+ /* SRAM is cached. MMU code will round size up to page size. */
+ mmu_config_range((uintptr_t)_sram/MiB, div_round_up(_sram_size, MiB),
+ DCACHE_WRITEBACK);
/* DRAM is cached. */
- mmu_config_range(dram_start, dram_size, DCACHE_WRITEBACK);
+ mmu_config_range(dram_start_mb, dram_size_mb, DCACHE_WRITEBACK);
/* A window for DMA is uncached. */
- mmu_config_range(CONFIG_DRAM_DMA_START >> 20,
- CONFIG_DRAM_DMA_SIZE >> 20, DCACHE_OFF);
+ mmu_config_range((uintptr_t)_dma_coherent/MiB,
+ _dma_coherent_size/MiB, DCACHE_OFF);
/* The space above DRAM is uncached. */
- if (dram_end < 4096)
- mmu_config_range(dram_end, 4096 - dram_end, DCACHE_OFF);
+ if (dram_end_mb < 4096)
+ mmu_config_range(dram_end_mb, 4096 - dram_end_mb, DCACHE_OFF);
mmu_disable_range(0, 1);
dcache_mmu_enable();
diff --git a/src/mainboard/google/nyan_blaze/Kconfig b/src/mainboard/google/nyan_blaze/Kconfig
index 5938e7e..3495919 100644
--- a/src/mainboard/google/nyan_blaze/Kconfig
+++ b/src/mainboard/google/nyan_blaze/Kconfig
@@ -45,14 +45,6 @@ config MAINBOARD_PART_NUMBER
string
default "Nyan Blaze"
-config DRAM_DMA_START
- hex
- default 0x90000000
-
-config DRAM_DMA_SIZE
- hex
- default 0x00200000
-
choice
prompt "BCT boot media"
default NYAN_BLAZE_BCT_CFG_SPI
diff --git a/src/mainboard/google/nyan_blaze/Makefile.inc b/src/mainboard/google/nyan_blaze/Makefile.inc
index dc998d1..3430409 100644
--- a/src/mainboard/google/nyan_blaze/Makefile.inc
+++ b/src/mainboard/google/nyan_blaze/Makefile.inc
@@ -45,3 +45,8 @@ ramstage-y += reset.c
ramstage-y += boardid.c
ramstage-y += mainboard.c
ramstage-$(CONFIG_CHROMEOS) += chromeos.c
+
+bootblock-y += memlayout.ld
+verstage-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/nyan_blaze/mainboard.c b/src/mainboard/google/nyan_blaze/mainboard.c
index ccbaf63..5f1cb49 100644
--- a/src/mainboard/google/nyan_blaze/mainboard.c
+++ b/src/mainboard/google/nyan_blaze/mainboard.c
@@ -30,6 +30,7 @@
#include <soc/nvidia/tegra124/pmc.h>
#include <soc/nvidia/tegra124/spi.h>
#include <soc/nvidia/tegra/usb.h>
+#include <symbols.h>
#include <vendorcode/google/chromeos/chromeos.h>
static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
@@ -266,6 +267,6 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = CONFIG_DRAM_DMA_START;
- dma->range_size = CONFIG_DRAM_DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
diff --git a/src/mainboard/google/nyan_blaze/memlayout.ld b/src/mainboard/google/nyan_blaze/memlayout.ld
new file mode 100644
index 0000000..33ce644
--- /dev/null
+++ b/src/mainboard/google/nyan_blaze/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/nvidia/tegra124/memlayout.ld>
diff --git a/src/mainboard/google/nyan_blaze/romstage.c b/src/mainboard/google/nyan_blaze/romstage.c
index fca705d..fb1b9e2 100644
--- a/src/mainboard/google/nyan_blaze/romstage.c
+++ b/src/mainboard/google/nyan_blaze/romstage.c
@@ -39,6 +39,7 @@
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <soc/display.h>
+#include <symbols.h>
#include <timestamp.h>
static void __attribute__((noinline)) romstage(void)
@@ -52,29 +53,30 @@ static void __attribute__((noinline)) romstage(void)
sdram_init(get_sdram_config());
/* used for MMU and CBMEM setup, in MB */
- u32 dram_start = (CONFIG_SYS_SDRAM_BASE >> 20);
- u32 dram_end = sdram_max_addressable_mb(); /* plus one... */
- u32 dram_size = dram_end - dram_start;
+ u32 dram_start_mb = (uintptr_t)_dram/MiB;
+ u32 dram_end_mb = sdram_max_addressable_mb();
+ u32 dram_size_mb = dram_end_mb - dram_start_mb;
#if !CONFIG_VBOOT2_VERIFY_FIRMWARE
configure_l2_cache();
mmu_init();
/* Device memory below DRAM is uncached. */
- mmu_config_range(0, dram_start, DCACHE_OFF);
- /* SRAM is cached. Round the size up to 2MB, the LPAE page size. */
- mmu_config_range(0x40000000 >> 20, 2, DCACHE_WRITEBACK);
+ mmu_config_range(0, dram_start_mb, DCACHE_OFF);
+ /* SRAM is cached. MMU code will round size up to page size. */
+ mmu_config_range((uintptr_t)_sram/MiB, div_round_up(_sram_size, MiB),
+ DCACHE_WRITEBACK);
/* The space above DRAM is uncached. */
- if (dram_end < 4096)
- mmu_config_range(dram_end, 4096 - dram_end, DCACHE_OFF);
+ if (dram_end_mb < 4096)
+ mmu_config_range(dram_end_mb, 4096 - dram_end_mb, DCACHE_OFF);
mmu_disable_range(0, 1);
dcache_mmu_enable();
#endif
/* DRAM is cached. */
- mmu_config_range(dram_start, dram_size, DCACHE_WRITEBACK);
+ mmu_config_range(dram_start_mb, dram_size_mb, DCACHE_WRITEBACK);
/* A window for DMA is uncached. */
- mmu_config_range(CONFIG_DRAM_DMA_START >> 20,
- CONFIG_DRAM_DMA_SIZE >> 20, DCACHE_OFF);
+ mmu_config_range((uintptr_t)_dma_coherent/MiB,
+ _dma_coherent_size/MiB, DCACHE_OFF);
/*
* A watchdog reset only resets part of the system so it ends up in
diff --git a/src/mainboard/google/peach_pit/Makefile.inc b/src/mainboard/google/peach_pit/Makefile.inc
index df9b797..1f041ab 100644
--- a/src/mainboard/google/peach_pit/Makefile.inc
+++ b/src/mainboard/google/peach_pit/Makefile.inc
@@ -26,3 +26,7 @@ romstage-y += chromeos.c
ramstage-y += mainboard.c
ramstage-y += chromeos.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/peach_pit/mainboard.c b/src/mainboard/google/peach_pit/mainboard.c
index 1a15bd2..b6f49e2 100644
--- a/src/mainboard/google/peach_pit/mainboard.c
+++ b/src/mainboard/google/peach_pit/mainboard.c
@@ -40,15 +40,12 @@
#include <drivers/parade/ps8625/ps8625.h>
#include <ec/google/chromeec/ec.h>
#include <stdlib.h>
+#include <symbols.h>
/* convenient shorthand (in MB) */
-#define DRAM_START (CONFIG_SYS_SDRAM_BASE >> 20)
+#define DRAM_START ((uintptr_t)_dram/MiB)
#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
-/* Arbitrary range of DMA memory for depthcharge's drivers */
-#define DMA_START (0x77300000)
-#define DMA_SIZE (0x00100000)
-
static struct edid edid = {
.ha = 1366,
.va = 768,
@@ -469,7 +466,8 @@ static void mainboard_enable(device_t dev)
/* set up caching for the DRAM */
mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
- mmu_config_range(DMA_START >> 20, DMA_SIZE >> 20, DCACHE_OFF);
+ mmu_config_range((uintptr_t)_dma_coherent/MiB,
+ _dma_coherent_size/MiB, DCACHE_OFF);
const unsigned epll_hz = 192000000;
const unsigned sample_rate = 48000;
@@ -493,6 +491,6 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = (intptr_t)DMA_START;
- dma->range_size = DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
diff --git a/src/mainboard/google/peach_pit/memlayout.ld b/src/mainboard/google/peach_pit/memlayout.ld
new file mode 100644
index 0000000..565ba89
--- /dev/null
+++ b/src/mainboard/google/peach_pit/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/samsung/exynos5420/memlayout.ld>
diff --git a/src/mainboard/google/rush/Makefile.inc b/src/mainboard/google/rush/Makefile.inc
index 2a1ce99..e41745f 100644
--- a/src/mainboard/google/rush/Makefile.inc
+++ b/src/mainboard/google/rush/Makefile.inc
@@ -40,3 +40,7 @@ ramstage-y += boardid.c
ramstage-y += mainboard.c
ramstage-y += reset.c
ramstage-$(CONFIG_CHROMEOS) += chromeos.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/rush/memlayout.ld b/src/mainboard/google/rush/memlayout.ld
new file mode 100644
index 0000000..b9def51
--- /dev/null
+++ b/src/mainboard/google/rush/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/nvidia/tegra132/memlayout.ld>
diff --git a/src/mainboard/google/rush_ryu/Makefile.inc b/src/mainboard/google/rush_ryu/Makefile.inc
index 2fe12a4..67a3fac 100644
--- a/src/mainboard/google/rush_ryu/Makefile.inc
+++ b/src/mainboard/google/rush_ryu/Makefile.inc
@@ -41,3 +41,7 @@ ramstage-y += boardid.c
ramstage-y += mainboard.c
ramstage-y += reset.c
ramstage-y += chromeos.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/rush_ryu/memlayout.ld b/src/mainboard/google/rush_ryu/memlayout.ld
new file mode 100644
index 0000000..b9def51
--- /dev/null
+++ b/src/mainboard/google/rush_ryu/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/nvidia/tegra132/memlayout.ld>
diff --git a/src/mainboard/google/storm/Kconfig b/src/mainboard/google/storm/Kconfig
index b0c064c..3e1e016 100644
--- a/src/mainboard/google/storm/Kconfig
+++ b/src/mainboard/google/storm/Kconfig
@@ -48,12 +48,4 @@ config DRAM_SIZE_MB
default 512 if BOARD_VARIANT_AP148
default 1024
-config DRAM_DMA_START
- hex
- default 0x5a000000
-
-config DRAM_DMA_SIZE
- hex
- default 0x00200000
-
endif # BOARD_GOOGLE_STORM
diff --git a/src/mainboard/google/storm/Makefile.inc b/src/mainboard/google/storm/Makefile.inc
index 907638a..6ee0841 100644
--- a/src/mainboard/google/storm/Makefile.inc
+++ b/src/mainboard/google/storm/Makefile.inc
@@ -25,3 +25,7 @@ romstage-y += cdp.c
ramstage-y += boardid.c
ramstage-y += cdp.c
ramstage-y += mainboard.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/storm/mainboard.c b/src/mainboard/google/storm/mainboard.c
index 3da6f90..478e2a8 100644
--- a/src/mainboard/google/storm/mainboard.c
+++ b/src/mainboard/google/storm/mainboard.c
@@ -25,19 +25,20 @@
#include <device/device.h>
#include <gpiolib.h>
#include <string.h>
+#include <symbols.h>
#include <soc/qualcomm/ipq806x/include/clock.h>
#include <soc/qualcomm/ipq806x/include/gpio.h>
#include <soc/qualcomm/ipq806x/include/usb.h>
/* convenient shorthand (in MB) */
-#define DRAM_START (CONFIG_SYS_SDRAM_BASE / MiB)
+#define DRAM_START ((uintptr_t)_dram / MiB)
#define DRAM_SIZE (CONFIG_DRAM_SIZE_MB)
#define DRAM_END (DRAM_START + DRAM_SIZE)
/* DMA memory for drivers */
-#define DMA_START (CONFIG_DRAM_DMA_START / MiB)
-#define DMA_SIZE (CONFIG_DRAM_DMA_SIZE / MiB)
+#define DMA_START ((uintptr_t)_dma_coherent / MiB)
+#define DMA_SIZE (_dma_coherent_size / MiB)
#define USB_ENABLE_GPIO 51
@@ -134,8 +135,8 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = CONFIG_DRAM_DMA_START;
- dma->range_size = CONFIG_DRAM_DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
static int read_gpio(gpio_t gpio_num)
diff --git a/src/mainboard/google/storm/memlayout.ld b/src/mainboard/google/storm/memlayout.ld
new file mode 100644
index 0000000..1735835
--- /dev/null
+++ b/src/mainboard/google/storm/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/qualcomm/ipq806x/memlayout.ld>
diff --git a/src/mainboard/google/urara/Kconfig b/src/mainboard/google/urara/Kconfig
index bde26d6..a9363f9 100644
--- a/src/mainboard/google/urara/Kconfig
+++ b/src/mainboard/google/urara/Kconfig
@@ -38,10 +38,6 @@ config MAINBOARD_PART_NUMBER
string
default "ImgTec Pistachio Virtual Platform"
-config SYS_SDRAM_BASE
- hex "SDRAM base address"
- default 0x80000000
-
config DRAM_SIZE_MB
int
default 256
diff --git a/src/mainboard/google/urara/Makefile.inc b/src/mainboard/google/urara/Makefile.inc
index 4ce6398..5a9dc02 100644
--- a/src/mainboard/google/urara/Makefile.inc
+++ b/src/mainboard/google/urara/Makefile.inc
@@ -21,3 +21,6 @@
ramstage-y += mainboard.c
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/urara/memlayout.ld b/src/mainboard/google/urara/memlayout.ld
new file mode 100644
index 0000000..ab0b4dd
--- /dev/null
+++ b/src/mainboard/google/urara/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/imgtec/pistachio/memlayout.ld>
diff --git a/src/mainboard/google/veyron_pinky/Kconfig b/src/mainboard/google/veyron_pinky/Kconfig
index 97a0097..7c4f084 100644
--- a/src/mainboard/google/veyron_pinky/Kconfig
+++ b/src/mainboard/google/veyron_pinky/Kconfig
@@ -61,14 +61,6 @@ config BOOT_MEDIA_SPI_BUS
int
default 2
-config DRAM_DMA_START
- hex
- default 0x10000000
-
-config DRAM_DMA_SIZE
- hex
- default 0x00200000
-
config DRAM_SIZE_MB
int
default 2048
diff --git a/src/mainboard/google/veyron_pinky/Makefile.inc b/src/mainboard/google/veyron_pinky/Makefile.inc
index c33cfa3..0cc89d0 100644
--- a/src/mainboard/google/veyron_pinky/Makefile.inc
+++ b/src/mainboard/google/veyron_pinky/Makefile.inc
@@ -35,3 +35,8 @@ ramstage-y += boardid.c
ramstage-y += chromeos.c
ramstage-y += mainboard.c
ramstage-y += reset.c
+
+bootblock-y += memlayout.ld
+verstage-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/google/veyron_pinky/mainboard.c b/src/mainboard/google/veyron_pinky/mainboard.c
index 232010d..19d6675 100644
--- a/src/mainboard/google/veyron_pinky/mainboard.c
+++ b/src/mainboard/google/veyron_pinky/mainboard.c
@@ -22,6 +22,7 @@
#include <arch/cache.h>
#include <delay.h>
#include <edid.h>
+#include <symbols.h>
#include <vbe.h>
#include <boot/coreboot_tables.h>
#include <device/i2c.h>
@@ -153,6 +154,6 @@ void lb_board(struct lb_header *header)
dma = (struct lb_range *)lb_new_record(header);
dma->tag = LB_TAB_DMA;
dma->size = sizeof(*dma);
- dma->range_start = CONFIG_DRAM_DMA_START;
- dma->range_size = CONFIG_DRAM_DMA_SIZE;
+ dma->range_start = (uintptr_t)_dma_coherent;
+ dma->range_size = _dma_coherent_size;
}
diff --git a/src/mainboard/google/veyron_pinky/memlayout.ld b/src/mainboard/google/veyron_pinky/memlayout.ld
new file mode 100644
index 0000000..a8b7465
--- /dev/null
+++ b/src/mainboard/google/veyron_pinky/memlayout.ld
@@ -0,0 +1 @@
+#include <soc/rockchip/rk3288/memlayout.ld>
diff --git a/src/mainboard/google/veyron_pinky/romstage.c b/src/mainboard/google/veyron_pinky/romstage.c
index f972ee2..1d7812b 100644
--- a/src/mainboard/google/veyron_pinky/romstage.c
+++ b/src/mainboard/google/veyron_pinky/romstage.c
@@ -35,6 +35,7 @@
#include <soc/rockchip/rk3288/clock.h>
#include <soc/rockchip/rk3288/pwm.h>
#include <soc/rockchip/rk3288/grf.h>
+#include <symbols.h>
#include "timer.h"
static void regulate_vdd_log(unsigned int mv)
@@ -64,9 +65,9 @@ void main(void)
start_romstage_time = timestamp_get();
#endif
/* used for MMU and CBMEM setup, in MB */
- u32 dram_start = (CONFIG_SYS_SDRAM_BASE >> 20);
- u32 dram_size = CONFIG_DRAM_SIZE_MB;
- u32 dram_end = dram_start + dram_size;
+ u32 dram_start_mb = (uintptr_t)_dram/MiB;
+ u32 dram_size_mb = CONFIG_DRAM_SIZE_MB;
+ u32 dram_end_mb = dram_start_mb + dram_size_mb;
console_init();
@@ -81,15 +82,15 @@ void main(void)
#endif
mmu_init();
/* Device memory below DRAM is uncached. */
- mmu_config_range(0, dram_start, DCACHE_OFF);
+ mmu_config_range(0, dram_start_mb, DCACHE_OFF);
/* DRAM is cached. */
- mmu_config_range(dram_start, dram_size, DCACHE_WRITEBACK);
+ mmu_config_range(dram_start_mb, dram_size_mb, DCACHE_WRITEBACK);
/* A window for DMA is uncached. */
- mmu_config_range(CONFIG_DRAM_DMA_START >> 20,
- CONFIG_DRAM_DMA_SIZE >> 20, DCACHE_OFF);
+ mmu_config_range((uintptr_t)_dma_coherent/MiB,
+ _dma_coherent_size/MiB, DCACHE_OFF);
/* The space above DRAM is uncached. */
- if (dram_end < 4096)
- mmu_config_range(dram_end, 4096 - dram_end, DCACHE_OFF);
+ if (dram_end_mb < 4096)
+ mmu_config_range(dram_end_mb, 4096 - dram_end_mb, DCACHE_OFF);
dcache_mmu_enable();
cbmem_initialize_empty();
diff --git a/src/mainboard/ti/beaglebone/Makefile.inc b/src/mainboard/ti/beaglebone/Makefile.inc
index 71d749d..1a2143f 100644
--- a/src/mainboard/ti/beaglebone/Makefile.inc
+++ b/src/mainboard/ti/beaglebone/Makefile.inc
@@ -21,3 +21,7 @@ bootblock-y += bootblock.c
romstage-y += romstage.c
#ramstage-y += ramstage.c
+
+bootblock-y += memlayout.ld
+romstage-y += memlayout.ld
+ramstage-y += memlayout.ld
diff --git a/src/mainboard/ti/beaglebone/memlayout.ld b/src/mainboard/ti/beaglebone/memlayout.ld
new file mode 100644
index 0000000..ff79e70
--- /dev/null
+++ b/src/mainboard/ti/beaglebone/memlayout.ld
@@ -0,0 +1 @@
+#include <cpu/ti/am335x/memlayout.ld>
diff --git a/src/soc/imgtec/pistachio/Kconfig b/src/soc/imgtec/pistachio/Kconfig
index 2e8b700..70e5741 100644
--- a/src/soc/imgtec/pistachio/Kconfig
+++ b/src/soc/imgtec/pistachio/Kconfig
@@ -35,10 +35,6 @@ config BOOTBLOCK_CPU_INIT
string
default "soc/imgtec/pistachio/bootblock.c"
-config BOOTBLOCK_BASE
- hex
- default 0x9b000000
-
config CBFS_ROM_OFFSET
hex
default 0x4100
@@ -48,31 +44,4 @@ config CBFS_HEADER_ROM_OFFSET
hex
default 0x4000
-config ROMSTAGE_BASE
- hex
- default 0x9b004000
- help
- The address where romstage is supposed to be loaded, right above the
- bootblock.
-
-config CBMEM_CONSOLE_PRERAM_BASE
- hex "memory address of the CBMEM console buffer"
- default 0x9b00f800
- help
- Allocate 4KB to the pre-ram console buffer, we should be able to use
- GRAM eventually and have a much larger buffer.
-
-config BOOTBLOCK_STACK_BOTTOM
- hex
- default 0x9b00e000
- help
- This allocates 6KB of stack space. One needs to verify that this is
- sufficient.
-
-config BOOTBLOCK_STACK_TOP
- hex
- default CBMEM_CONSOLE_PRERAM_BASE
- help
- Bootblock stack starts immediately under the CBMEM console buffer,
- stack location might be changed by romstage.
endif
diff --git a/src/soc/imgtec/pistachio/Makefile.inc b/src/soc/imgtec/pistachio/Makefile.inc
index b91bb1b5..d052c8f 100644
--- a/src/soc/imgtec/pistachio/Makefile.inc
+++ b/src/soc/imgtec/pistachio/Makefile.inc
@@ -51,5 +51,5 @@ $(objcbfs)/bootblock.raw: $(objcbfs)/bootblock.elf
# Create a complete bootblock which will start up the system
$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw $(BIMGTOOL)
@printf " BIMGTOOL $(subst $(obj)/,,$(@))\n"
- $(BIMGTOOL) $< $@ $(CONFIG_BOOTBLOCK_BASE)
+ $(BIMGTOOL) $< $@ $(call loadaddr,bootblock)
diff --git a/src/soc/imgtec/pistachio/cbmem.c b/src/soc/imgtec/pistachio/cbmem.c
index 5fb6c0e..373d4f8 100644
--- a/src/soc/imgtec/pistachio/cbmem.c
+++ b/src/soc/imgtec/pistachio/cbmem.c
@@ -21,9 +21,10 @@
#include <cbmem.h>
#include <stdlib.h>
+#include <symbols.h>
void *cbmem_top(void)
{
uintptr_t top = MIN(CONFIG_DRAM_SIZE_MB, 256) << 20;
- return (void *)(top + CONFIG_SYS_SDRAM_BASE);
+ return _dram + top;
}
diff --git a/src/soc/imgtec/pistachio/memlayout.ld b/src/soc/imgtec/pistachio/memlayout.ld
new file mode 100644
index 0000000..21c3d73
--- /dev/null
+++ b/src/soc/imgtec/pistachio/memlayout.ld
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+/* TODO: This should be revised by someone who understands the SoC better. */
+
+SECTIONS
+{
+ CBFS_CACHE(0x0, 0) /* TODO: fix this, it was already broken before!!! */
+
+ DRAM_START(0x80000000)
+ RAMSTAGE(0x80000000, 128K)
+
+ /* TODO: Does this SoC use SRAM? Add SRAM_START() and SRAM_END(). */
+ BOOTBLOCK(0x9B000000, 16K)
+ ROMSTAGE(0x9B004000, 40K)
+ STACK(0x9B00E000, 6K)
+ PRERAM_CBMEM_CONSOLE(0x9B00F800, 3K)
+}
diff --git a/src/soc/nvidia/tegra124/Kconfig b/src/soc/nvidia/tegra124/Kconfig
index acc6e7e..1680f45 100644
--- a/src/soc/nvidia/tegra124/Kconfig
+++ b/src/soc/nvidia/tegra124/Kconfig
@@ -22,34 +22,6 @@ config BOOTBLOCK_CPU_INIT
bootblock must load microcode or copy data from ROM before
searching for the bootblock.
-# ROM image layout.
-#
-# 0x00000 Combined bootblock and BCT blob
-# 0x18000 Master CBFS header.
-# 0x18080 Free for CBFS data.
-#
-# iRAM (256k) layout.
-# (Note: The BootROM uses the address range [0x4000_0000:0x4000_E000) itself,
-# so the bootblock loading address must be placed after that. After the
-# handoff that area may be reclaimed for other uses, e.g. CBFS cache.)
-#
-# 0x4000_0000 TTB (16K+32B). 32B is for L1 table of LPAE.
-# 0x4000_4020 CBFS mapping cache (96K-32B)
-# 0x4001_C000 Stack (16KB... don't reduce without comparing LZMA scratchpad!).
-# 0x4002_0000 Bootblock (max 48KB).
-# 0x4002_C000 ROM stage (max 80KB).
-# 0x4003_FFFF End of iRAM.
-#
-# if VBOOT2_VERIFY_FIRMWARE,
-# 0x4000_0000 TTB (16K+32B). 32B is for L1 table of LPAE.
-# 0x4000_4020 CBMEM console area (8K-32B)
-# 0x4000_6000 CBFS mapping cache (72K)
-# 0x4001_8000 vboot work buffer (16K)
-# 0x4001_C000 Stack (16KB... don't reduce without comparing LZMA scratchpad!).
-# 0x4002_0000 bootblock and romstage (max 70KB).
-# 0x4003_1000 verstage (max 60KB).
-# 0x4003_FFFF End of iRAM.
-
config BOOTBLOCK_ROM_OFFSET
hex
default 0x0
@@ -62,65 +34,6 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x18080
-config SYS_SDRAM_BASE
- hex
- default 0x80000000
-
-config BOOTBLOCK_BASE
- hex
- default 0x40020000
-
-# this has to be big enough to leave room big enough for the larger of the
-# bootblock and the romstage.
-config VERSTAGE_BASE
- hex
- default 0x40031000
-
-# with vboot2, romstage is loaded over to the bootblock space
-config ROMSTAGE_BASE
- hex
- default 0x40020000 if VBOOT2_VERIFY_FIRMWARE
- default 0x4002c000
-
-config RAMSTAGE_BASE
- hex
- default 0x80200000
-
-config STACK_TOP
- hex
- default 0x40020000
-
-config STACK_BOTTOM
- hex
- default 0x4001c000
-
-# This is the ramstage thread stack, *not* the same as above! Currently unused.
-config STACK_SIZE
- hex
- default 0x800
-
-# TTB needs to be aligned to 16KB. Stick it in iRAM.
-config TTB_BUFFER
- hex "memory address of the TTB buffer"
- default 0x40000000
-
-config CBFS_CACHE_ADDRESS
- hex "memory address to put CBFS cache data"
- default 0x40004020
-
-config CBFS_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00012000 if VBOOT2_VERIFY_FIRMWARE
- default 0x00016000
-
-config VBOOT_WORK_BUFFER_ADDRESS
- hex "memory address of vboot work buffer"
- default 0x40018000
-
-config VBOOT_WORK_BUFFER_SIZE
- hex "size of vboot work buffer"
- default 0x00004000
-
config TEGRA124_MODEL_TD570D
bool "TD570D"
diff --git a/src/soc/nvidia/tegra124/Makefile.inc b/src/soc/nvidia/tegra124/Makefile.inc
index d32580e..6de142d 100644
--- a/src/soc/nvidia/tegra124/Makefile.inc
+++ b/src/soc/nvidia/tegra124/Makefile.inc
@@ -103,6 +103,6 @@ $(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin $(BCT_BIN) $(CBOOTIMAGE)
echo "Version = 1;" > $(BCT_WRAPPER)
echo "Redundancy = 1;" >> $(BCT_WRAPPER)
echo "Bctfile = $(BCT_BIN);" >> $(BCT_WRAPPER)
- echo "BootLoader = $<,$(CONFIG_BOOTBLOCK_BASE),$(CONFIG_BOOTBLOCK_BASE),Complete;" >> $(BCT_WRAPPER)
+ echo "BootLoader = $<,$(call loadaddr,bootblock),$(call loadaddr,bootblock),Complete;" >> $(BCT_WRAPPER)
@printf " CBOOTIMAGE $(subst $(obj)/,,$(@))\n"
$(CBOOTIMAGE) $(BCT_WRAPPER) $@
diff --git a/src/soc/nvidia/tegra124/bootblock_asm.S b/src/soc/nvidia/tegra124/bootblock_asm.S
index e4d4302..1a30dda 100644
--- a/src/soc/nvidia/tegra124/bootblock_asm.S
+++ b/src/soc/nvidia/tegra124/bootblock_asm.S
@@ -44,10 +44,8 @@ ENTRY(_start)
* Initialize the stack to a known value. This is used to check for
* stack overflow later in the boot process.
*/
- ldr r0, .Stack
- ldr r1, .Stack_size
- sub r0, r0, r1
- ldr r1, .Stack
+ ldr r0, =_stack
+ ldr r1, =_estack
ldr r2, =0xdeadbeef
init_stack_loop:
str r2, [r0]
@@ -57,7 +55,7 @@ init_stack_loop:
/* Set stackpointer in internal RAM to call bootblock main() */
call_bootblock:
- ldr sp, .Stack /* Set up stack pointer */
+ ldr sp, =_estack /* Set up stack pointer */
ldr r0,=0x00000000
/*
* The current design of cpu_info places the
@@ -75,15 +73,3 @@ call_bootblock:
*/
bl main
ENDPROC(_start)
-
-/* we do it this way because it's a 32-bit constant and
- * in some cases too far away to be loaded as just an offset
- * from IP
- */
-.align 2
-.Stack:
- .word CONFIG_STACK_TOP
-.align 2
-/* create this size the same way we do in coreboot_ram.ld: top-bottom */
-.Stack_size:
- .word CONFIG_STACK_TOP - CONFIG_STACK_BOTTOM
diff --git a/src/soc/nvidia/tegra124/cbfs.c b/src/soc/nvidia/tegra124/cbfs.c
index 4497d6a..d56050d 100644
--- a/src/soc/nvidia/tegra124/cbfs.c
+++ b/src/soc/nvidia/tegra124/cbfs.c
@@ -19,12 +19,12 @@
#include <cbfs.h> /* This driver serves as a CBFS media source. */
+#include <symbols.h>
#include "spi.h"
int init_default_cbfs_media(struct cbfs_media *media)
{
return initialize_tegra_spi_cbfs_media(media,
- (void*)CONFIG_CBFS_CACHE_ADDRESS,
- CONFIG_CBFS_CACHE_SIZE);
+ _cbfs_cache, _cbfs_cache_size);
}
diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c
index fa33283..f5043af 100644
--- a/src/soc/nvidia/tegra124/clock.c
+++ b/src/soc/nvidia/tegra124/clock.c
@@ -20,6 +20,7 @@
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <stdlib.h>
+#include <symbols.h>
#include <arch/clock.h>
#include "clk_rst.h"
#include "flow.h"
@@ -485,7 +486,7 @@ void clock_cpu0_config(void *entry)
{
void * const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100;
- write32(CONFIG_STACK_TOP, &maincpu_stack_pointer);
+ write32((uintptr_t)_estack, &maincpu_stack_pointer);
write32((uintptr_t)entry, &maincpu_entry_point);
write32((uintptr_t)&maincpu_setup, evp_cpu_reset);
diff --git a/src/soc/nvidia/tegra124/memlayout.ld b/src/soc/nvidia/tegra124/memlayout.ld
new file mode 100644
index 0000000..0d9e772
--- /dev/null
+++ b/src/soc/nvidia/tegra124/memlayout.ld
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+#include <vendorcode/google/chromeos/memlayout.h>
+
+#include <arch/header.ld>
+
+/*
+ * Note: The BootROM uses the address range [0x4000_0000:0x4000_E000) itself,
+ * so the bootblock loading address must be placed after that. After the
+ * handoff that area may be reclaimed for other uses, e.g. CBFS cache.
+ */
+
+SECTIONS
+{
+ SRAM_START(0x40000000)
+ TTB(0x40000000, 16K + 32)
+ PRERAM_CBMEM_CONSOLE(0x40004020, 8K - 32)
+ PRERAM_CBFS_CACHE(0x40006000, 16K)
+ VBOOT2_WORK(0x4000A000, 16K)
+ STACK(0x4000E000, 8K)
+ BOOTBLOCK(0x40010000, 24K)
+ VERSTAGE(0x40016000, 72K)
+ ROMSTAGE(0x40028000, 96K)
+ SRAM_END(0x40040000)
+
+ DRAM_START(0x80000000)
+ POSTRAM_CBFS_CACHE(0x80100000, 1M)
+ RAMSTAGE(0x80200000, 128K)
+ DMA_COHERENT(0x90000000, 2M)
+}
diff --git a/src/soc/nvidia/tegra124/sdram.c b/src/soc/nvidia/tegra124/sdram.c
index f0797db..82219b1 100644
--- a/src/soc/nvidia/tegra124/sdram.c
+++ b/src/soc/nvidia/tegra124/sdram.c
@@ -23,6 +23,7 @@
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <stdlib.h>
+#include <symbols.h>
#include "emc.h"
#include "mc.h"
@@ -643,5 +644,5 @@ int sdram_size_mb(void)
uintptr_t sdram_max_addressable_mb(void)
{
- return MIN((CONFIG_SYS_SDRAM_BASE/MiB) + sdram_size_mb(), 4096);
+ return MIN(((uintptr_t)_dram/MiB) + sdram_size_mb(), 4096);
}
diff --git a/src/soc/nvidia/tegra124/soc.c b/src/soc/nvidia/tegra124/soc.c
index 48e50bd..5da41a9 100644
--- a/src/soc/nvidia/tegra124/soc.c
+++ b/src/soc/nvidia/tegra124/soc.c
@@ -26,6 +26,7 @@
#include <soc/nvidia/tegra124/sdram.h>
#include "chip.h"
#include <soc/display.h>
+#include <symbols.h>
#include <vendorcode/google/chromeos/chromeos.h>
/* this sucks, but for now, fb size/location are hardcoded.
@@ -37,12 +38,12 @@ static void soc_enable(device_t dev)
u32 lcdbase = fb_base_mb();
unsigned long fb_size = FB_SIZE_MB;
- ram_resource(dev, 0, CONFIG_SYS_SDRAM_BASE/KiB,
+ ram_resource(dev, 0, (uintptr_t)_dram/KiB,
(sdram_max_addressable_mb() - fb_size)*KiB -
- CONFIG_SYS_SDRAM_BASE/KiB);
+ (uintptr_t)_dram/KiB);
mmio_resource(dev, 1, lcdbase*KiB, fb_size*KiB);
- u32 sdram_end_mb = sdram_size_mb() + CONFIG_SYS_SDRAM_BASE/MiB;
+ u32 sdram_end_mb = sdram_size_mb() + (uintptr_t)_dram/MiB;
if (sdram_end_mb > sdram_max_addressable_mb())
ram_resource(dev, 2, sdram_max_addressable_mb()*KiB,
diff --git a/src/soc/nvidia/tegra124/verstage.c b/src/soc/nvidia/tegra124/verstage.c
index 60361a2..2e5ddf2 100644
--- a/src/soc/nvidia/tegra124/verstage.c
+++ b/src/soc/nvidia/tegra124/verstage.c
@@ -22,6 +22,8 @@
#include <console/console.h>
#include <soc/nvidia/tegra124/cache.h>
#include <soc/nvidia/tegra124/early_configs.h>
+#include <stdlib.h>
+#include <symbols.h>
#include <vendorcode/google/chromeos/chromeos.h>
static void enable_cache(void)
@@ -29,8 +31,9 @@ static void enable_cache(void)
mmu_init();
/* Whole space is uncached. */
mmu_config_range(0, 4096, DCACHE_OFF);
- /* SRAM is cached. Round the size up to 2MB, the LPAE page size. */
- mmu_config_range(0x40000000 >> 20, 1, DCACHE_WRITEBACK);
+ /* SRAM is cached. MMU code will round size up to page size. */
+ mmu_config_range((uintptr_t)_sram/MiB, div_round_up(_sram_size, MiB),
+ DCACHE_WRITEBACK);
mmu_disable_range(0, 1);
dcache_mmu_enable();
}
diff --git a/src/soc/nvidia/tegra132/Kconfig b/src/soc/nvidia/tegra132/Kconfig
index 24bf864..c87698a 100644
--- a/src/soc/nvidia/tegra132/Kconfig
+++ b/src/soc/nvidia/tegra132/Kconfig
@@ -43,50 +43,6 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x40080
-config BOOTBLOCK_BASE
- hex
- default 0x40020000
-
-config ROMSTAGE_BASE
- hex
- default 0x40025000
-
-config SYS_SDRAM_BASE
- hex
- default 0x80000000
-
-config RAMSTAGE_BASE
- hex
- default 0x80200000
-
-config BOOTBLOCK_STACK_TOP
- hex
- default 0x40020000
-
-config BOOTBLOCK_STACK_BOTTOM
- hex
- default 0x4001c000
-
-config ROMSTAGE_STACK_TOP
- hex
- default 0x40020000
-
-config ROMSTAGE_STACK_BOTTOM
- hex
- default 0x4001c000
-
-config CBFS_CACHE_ADDRESS
- hex "memory address to put CBFS cache data"
- default 0x40006000
-
-config CBFS_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00016000
-
-config CONSOLE_PRERAM_BUFFER_BASE
- hex "memory address of the CBMEM console buffer"
- default 0x40004020
-
config MTS_DIRECTORY
string "Directory where MTS microcode files are located"
default "3rdparty/cpu/nvidia/tegra132/current/prod"
diff --git a/src/soc/nvidia/tegra132/Makefile.inc b/src/soc/nvidia/tegra132/Makefile.inc
index 10d4d4e..81d08f5 100644
--- a/src/soc/nvidia/tegra132/Makefile.inc
+++ b/src/soc/nvidia/tegra132/Makefile.inc
@@ -114,7 +114,7 @@ $(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin $(BCT_BIN) $(CBOOTIMAGE)
echo "Bctcopy = 1;" >> $(BCT_WRAPPER)
echo "Bctfile = $(BCT_BIN);" >> $(BCT_WRAPPER)
echo "MtsPreboot = $(PREBOOT_MTS_FILE),0x4000f000,0x4000f000,Complete;" >> $(BCT_WRAPPER)
- echo "BootLoader = $<,$(CONFIG_BOOTBLOCK_BASE),$(CONFIG_BOOTBLOCK_BASE),Complete;" >> $(BCT_WRAPPER)
+ echo "BootLoader = $<,$(call loadaddr,bootblock),$(call loadaddr,bootblock),Complete;" >> $(BCT_WRAPPER)
@printf " CBOOTIMAGE $(subst $(obj)/,,$(@))\n"
$(CBOOTIMAGE) $(CBOOTIMAGE_OPTS) $(BCT_WRAPPER) $@
diff --git a/src/soc/nvidia/tegra132/addressmap.c b/src/soc/nvidia/tegra132/addressmap.c
index a18e1b8..bd644d4 100644
--- a/src/soc/nvidia/tegra132/addressmap.c
+++ b/src/soc/nvidia/tegra132/addressmap.c
@@ -23,6 +23,7 @@
#include <console/console.h>
#include <soc/addressmap.h>
#include <soc/id.h>
+#include <symbols.h>
#include "mc.h"
#include "sdram.h"
@@ -105,7 +106,7 @@ static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib,
uintptr_t end;
int i;
- base = CONFIG_SYS_SDRAM_BASE / MiB;
+ base = (uintptr_t)_dram / MiB;
end = base + sdram_size_mb();
/* Requested limits out of range. */
diff --git a/src/soc/nvidia/tegra132/bootblock_asm.S b/src/soc/nvidia/tegra132/bootblock_asm.S
index 1b2fbb7..bf63c02 100644
--- a/src/soc/nvidia/tegra132/bootblock_asm.S
+++ b/src/soc/nvidia/tegra132/bootblock_asm.S
@@ -42,17 +42,5 @@ ENTRY(_start)
*/
msr cpsr_cxf, #0xdf
- stack_init stack=.Stack size=.Stack_size seed=1 func=main
+ stack_init stack_top=_estack stack_bottom=_stack seed=1 func=main
ENDPROC(_start)
-
-/* we do it this way because it's a 32-bit constant and
- * in some cases too far away to be loaded as just an offset
- * from IP
- */
-.align 2
-.Stack:
- .word CONFIG_BOOTBLOCK_STACK_TOP
-.align 2
-/* create this size the same way we do in ramstage.ld: top-bottom */
-.Stack_size:
- .word CONFIG_BOOTBLOCK_STACK_TOP - CONFIG_BOOTBLOCK_STACK_BOTTOM
diff --git a/src/soc/nvidia/tegra132/cbfs.c b/src/soc/nvidia/tegra132/cbfs.c
index 7b75f7c..648d136 100644
--- a/src/soc/nvidia/tegra132/cbfs.c
+++ b/src/soc/nvidia/tegra132/cbfs.c
@@ -19,12 +19,12 @@
#include <cbfs.h> /* This driver serves as a CBFS media source. */
+#include <symbols.h>
#include "spi.h"
int init_default_cbfs_media(struct cbfs_media *media)
{
return initialize_tegra_spi_cbfs_media(media,
- (void*)CONFIG_CBFS_CACHE_ADDRESS,
- CONFIG_CBFS_CACHE_SIZE);
+ _cbfs_cache, _cbfs_cache_size);
}
diff --git a/src/soc/nvidia/tegra132/memlayout.ld b/src/soc/nvidia/tegra132/memlayout.ld
new file mode 100644
index 0000000..63cf4f0
--- /dev/null
+++ b/src/soc/nvidia/tegra132/memlayout.ld
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+/*
+ * Note: The BootROM uses the address range [0x4000_0000:0x4000_E000) itself,
+ * so the bootblock loading address must be placed after that. After the
+ * handoff that area may be reclaimed for other uses, e.g. CBFS cache.
+ * TODO: Did this change on Tegra132? What's the new valid range?
+ */
+
+SECTIONS
+{
+ SRAM_START(0x40000000)
+ /* 16K hole */
+ PRERAM_CBMEM_CONSOLE(0x40004000, 8K)
+ CBFS_CACHE(0x40006000, 88K)
+ STACK(0x4001C000, 16K)
+ BOOTBLOCK(0x40020000, 20K)
+ ROMSTAGE(0x40025000, 108K)
+ SRAM_END(0x40040000)
+
+ DRAM_START(0x80000000)
+ RAMSTAGE(0x80200000, 192K)
+}
diff --git a/src/soc/nvidia/tegra132/romstage_asm.S b/src/soc/nvidia/tegra132/romstage_asm.S
index ac3c93e..d0b036c 100644
--- a/src/soc/nvidia/tegra132/romstage_asm.S
+++ b/src/soc/nvidia/tegra132/romstage_asm.S
@@ -23,17 +23,5 @@
.section ".text", "ax", %progbits
ENTRY(main)
- stack_init stack=.Stack size=.Stack_size seed=0 func=romstage
+ stack_init stack_top=_estack stack_bottom=_stack seed=0 func=romstage
ENDPROC(main)
-
-/* we do it this way because it's a 32-bit constant and
- * in some cases too far away to be loaded as just an offset
- * from IP
- */
-.align 2
-.Stack:
- .word CONFIG_ROMSTAGE_STACK_TOP
-.align 2
-.Stack_size:
- .word CONFIG_ROMSTAGE_STACK_TOP - CONFIG_ROMSTAGE_STACK_BOTTOM
-
diff --git a/src/soc/nvidia/tegra132/stack.S b/src/soc/nvidia/tegra132/stack.S
index 6d3cd4e..3b877e4 100644
--- a/src/soc/nvidia/tegra132/stack.S
+++ b/src/soc/nvidia/tegra132/stack.S
@@ -19,21 +19,19 @@
/* Macro to initialize stack, perform seeding if required and finally call the
* function provided
- * @stack : Stack address
- * @size : Stack size
- * @seed : Stack seeding required (1=yes/otherwise=no)
- * @func : Function to call after initializing stack
+ * @stack_top : First address above the stack
+ * @stack_bottom : Lowest address on the stack
+ * @seed : Stack seeding required (1=yes/otherwise=no)
+ * @func : Function to call after initializing stack
*/
-.macro stack_init stack, size, seed, func
+.macro stack_init stack_top, stack_bottom, seed, func
/* Check if stack seeding is required */
mov r0, #\seed
cmp r0, #1
bne call_func
/* Stack seeding */
- ldr r0, \stack
- ldr r1, \size
- sub r0, r0, r1
- ldr r1, \stack
+ ldr r0, =\stack_bottom
+ ldr r1, =\stack_top
ldr r2, =0xdeadbeef
init_stack_loop:
str r2, [r0]
@@ -42,6 +40,6 @@ init_stack_loop:
bne init_stack_loop
call_func:
- ldr sp, \stack /* Set up stack pointer */
+ ldr sp, =\stack_top /* Set up stack pointer */
bl \func
.endm
diff --git a/src/soc/qualcomm/ipq806x/Kconfig b/src/soc/qualcomm/ipq806x/Kconfig
index 013d86c..092951d 100644
--- a/src/soc/qualcomm/ipq806x/Kconfig
+++ b/src/soc/qualcomm/ipq806x/Kconfig
@@ -39,44 +39,4 @@ config SBL_BLOB
ipq806x early initialization code, as supplied by the
vendor.
-config BOOTBLOCK_BASE
- hex "256K bytes left for TZBSP"
- default 0x40600000
-
-config ROMSTAGE_BASE
- hex
- default 0x40620000
-
-config RAMSTAGE_BASE
- hex
- default 0x40640000
-
-config SYS_SDRAM_BASE
- hex
- default 0x40000000
-
-config CBMEM_CONSOLE_PRERAM_BASE
- hex "memory address of the pre-RAM CBMEM console buffer"
- default 0x40618000
-
-config STACK_TOP
- hex
- default 0x40600000
-
-config STACK_BOTTOM
- hex
- default 0x405fc000
-
-config CBFS_CACHE_ADDRESS
- hex "memory address to put CBFS cache data"
- default 0x405cc000
-
-config CBFS_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00030000
-
-config TTB_BUFFER
- hex "memory address for page tables"
- default 0x2a05c000
-
endif
diff --git a/src/soc/qualcomm/ipq806x/Makefile.inc b/src/soc/qualcomm/ipq806x/Makefile.inc
index a7dabc6..5dfca4d 100644
--- a/src/soc/qualcomm/ipq806x/Makefile.inc
+++ b/src/soc/qualcomm/ipq806x/Makefile.inc
@@ -51,7 +51,7 @@ $(objcbfs)/bootblock.raw: $(objcbfs)/bootblock.elf
# Add MBN header to allow SBL3 to start coreboot bootblock
$(objcbfs)/bootblock.mbn: $(objcbfs)/bootblock.raw
@printf " ADD MBN $(subst $(obj)/,,$(@))\n"
- ./util/ipqheader/ipqheader.py $(CONFIG_BOOTBLOCK_BASE) $< $@.tmp
+ ./util/ipqheader/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp
@mv $@.tmp $@
# Create a complete bootblock which will start up the system
diff --git a/src/soc/qualcomm/ipq806x/cbmem.c b/src/soc/qualcomm/ipq806x/cbmem.c
index ecb02e4..fdf2605 100644
--- a/src/soc/qualcomm/ipq806x/cbmem.c
+++ b/src/soc/qualcomm/ipq806x/cbmem.c
@@ -19,9 +19,9 @@
#include <cbmem.h>
#include <stddef.h>
+#include <symbols.h>
void *cbmem_top(void)
{
- return (void *)((uintptr_t)CONFIG_SYS_SDRAM_BASE +
- (CONFIG_DRAM_SIZE_MB << 20));
+ return (void *)((uintptr_t)_dram + CONFIG_DRAM_SIZE_MB*MiB);
}
diff --git a/src/soc/qualcomm/ipq806x/memlayout.ld b/src/soc/qualcomm/ipq806x/memlayout.ld
new file mode 100644
index 0000000..3059603
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/memlayout.ld
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+/* TODO: This should be revised by someone who understands the SoC better. */
+
+SECTIONS
+{
+ /* TODO: add SRAM_START(), SRAM_END() and REGION(reserved_sbl) */
+ TTB(0x2A05C000, 48K)
+
+ DRAM_START(0x40000000)
+ CBFS_CACHE(0x405CC000, 192K)
+ STACK(0x405FC000, 16K)
+ /* TODO: "256K bytes left for TZBSP"... what does that mean? */
+ BOOTBLOCK(0x40600000, 32K)
+ PRERAM_CBMEM_CONSOLE(0x40618000, 8K)
+ ROMSTAGE(0x40620000, 128K)
+ RAMSTAGE(0x40640000, 128K)
+ DMA_COHERENT(0x5A000000, 2M)
+}
diff --git a/src/soc/qualcomm/ipq806x/soc.c b/src/soc/qualcomm/ipq806x/soc.c
index 6421ccd..1d63cac 100644
--- a/src/soc/qualcomm/ipq806x/soc.c
+++ b/src/soc/qualcomm/ipq806x/soc.c
@@ -21,16 +21,15 @@
#include <console/console.h>
#include <device/device.h>
-
+#include <symbols.h>
#define RESERVED_SIZE_KB (0x01500000 / KiB)
static void soc_read_resources(device_t dev)
{
/* Reserve bottom 0x150_0000 bytes for NSS, SMEM, etc. */
- reserved_ram_resource(dev, 0,
- CONFIG_SYS_SDRAM_BASE/KiB, RESERVED_SIZE_KB);
- ram_resource(dev, 0, CONFIG_SYS_SDRAM_BASE/KiB + RESERVED_SIZE_KB,
+ reserved_ram_resource(dev, 0, (uintptr_t)_dram / KiB, RESERVED_SIZE_KB);
+ ram_resource(dev, 0, (uintptr_t)_dram / KiB + RESERVED_SIZE_KB,
(CONFIG_DRAM_SIZE_MB * KiB) - RESERVED_SIZE_KB);
}
diff --git a/src/soc/rockchip/rk3288/Kconfig b/src/soc/rockchip/rk3288/Kconfig
index 05876f4..0865fe8 100644
--- a/src/soc/rockchip/rk3288/Kconfig
+++ b/src/soc/rockchip/rk3288/Kconfig
@@ -41,51 +41,6 @@ config BOOTBLOCK_CPU_INIT
# 0x00000 Combined bootblock and ID Block
# 0x08000 Master CBFS header.
# 0x18000 Free for CBFS data.
-#
-# iRAM (96k) layout.
-# (Note: The BootROM will jump to 0xff704004 after loading bootblock,
-# so the bootblock loading address must be at 0xff704004.)
-#
-# 0xFF70_0000 TTB (16KB).
-# 0xFF70_4004 Bootblock (max 16KB-4B).
-# 0xFF70_8000 verstage then romstage (max 40KB).
-# 0xFF71_2000 STACK (4KB).
-# 0xFF71_3000 CBFS mapping cache (4K)
-# 0xFF71_4000 vboot work buffer (16K)
-# 0xFF71_7FFF End of iRAM.
-
-config SYS_SRAM_BASE
- hex "SRAM base address"
- default 0xFF700000
-
-config SYS_SDRAM_BASE
- hex "SDRAM base address"
- default 0x00000000
-
-config STACK_TOP
- hex "STACK TOP"
- default 0xff713000
-
-config STACK_BOTTOM
- hex "STACK BOTTOM"
- default 0xff712000
-
-config BOOTBLOCK_BASE
- hex
- default 0xff704004
-
-# with vboot2, romstage is loaded over the verstage space
-config VERSTAGE_BASE
- hex
- default 0xff708000
-
-config ROMSTAGE_BASE
- hex "ROM STAGE BASE"
- default 0xff708000
-
-config RAMSTAGE_BASE
- hex "RAMSTAGE BASE"
- default 0x00200000
config BOOTBLOCK_ROM_OFFSET
hex
@@ -99,32 +54,4 @@ config CBFS_ROM_OFFSET
hex
default 0x0018000
-config CBFS_SRAM_CACHE_ADDRESS
- hex "sram memory address to put CBFS cache data"
- default 0xff713000
-
-config CBFS_SRAM_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00001000
-
-config VBOOT_WORK_BUFFER_ADDRESS
- hex "memory address of vboot work buffer"
- default 0xff714000
-
-config VBOOT_WORK_BUFFER_SIZE
- hex "size of vboot work buffer"
- default 0x00004000
-
-config CBFS_DRAM_CACHE_ADDRESS
- hex "dram memory address to put CBFS cache data"
- default 0x01000000
-
-config CBFS_DRAM_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00100000
-
-config TTB_BUFFER
- hex "memory address of the TTB buffer"
- default 0xff700000
-
endif
diff --git a/src/soc/rockchip/rk3288/media.c b/src/soc/rockchip/rk3288/media.c
index 2b023e1..f2471f9 100644
--- a/src/soc/rockchip/rk3288/media.c
+++ b/src/soc/rockchip/rk3288/media.c
@@ -18,19 +18,12 @@
*/
#include <cbfs.h>
-#include <string.h>
-#include <console/console.h>
-#include "soc/rockchip/rk3288/spi.h"
+#include <symbols.h>
+
+#include "spi.h"
int init_default_cbfs_media(struct cbfs_media *media)
{
-#if defined(__PRE_RAM__) && !defined(__ROMSTAGE__)
- return initialize_rockchip_spi_cbfs_media(media,
- (void *)CONFIG_CBFS_SRAM_CACHE_ADDRESS,
- CONFIG_CBFS_SRAM_CACHE_SIZE);
-#else
return initialize_rockchip_spi_cbfs_media(media,
- (void *)CONFIG_CBFS_DRAM_CACHE_ADDRESS,
- CONFIG_CBFS_DRAM_CACHE_SIZE);
-#endif
+ _cbfs_cache, _cbfs_cache_size);
}
diff --git a/src/soc/rockchip/rk3288/memlayout.ld b/src/soc/rockchip/rk3288/memlayout.ld
new file mode 100644
index 0000000..6faec63
--- /dev/null
+++ b/src/soc/rockchip/rk3288/memlayout.ld
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+#include <vendorcode/google/chromeos/memlayout.h>
+
+#include <arch/header.ld>
+
+/* Note: The BootROM will jump to 0xFF704004 after loading bootblock,
+ * so the bootblock loading address must be at 0xFF704004.
+ */
+SECTIONS
+{
+ DRAM_START(0x00000000)
+ RAMSTAGE(0x00200000, 128K)
+ POSTRAM_CBFS_CACHE(0x01000000, 1M)
+ DMA_COHERENT(0x10000000, 2M)
+
+ SRAM_START(0xFF700000)
+ TTB(0xFF700000, 16K)
+ BOOTBLOCK(0xFF704004, 16K - 4)
+ VBOOT2_WORK(0xFF708000, 16K)
+ OVERLAP_VERSTAGE_ROMSTAGE(0xFF70C000, 40K)
+ PRERAM_CBFS_CACHE(0xFF716000, 4K)
+ STACK(0xFF717000, 4K)
+ SRAM_END(0xFF718000)
+
+ /* 4K of special SRAM in PMU power domain. Careful: only supports 32-bit
+ * wide write accesses! Only use with MMU and writeback mapping. */
+ SYMBOL(pmu_sram, 0xFF720000)
+ SYMBOL(epmu_sram, 0xFF721000)
+}
diff --git a/src/soc/rockchip/rk3288/soc.h b/src/soc/rockchip/rk3288/soc.h
index 3121fd8..00f35b2 100644
--- a/src/soc/rockchip/rk3288/soc.h
+++ b/src/soc/rockchip/rk3288/soc.h
@@ -21,13 +21,14 @@
#define __SOC_ROCKCHIP_RK3288_CPU_H__
#include <arch/io.h>
+#include <symbols.h>
#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set)
#define RK_SETBITS(set) RK_CLRSETBITS(0, set)
#define RK_CLRBITS(clr) RK_CLRSETBITS(clr, 0)
#define FB_SIZE_KB 4096
-#define RAM_BASE_KB (CONFIG_SYS_SDRAM_BASE >> 10)
+#define RAM_BASE_KB ((uintptr_t)_dram >> 10)
#define RAM_SIZE_KB (CONFIG_DRAM_SIZE_MB << 10UL)
static inline u32 get_fb_base_kb(void)
diff --git a/src/soc/samsung/exynos5250/Kconfig b/src/soc/samsung/exynos5250/Kconfig
index 3c7d6c4..4126ec1 100644
--- a/src/soc/samsung/exynos5250/Kconfig
+++ b/src/soc/samsung/exynos5250/Kconfig
@@ -32,59 +32,4 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x0A080
-config SYS_SDRAM_BASE
- hex
- default 0x40000000
-
-# Example SRAM/iRAM map for Exynos5250 platform:
-#
-# 0x0202_0000: vendor-provided BL1
-# 0x0202_3400: bootblock, assume up to 32KB in size
-# 0x0203_0000: romstage, assume up to 128KB in size.
-# 0x0207_8000: stack pointer
-
-config BOOTBLOCK_BASE
- hex
- default 0x02023400
-
-config ROMSTAGE_BASE
- hex
- default 0x02030000
-
-config RAMSTAGE_BASE
- hex
- default SYS_SDRAM_BASE
-
-# Stack may reside in either IRAM or DRAM. We will define it to live
-# at the top of IRAM for now.
-#
-# Stack grows downward, push operation stores register contents in
-# consecutive memory locations ending just below SP
-config STACK_TOP
- hex
- default 0x02078000
-
-config STACK_BOTTOM
- hex
- default 0x02074000
-
-config STACK_SIZE
- hex
- default 0x4000
-
-# TODO We may probably move this to board-specific implementation files instead
-# of KConfig values.
-config CBFS_CACHE_ADDRESS
- hex "memory address to put CBFS cache data"
- default 0x0205c000
-
-config CBFS_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00018000
-
-# TTB needs to be aligned to 16KB.
-config TTB_BUFFER
- hex "memory address of the TTB buffer"
- default 0x02058000
-
endif
diff --git a/src/soc/samsung/exynos5250/alternate_cbfs.c b/src/soc/samsung/exynos5250/alternate_cbfs.c
index 10b33f0..e46221c 100644
--- a/src/soc/samsung/exynos5250/alternate_cbfs.c
+++ b/src/soc/samsung/exynos5250/alternate_cbfs.c
@@ -22,6 +22,7 @@
#include <cbfs.h> /* This driver serves as a CBFS media source. */
#include <stdlib.h>
#include <string.h>
+#include <symbols.h>
#include <console/console.h>
#include "alternate_cbfs.h"
#include "power.h"
@@ -33,14 +34,14 @@
* by the IROM / BL1, so this code has nothing to do with them.
*
* The third transfer is a valid CBFS image that contains only the romstage,
- * and must be small enough to fit into alternate_cbfs_size[__BOOT_BLOCK__] in
+ * and must be small enough to fit into the PRE_RAM CBFS cache in
* IRAM. It is loaded when this function gets called in the boot block, and
* the normal CBFS code extracts the romstage from it.
*
* The fourth transfer is also a CBFS image, but can be of arbitrary size and
* should contain all available stages/payloads/etc. It is loaded when this
* function is called a second time at the end of the romstage, and copied to
- * alternate_cbfs_buffer[!__BOOT_BLOCK__] in DRAM. It will reside there for the
+ * the romstage/ramstage CBFS cache in DRAM. It will reside there for the
* rest of the firmware's lifetime and all subsequent stages (which will not
* have __PRE_RAM__ defined) can just directly reference it there.
*/
@@ -60,12 +61,12 @@ static int usb_cbfs_open(struct cbfs_media *media)
/*
* We need to trust the host/irom to copy the image to our
- * alternate_cbfs_buffer address... there is no way to control or even
+ * _cbfs_cache address... there is no way to control or even
* check the transfer size or target address from our side.
*/
printk(BIOS_DEBUG, "USB A-A transfer successful, CBFS image should now"
- " be at %p\n", alternate_cbfs_buffer);
+ " be at %p\n", _cbfs_cache);
first_run = 0;
#endif
return 0;
@@ -86,11 +87,11 @@ static int sdmmc_cbfs_open(struct cbfs_media *media)
* In the bootblock, we just copy the small part that fits in the buffer
* and hope that it's enough (since the romstage is currently always the
* first component in the image, this should work out). In the romstage,
- * we copy until our buffer is full (currently 12M) to avoid the pain of
+ * we copy until our cache is full (currently 12M) to avoid the pain of
* figuring out the true image size from in here. Since this is mainly a
* developer/debug boot mode, those shortcomings should be bearable.
*/
- const u32 count = alternate_cbfs_size / 512;
+ const u32 count = _cbfs_cache_size / 512;
static int first_run = 1;
int (*irom_load_sdmmc)(u32 start, u32 count, void *dst) =
*irom_sdmmc_read_blocks_ptr;
@@ -98,13 +99,13 @@ static int sdmmc_cbfs_open(struct cbfs_media *media)
if (!first_run)
return 0;
- if (!irom_load_sdmmc(1, count, alternate_cbfs_buffer)) {
+ if (!irom_load_sdmmc(1, count, _cbfs_cache)) {
printk(BIOS_EMERG, "Unable to load CBFS image from SDMMC!\n");
return -1;
}
printk(BIOS_DEBUG, "SDMMC read successful, CBFS image should now be"
- " at %p\n", alternate_cbfs_buffer);
+ " at %p\n", _cbfs_cache);
first_run = 0;
#endif
return 0;
@@ -115,16 +116,16 @@ static int alternate_cbfs_close(struct cbfs_media *media) { return 0; }
static size_t alternate_cbfs_read(struct cbfs_media *media, void *dest,
size_t offset, size_t count)
{
- ASSERT(offset + count < alternate_cbfs_size);
- memcpy(dest, alternate_cbfs_buffer + offset, count);
+ ASSERT(offset + count < _cbfs_cache_size);
+ memcpy(dest, _cbfs_cache + offset, count);
return count;
}
static void *alternate_cbfs_map(struct cbfs_media *media, size_t offset,
size_t count)
{
- ASSERT(offset + count < alternate_cbfs_size);
- return alternate_cbfs_buffer + offset;
+ ASSERT(offset + count < _cbfs_cache_size);
+ return _cbfs_cache + offset;
}
static void *alternate_cbfs_unmap(struct cbfs_media *media,
@@ -166,8 +167,7 @@ int init_default_cbfs_media(struct cbfs_media *media)
return initialize_exynos_sdmmc_cbfs_media(media);
case OM_STAT_SPI:
return initialize_exynos_spi_cbfs_media(media,
- (void*)CONFIG_CBFS_CACHE_ADDRESS,
- CONFIG_CBFS_CACHE_SIZE);
+ _cbfs_cache, _cbfs_cache_size);
default:
printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n",
exynos_power->om_stat);
diff --git a/src/soc/samsung/exynos5250/alternate_cbfs.h b/src/soc/samsung/exynos5250/alternate_cbfs.h
index a064b62..fe1af46 100644
--- a/src/soc/samsung/exynos5250/alternate_cbfs.h
+++ b/src/soc/samsung/exynos5250/alternate_cbfs.h
@@ -36,16 +36,4 @@ static u32 * const iram_secondary_base = (u32 *)0x02020018;
#define OM_STAT_SPI 0x14
#define OM_STAT_MASK 0x7f
-#if defined(__PRE_RAM__) && !defined(__ROMSTAGE__)
- /* A small space in IRAM to hold the romstage-only image */
- static void * const alternate_cbfs_buffer =
- (void *)CONFIG_CBFS_CACHE_ADDRESS;
- static size_t const alternate_cbfs_size = CONFIG_CBFS_CACHE_SIZE;
-#else
- /* Just put this anywhere in RAM that's far enough from anything else */
- /* TODO: Find a better way to "reserve" this region? */
- static void * const alternate_cbfs_buffer = (void *)0x77400000;
- static size_t const alternate_cbfs_size = 0xc00000;
-#endif
-
#endif
diff --git a/src/soc/samsung/exynos5250/cpu.h b/src/soc/samsung/exynos5250/cpu.h
index 10f9ef4..c9c5832 100644
--- a/src/soc/samsung/exynos5250/cpu.h
+++ b/src/soc/samsung/exynos5250/cpu.h
@@ -21,6 +21,7 @@
#define CPU_SAMSUNG_EXYNOS5250_CPU_H
#include <arch/io.h>
+#include <symbols.h>
/* Base address registers */
#define EXYNOS5_GPIO_PART6_BASE 0x03860000 /* Z<6:0> */
@@ -76,7 +77,7 @@ extern struct tmu_info exynos5250_tmu_info;
/* TODO clean up defines. */
#define FB_SIZE_KB 4096
-#define RAM_BASE_KB (CONFIG_SYS_SDRAM_BASE >> 10)
+#define RAM_BASE_KB ((uintptr_t)_dram/KiB)
#define RAM_SIZE_KB (CONFIG_DRAM_SIZE_MB << 10UL)
static inline u32 get_fb_base_kb(void)
diff --git a/src/soc/samsung/exynos5250/memlayout.ld b/src/soc/samsung/exynos5250/memlayout.ld
new file mode 100644
index 0000000..010bb7b
--- /dev/null
+++ b/src/soc/samsung/exynos5250/memlayout.ld
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+/*
+ * Note: The BootROM loads the 8K BL1 at [0x2020000:0x2022000), so the bootblock
+ * must be placed after that. After the handoff, the space can be reclaimed.
+ */
+
+SECTIONS
+{
+ SRAM_START(0x2020000)
+ /* 13K hole, includes BL1 */
+ BOOTBLOCK(0x2023400, 32K)
+ /* 19K hole */
+ ROMSTAGE(0x2030000, 128K)
+ /* 32K hole */
+ TTB(0x2058000, 16K)
+ PRERAM_CBFS_CACHE(0x205C000, 96K)
+ STACK(0x2074000, 16K)
+ SRAM_END(0x2078000)
+
+ DRAM_START(0x40000000)
+ RAMSTAGE(0x40000000, 128K)
+ POSTRAM_CBFS_CACHE(0x41000000, 8M)
+ DMA_COHERENT(0x77300000, 1M)
+}
diff --git a/src/soc/samsung/exynos5420/Kconfig b/src/soc/samsung/exynos5420/Kconfig
index bd2bf13..ed9d2f8 100644
--- a/src/soc/samsung/exynos5420/Kconfig
+++ b/src/soc/samsung/exynos5420/Kconfig
@@ -33,78 +33,4 @@ config CBFS_ROM_OFFSET
hex "offset of CBFS data in ROM"
default 0x0A000
-config SYS_SDRAM_BASE
- hex
- default 0x20000000
-
-# Example SRAM/iRAM map for Exynos5420 platform:
-#
-# 0x0202_0000: vendor-provided BL1
-# 0x0202_4400: variable length bootblock checksum header.
-# 0x0202_4410: bootblock, assume up to 32KB in size
-# 0x0203_0000: romstage, assume up to 128KB in size.
-# 0x0205_8000: TTB buffer.
-# 0x0205_c000: cache for CBFS data.
-# 0x0206_f000: stack bottom
-# 0x0207_3000: stack pointer
-# 0x0207_3000: shared (with kernel) page for cpu & secondary core states.
-# the shared data is currently only <0x50 bytes so we can share
-# this page with stack.
-
-config BOOTBLOCK_BASE
- hex
- default 0x02024410
-
-config ROMSTAGE_BASE
- hex
- default 0x02030000
-
-config RAMSTAGE_BASE
- hex
- default SYS_SDRAM_BASE
-
-# Stack may reside in either IRAM or DRAM. We will define it to live
-# at the top of IRAM for now.
-#
-# Stack grows downward, push operation stores register contents in
-# consecutive memory locations ending just below SP.
-# The setup in the exynos 5420 is a new one for coreboot. We have got
-# the bootblock, romstage, and ramstage sharing the same stack space.
-# The SRAM is always there and having a known-good stack memory
-# makes for a more reliable setup.
-# Thus, in this case:
-# STACK_TOP: highest stack address in SRAM
-# STACK_BOTTOM: lowest stack address in SRAM
-# STACK_SIZE: as in standard coreboot usage, size of thread stacks in ramstage
-# ROMSTAGE_STACK_SIZE: size of the single stack in romstage
-
-config STACK_TOP
- hex
- default 0x02073000
-
-config STACK_BOTTOM
- hex
- default 0x0206f000
-
-# STACK_SIZE is for the ramstage core and thread stacks.
-# It must be a power of 2, to make the cpu_info computation work,
-# and cpu_info needs to work to make SMP startup and threads work.
-config STACK_SIZE
- hex
- default 0x0800
-
-# TODO We may probably move this to board-specific implementation files instead
-# of KConfig values.
-config CBFS_CACHE_ADDRESS
- hex "memory address to put CBFS cache data"
- default 0x0205c000
-
-config CBFS_CACHE_SIZE
- hex "size of CBFS cache data"
- default 0x00013000
-
-config TTB_BUFFER
- hex "memory address of the TTB buffer"
- default 0x02058000
-
endif
diff --git a/src/soc/samsung/exynos5420/alternate_cbfs.c b/src/soc/samsung/exynos5420/alternate_cbfs.c
index d19098b..7fc0e6d 100644
--- a/src/soc/samsung/exynos5420/alternate_cbfs.c
+++ b/src/soc/samsung/exynos5420/alternate_cbfs.c
@@ -22,6 +22,7 @@
#include <cbfs.h> /* This driver serves as a CBFS media source. */
#include <stdlib.h>
#include <string.h>
+#include <symbols.h>
#include <arch/cache.h>
#include <console/console.h>
#include "alternate_cbfs.h"
@@ -34,14 +35,14 @@
* by the IROM / BL1, so this code has nothing to do with them.
*
* The third transfer is a valid CBFS image that contains only the romstage,
- * and must be small enough to fit into alternate_cbfs_size[__BOOT_BLOCK__] in
+ * and must be small enough to fit into the PRE_RAM CBFS cache in
* IRAM. It is loaded when this function gets called in the boot block, and
* the normal CBFS code extracts the romstage from it.
*
* The fourth transfer is also a CBFS image, but can be of arbitrary size and
* should contain all available stages/payloads/etc. It is loaded when this
* function is called a second time at the end of the romstage, and copied to
- * alternate_cbfs_buffer[!__BOOT_BLOCK__] in DRAM. It will reside there for the
+ * the romstage/ramstage CBFS cache in DRAM. It will reside there for the
* rest of the firmware's lifetime and all subsequent stages (which will not
* have __PRE_RAM__ defined) can just directly reference it there.
*/
@@ -64,12 +65,12 @@ static int usb_cbfs_open(struct cbfs_media *media)
/*
* We need to trust the host/irom to copy the image to our
- * alternate_cbfs_buffer address... there is no way to control or even
+ * _cbfs_cache address... there is no way to control or even
* check the transfer size or target address from our side.
*/
printk(BIOS_DEBUG, "USB A-A transfer successful, CBFS image should now"
- " be at %p\n", alternate_cbfs_buffer);
+ " be at %p\n", _cbfs_cache);
first_run = 0;
#endif
return 0;
@@ -90,11 +91,11 @@ static int sdmmc_cbfs_open(struct cbfs_media *media)
* In the bootblock, we just copy the small part that fits in the buffer
* and hope that it's enough (since the romstage is currently always the
* first component in the image, this should work out). In the romstage,
- * we copy until our buffer is full (currently 12M) to avoid the pain of
+ * we copy until our cache is full (currently 12M) to avoid the pain of
* figuring out the true image size from in here. Since this is mainly a
* developer/debug boot mode, those shortcomings should be bearable.
*/
- const u32 count = alternate_cbfs_size / 512;
+ const u32 count = _cbfs_cache_size / 512;
static int first_run = 1;
int (*irom_load_sdmmc)(u32 start, u32 count, void *dst) =
*irom_sdmmc_read_blocks_ptr;
@@ -103,7 +104,7 @@ static int sdmmc_cbfs_open(struct cbfs_media *media)
return 0;
dcache_mmu_disable();
- if (!irom_load_sdmmc(1, count, alternate_cbfs_buffer)) {
+ if (!irom_load_sdmmc(1, count, _cbfs_cache)) {
dcache_mmu_enable();
printk(BIOS_EMERG, "Unable to load CBFS image from SDMMC!\n");
return -1;
@@ -111,7 +112,7 @@ static int sdmmc_cbfs_open(struct cbfs_media *media)
dcache_mmu_enable();
printk(BIOS_DEBUG, "SDMMC read successful, CBFS image should now be"
- " at %p\n", alternate_cbfs_buffer);
+ " at %p\n", _cbfs_cache);
first_run = 0;
#endif
return 0;
@@ -122,16 +123,16 @@ static int alternate_cbfs_close(struct cbfs_media *media) { return 0; }
static size_t alternate_cbfs_read(struct cbfs_media *media, void *dest,
size_t offset, size_t count)
{
- ASSERT(offset + count < alternate_cbfs_size);
- memcpy(dest, alternate_cbfs_buffer + offset, count);
+ ASSERT(offset + count < _cbfs_cache_size);
+ memcpy(dest, _cbfs_cache + offset, count);
return count;
}
static void *alternate_cbfs_map(struct cbfs_media *media, size_t offset,
size_t count)
{
- ASSERT(offset + count < alternate_cbfs_size);
- return alternate_cbfs_buffer + offset;
+ ASSERT(offset + count < _cbfs_cache_size);
+ return _cbfs_cache + offset;
}
static void *alternate_cbfs_unmap(struct cbfs_media *media,
@@ -173,8 +174,7 @@ int init_default_cbfs_media(struct cbfs_media *media)
return initialize_exynos_sdmmc_cbfs_media(media);
case OM_STAT_SPI:
return initialize_exynos_spi_cbfs_media(media,
- (void*)CONFIG_CBFS_CACHE_ADDRESS,
- CONFIG_CBFS_CACHE_SIZE);
+ _cbfs_cache, _cbfs_cache_size);
default:
printk(BIOS_EMERG, "Exynos OM_STAT value 0x%x not supported!\n",
exynos_power->om_stat);
diff --git a/src/soc/samsung/exynos5420/alternate_cbfs.h b/src/soc/samsung/exynos5420/alternate_cbfs.h
index 8122a25..4df61d5 100644
--- a/src/soc/samsung/exynos5420/alternate_cbfs.h
+++ b/src/soc/samsung/exynos5420/alternate_cbfs.h
@@ -36,16 +36,4 @@ static u32 * const iram_secondary_base = (u32 *)0x02020018;
#define OM_STAT_SPI 0x14
#define OM_STAT_MASK 0x7f
-#if defined(__PRE_RAM__) && !defined(__ROMSTAGE__)
- /* A small space in IRAM to hold the romstage-only image */
- static void * const alternate_cbfs_buffer =
- (void *)CONFIG_CBFS_CACHE_ADDRESS;
- static size_t const alternate_cbfs_size = CONFIG_CBFS_CACHE_SIZE;
-#else
- /* Just put this anywhere in RAM that's far enough from anything else */
- /* TODO: Find a better way to "reserve" this region? */
- static void * const alternate_cbfs_buffer = (void *)0x77400000;
- static size_t const alternate_cbfs_size = 0xc00000;
-#endif
-
#endif /* CPU_SAMSUNG_EXYNOS5420_ALTERNATE_CBFS_H */
diff --git a/src/soc/samsung/exynos5420/cpu.h b/src/soc/samsung/exynos5420/cpu.h
index 5b5c731..bea7f1e 100644
--- a/src/soc/samsung/exynos5420/cpu.h
+++ b/src/soc/samsung/exynos5420/cpu.h
@@ -21,6 +21,7 @@
#define CPU_SAMSUNG_EXYNOS5420_CPU_H
#include <arch/io.h>
+#include <symbols.h>
#define EXYNOS5_SRAM_BASE 0x02020000
@@ -84,7 +85,7 @@ extern struct tmu_info exynos5420_tmu_info;
/* TODO clean up defines. */
#define FB_SIZE_KB 4096
-#define RAM_BASE_KB (CONFIG_SYS_SDRAM_BASE >> 10)
+#define RAM_BASE_KB ((uintptr_t)_dram/KiB)
#define RAM_SIZE_KB (CONFIG_DRAM_SIZE_MB << 10UL)
static inline u32 get_fb_base_kb(void)
diff --git a/src/soc/samsung/exynos5420/memlayout.ld b/src/soc/samsung/exynos5420/memlayout.ld
new file mode 100644
index 0000000..3259ff9
--- /dev/null
+++ b/src/soc/samsung/exynos5420/memlayout.ld
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <memlayout.h>
+
+#include <arch/header.ld>
+
+/*
+ * Note: The BootROM loads the 8K BL1 at [0x2020000:0x2022000), so the bootblock
+ * must be placed after that. After the handoff, the space can be reclaimed.
+ */
+
+SECTIONS
+{
+ SRAM_START(0x2020000)
+ /* 17K hole, includes BL1 */
+ /* Bootblock is preceeded by 16 byte variable length BL2 checksum. */
+ BOOTBLOCK(0x2024410, 32K - 16)
+ /* 15K hole */
+ ROMSTAGE(0x2030000, 128K)
+ /* 32K hole */
+ TTB(0x2058000, 16K)
+ PRERAM_CBFS_CACHE(0x205C000, 76K)
+ STACK(0x206F000, 16K)
+ /* 1K hole for weird kernel-shared CPU/SMP state structure that doesn't
+ * seem to be implemented right now? */
+ SRAM_END(0x2074000)
+
+ DRAM_START(0x20000000)
+ RAMSTAGE(0x20000000, 128K)
+ POSTRAM_CBFS_CACHE(0x21000000, 8M)
+ DMA_COHERENT(0x77300000, 1M)
+}
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index c445135..f43a87e 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -110,6 +110,8 @@ verstage-$(CONFIG_CHROMEOS_VBNV_EC) += vbnv_ec.c
verstage-$(CONFIG_CHROMEOS_VBNV_FLASH) += vbnv_flash.c
romstage-y += vboot_handoff.c
+verstage-y += verstage.ld
+
VB_FIRMWARE_ARCH := $(ARCHDIR-$(ARCH-VERSTAGE-y))
VB2_LIB = $(obj)/external/vboot_reference/vboot_fw2.a
VBOOT_CFLAGS += $(patsubst -I%,-I$(top)/%,$(filter-out -include $(src)/include/kconfig.h, $(CFLAGS_verstage) $(CPPFLAGS_verstage)))
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
index edaa0d9..c4d651a 100644
--- a/src/vendorcode/google/chromeos/chromeos.c
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -22,6 +22,7 @@
#include "chromeos.h"
#if CONFIG_VBOOT_VERIFY_FIRMWARE || CONFIG_VBOOT2_VERIFY_FIRMWARE
#include "fmap.h"
+#include "symbols.h"
#include "vboot_handoff.h"
#include <reset.h>
#endif
@@ -253,7 +254,7 @@ void *vboot_load_stage(int stage_index,
struct vb2_working_data * const vboot_get_working_data(void)
{
- return (struct vb2_working_data *)CONFIG_VBOOT_WORK_BUFFER_ADDRESS;
+ return (struct vb2_working_data *)_vboot2_work;
}
void vboot_reboot(void)
diff --git a/src/vendorcode/google/chromeos/memlayout.h b/src/vendorcode/google/chromeos/memlayout.h
new file mode 100644
index 0000000..468f746
--- /dev/null
+++ b/src/vendorcode/google/chromeos/memlayout.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file contains macro definitions for memlayout.ld linker scripts. */
+
+#ifndef __CHROMEOS_MEMLAYOUT_H
+#define __CHROMEOS_MEMLAYOUT_H
+
+#define VBOOT2_WORK(addr, size) \
+ REGION(vboot2_work, addr, size, 4) \
+ _ = ASSERT(size >= 16K, "vboot2 work buffer must be at least 16K!");
+
+#ifdef __VERSTAGE__
+ #define VERSTAGE(addr, sz) \
+ SET_COUNTER(VERSTAGE, addr) \
+ _ = ASSERT(_everstage - _verstage <= sz, \
+ STR(Verstage exceeded its allotted size! (sz))); \
+ INCLUDE "vendorcode/google/chromeos/verstage.verstage.ld"
+#else
+ #define VERSTAGE(addr, sz) \
+ SET_COUNTER(VERSTAGE, addr) \
+ . += sz;
+#endif
+
+#ifdef __VERSTAGE__
+ #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) VERSTAGE(addr, size)
+#else
+ #define OVERLAP_VERSTAGE_ROMSTAGE(addr, size) ROMSTAGE(addr, size)
+#endif
+
+#endif /* __CHROMEOS_MEMLAYOUT_H */
diff --git a/src/vendorcode/google/chromeos/symbols.h b/src/vendorcode/google/chromeos/symbols.h
new file mode 100644
index 0000000..21169f0
--- /dev/null
+++ b/src/vendorcode/google/chromeos/symbols.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef __CHROMEOS_SYMBOLS_H
+#define __CHROMEOS_SYMBOLS_H
+
+extern u8 _vboot2_work[];
+extern u8 _evboot2_work[];
+#define _vboot2_work_size (_evboot2_work - _vboot2_work)
+
+/* Careful: _e<stage> and _<stage>_size only defined for the current stage! */
+extern u8 _verstage[];
+extern u8 _everstage[];
+#define _verstage_size (_everstage - _verstage)
+
+#endif /* __CHROMEOS_SYMBOLS_H */
diff --git a/src/vendorcode/google/chromeos/verstage.ld b/src/vendorcode/google/chromeos/verstage.ld
new file mode 100644
index 0000000..c7fd646
--- /dev/null
+++ b/src/vendorcode/google/chromeos/verstage.ld
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2014 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file is included inside a SECTIONS block */
+
+.text . : {
+ _program = .;
+ _verstage = .;
+ *(.text._start);
+ *(.text.stage_entry);
+ *(.text);
+ *(.text.*);
+} : to_load
+
+.data . : {
+ *(.rodata);
+ *(.rodata.*);
+ *(.data);
+ *(.data.*);
+ . = ALIGN(8);
+}
+
+.bss . : {
+ . = ALIGN(8);
+ _bss = .;
+ *(.bss)
+ *(.bss.*)
+ *(.sbss)
+ *(.sbss.*)
+ _ebss = .;
+ _everstage = .;
+ _eprogram = .;
+}
+
+/* Discard the sections we don't need/want */
+/DISCARD/ : {
+ *(.comment)
+ *(.note)
+ *(.comment.*)
+ *(.note.*)
+ *(.eh_frame);
+}
diff --git a/src/vendorcode/google/chromeos/verstub.c b/src/vendorcode/google/chromeos/verstub.c
index e295b25..eb91c22 100644
--- a/src/vendorcode/google/chromeos/verstub.c
+++ b/src/vendorcode/google/chromeos/verstub.c
@@ -22,17 +22,18 @@
#include <console/console.h>
#include <string.h>
#include "chromeos.h"
+#include "symbols.h"
static struct vb2_working_data *init_vb2_working_data(void)
{
struct vb2_working_data *wd;
wd = vboot_get_working_data();
- memset(wd, 0, CONFIG_VBOOT_WORK_BUFFER_SIZE);
+ memset(wd, 0, _vboot2_work_size);
/* 8-byte alignment for ARMv7 */
wd->buffer = ALIGN_UP((uintptr_t)&wd[1], 8);
- wd->buffer_size = CONFIG_VBOOT_WORK_BUFFER_SIZE + (uintptr_t)wd
- - (uintptr_t)wd->buffer;
+ wd->buffer_size = _vboot2_work_size + (uintptr_t)wd
+ - (uintptr_t)wd->buffer;
return wd;
}