[coreboot-gerrit] Patch set updated for coreboot: 0975b3b i945: consolidate sb & nb early inits

Vladimir Serbinenko (phcoder@gmail.com) gerrit at coreboot.org
Sat Oct 18 12:07:10 CEST 2014


Vladimir Serbinenko (phcoder at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7062

-gerrit

commit 0975b3b297ad5be1d1e3d640ad7b7b8120a3dc60
Author: Vladimir Serbinenko <phcoder at gmail.com>
Date:   Wed Oct 15 20:17:51 2014 +0200

    i945: consolidate sb & nb early inits
    
    Change-Id: I00c2c725de5b982a5e4f584b77b09017a5bc0a72
    Signed-off-by: Vladimir Serbinenko <phcoder at gmail.com>
---
 src/mainboard/apple/macbook21/romstage.c    | 69 ++---------------------------
 src/mainboard/getac/p470/irq_tables.c       | 62 --------------------------
 src/mainboard/getac/p470/romstage.c         | 48 ++------------------
 src/mainboard/ibase/mb899/irq_tables.c      | 60 -------------------------
 src/mainboard/ibase/mb899/romstage.c        | 51 ++-------------------
 src/mainboard/intel/d945gclf/irq_tables.c   | 60 -------------------------
 src/mainboard/intel/d945gclf/romstage.c     | 48 ++------------------
 src/mainboard/kontron/986lcd-m/irq_tables.c | 60 -------------------------
 src/mainboard/kontron/986lcd-m/romstage.c   | 50 ++-------------------
 src/mainboard/lenovo/t60/irq_tables.c       | 61 -------------------------
 src/mainboard/lenovo/t60/romstage.c         | 50 +++------------------
 src/mainboard/lenovo/x60/irq_tables.c       | 61 -------------------------
 src/mainboard/lenovo/x60/romstage.c         | 50 ++-------------------
 src/mainboard/roda/rk886ex/irq_tables.c     | 62 --------------------------
 src/mainboard/roda/rk886ex/romstage.c       | 48 ++------------------
 src/northbridge/intel/i945/early_init.c     | 52 +++++++++++++++++++++-
 src/northbridge/intel/i945/i945.h           |  2 +-
 src/southbridge/intel/i82801gx/early_lpc.c  | 26 +++++++++++
 src/southbridge/intel/i82801gx/i82801gx.h   |  1 +
 19 files changed, 112 insertions(+), 809 deletions(-)

diff --git a/src/mainboard/apple/macbook21/romstage.c b/src/mainboard/apple/macbook21/romstage.c
index e7ff902..7bec26b 100644
--- a/src/mainboard/apple/macbook21/romstage.c
+++ b/src/mainboard/apple/macbook21/romstage.c
@@ -286,12 +286,9 @@ static void early_ich7_init(void)
 
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0;
 	const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x51, 0x52, 0x53 };
 
-
 	timestamp_init(get_initial_timestamp());
 	timestamp_add_now(TS_START_ROMSTAGE);
 
@@ -324,22 +321,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-#if CONFIG_HAVE_ACPI_RESUME
-		printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-		boot_mode = 2;
-		/* Clear SLP_TYPE. This will break stage2 but
-		 * we care for that when we get there.
-		 */
-		outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-
-#else
-		printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-#endif
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -349,7 +331,7 @@ void main(unsigned long bist)
 #endif
 
 	timestamp_add_now(TS_BEFORE_INITRAM);
-	sdram_initialize(boot_mode, spd_addrmap);
+	sdram_initialize(s3resume ? 2 : 0, spd_addrmap);
 	timestamp_add_now(TS_AFTER_INITRAM);
 
 	/* Perform some initialization that must run before stage2 */
@@ -364,50 +346,7 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-#if !CONFIG_HAVE_ACPI_RESUME
-#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8
-#if CONFIG_DEBUG_RAM_SETUP
-	sdram_dump_mchbar_registers();
-
-	{
-		/* This will not work if TSEG is in place! */
-		u32 tom = pci_read_config32(PCI_DEV(0, 2, 0), 0x5c);
-
-		printk(BIOS_DEBUG, "TOM: 0x%08x\n", tom);
-		ram_check(0x00000000, 0x000a0000);
-		ram_check(0x00100000, tom);
-	}
-#endif
-#endif
-#endif
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD,
-				   SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 
 	timestamp_add_now(TS_END_ROMSTAGE);
 
diff --git a/src/mainboard/getac/p470/irq_tables.c b/src/mainboard/getac/p470/irq_tables.c
deleted file mode 100644
index 5390741..0000000
--- a/src/mainboard/getac/p470/irq_tables.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,  /* u32 signature */
-	PIRQ_VERSION,    /* u16 version   */
-	32+16*CONFIG_IRQ_SLOT_COUNT,	 /* There can be total 18 devices on the bus */
-	0x00,		 /* Where the interrupt router lies (bus) */
-	(0x1f<<3)|0x0,   /* Where the interrupt router lies (dev) */
-	0,		 /* IRQs devoted exclusively to PCI usage */
-	0x8086,		 /* Vendor */
-	0x27b0,		 /* Device */
-	0,		 /* miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf,		 /* u8 checksum. */
-	{
-		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
-		{0x00,(0x01<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // PCIe?
-		{0x00,(0x02<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // VGA
-		{0x00,(0x1e<<3)|0x0, {{0x61, 0xdcf8}, {0x68, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // PCI bridge
-		{0x00,(0x1f<<3)|0x0, {{0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // LPC
-		{0x00,(0x1d<<3)|0x0, {{0x6b, 0xdcf8}, {0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x60, 0x0dcf8}}, 0x0, 0x0}, // USB#1
-		{0x00,(0x1b<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Audio device
-		{0x00,(0x1c<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x2, 0x0}, // PCIe bridge
-		{0x04,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Firewire
-		{0x04,(0x01<<3)|0x0, {{0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0x0dcf8}}, 0x1, 0x0}, // PCI Bridge
-		{0x04,(0x02<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x2, 0x0},
-		{0x04,(0x03<<3)|0x0, {{0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0x0dcf8}}, 0x3, 0x0},
-		{0x04,(0x04<<3)|0x0, {{0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0x0dcf8}}, 0x4, 0x0},
-		{0x04,(0x05<<3)|0x0, {{0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0x0dcf8}}, 0x5, 0x0},
-		{0x04,(0x06<<3)|0x0, {{0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0x0dcd8}}, 0x6, 0x0},
-		{0x04,(0x09<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x9, 0x0},
-		{0x01,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // Ethernet 8168
-		{0x02,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x9, 0x0},
-		{0x03,(0x00<<3)|0x0, {{0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x60, 0x0dcf8}}, 0xa, 0x0},
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/getac/p470/romstage.c b/src/mainboard/getac/p470/romstage.c
index 3dab527..ccfb076 100644
--- a/src/mainboard/getac/p470/romstage.c
+++ b/src/mainboard/getac/p470/romstage.c
@@ -268,9 +268,7 @@ static void early_ich7_init(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0;
 
 	if (bist == 0)
 		enable_lapic();
@@ -302,21 +300,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -325,7 +309,7 @@ void main(unsigned long bist)
 	dump_spd_registers();
 #endif
 
-	sdram_initialize(boot_mode, NULL);
+	sdram_initialize(s3resume ? 2 : 0, NULL);
 
 	/* Perform some initialization that must run before stage2 */
 	early_ich7_init();
@@ -339,29 +323,5 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD, SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 }
diff --git a/src/mainboard/ibase/mb899/irq_tables.c b/src/mainboard/ibase/mb899/irq_tables.c
deleted file mode 100644
index 9c275d5..0000000
--- a/src/mainboard/ibase/mb899/irq_tables.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,  /* u32 signature */
-	PIRQ_VERSION,    /* u16 version   */
-	32+16*CONFIG_IRQ_SLOT_COUNT,	 /* There can be total CONFIG_IRQ_SLOT_COUNT devices on the bus */
-	0x00,		 /* Where the interrupt router lies (bus) */
-	(0x1f<<3)|0x0,   /* Where the interrupt router lies (dev) */
-	0,		 /* IRQs devoted exclusively to PCI usage */
-	0x8086,		 /* Vendor */
-	0x27b9,		 /* Device */
-	0,		 /* miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf,		 /* u8 checksum. */
-	{
-		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
-		{0x00,(0x01<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // PCIe?
-		{0x00,(0x02<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // VGA
-		{0x00,(0x1e<<3)|0x0, {{0x61, 0xdcf8}, {0x68, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // PCI bridge
-		{0x00,(0x1f<<3)|0x0, {{0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // LPC
-		{0x00,(0x1d<<3)|0x0, {{0x6b, 0xdcf8}, {0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x60, 0x0dcf8}}, 0x0, 0x0}, // USB#1
-		{0x00,(0x1b<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Audio device
-		{0x00,(0x1c<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x2, 0x0}, // PCIe bridge
-		{0x04,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Firewire
-		{0x04,(0x01<<3)|0x0, {{0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0x0dcf8}}, 0x1, 0x0}, // PCI Bridge
-		{0x04,(0x02<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x2, 0x0},
-		{0x04,(0x03<<3)|0x0, {{0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0x0dcf8}}, 0x3, 0x0},
-		{0x04,(0x04<<3)|0x0, {{0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0x0dcf8}}, 0x4, 0x0},
-		{0x04,(0x05<<3)|0x0, {{0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0x0dcf8}}, 0x5, 0x0},
-		{0x04,(0x06<<3)|0x0, {{0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0x0dcd8}}, 0x6, 0x0},
-		{0x04,(0x09<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x9, 0x0},
-		{0x01,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // Ethernet Marvell 88E8053
-		{0x02,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x9, 0x0},
-		{0x03,(0x00<<3)|0x0, {{0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x60, 0x0dcf8}}, 0xa, 0x0},
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/ibase/mb899/romstage.c b/src/mainboard/ibase/mb899/romstage.c
index 322907b..2a81921 100644
--- a/src/mainboard/ibase/mb899/romstage.c
+++ b/src/mainboard/ibase/mb899/romstage.c
@@ -226,9 +226,7 @@ static void early_ich7_init(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0;
 
 	if (bist == 0)
 		enable_lapic();
@@ -253,21 +251,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -276,7 +260,7 @@ void main(unsigned long bist)
 	dump_spd_registers();
 #endif
 
-	sdram_initialize(boot_mode, NULL);
+	sdram_initialize(s3resume ? 2 : 0, NULL);
 
 	/* Perform some initialization that must run before stage2 */
 	early_ich7_init();
@@ -290,32 +274,5 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-
-	quick_ram_check();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD, SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 }
diff --git a/src/mainboard/intel/d945gclf/irq_tables.c b/src/mainboard/intel/d945gclf/irq_tables.c
deleted file mode 100644
index 08108f8..0000000
--- a/src/mainboard/intel/d945gclf/irq_tables.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,  /* u32 signature */
-	PIRQ_VERSION,    /* u16 version   */
-	32+16*18,	 /* There can be total 18 devices on the bus */
-	0x00,		 /* Where the interrupt router lies (bus) */
-	(0x1f<<3)|0x0,   /* Where the interrupt router lies (dev) */
-	0,		 /* IRQs devoted exclusively to PCI usage */
-	0x8086,		 /* Vendor */
-	0x27b0,		 /* Device */
-	0,		 /* miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf,		 /* u8 checksum. */
-	{
-		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
-		{0x00,(0x01<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // PCIe?
-		{0x00,(0x02<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // VGA
-		{0x00,(0x1e<<3)|0x0, {{0x61, 0xdcf8}, {0x68, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // PCI bridge
-		{0x00,(0x1f<<3)|0x0, {{0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // LPC
-		{0x00,(0x1d<<3)|0x0, {{0x6b, 0xdcf8}, {0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x60, 0x0dcf8}}, 0x0, 0x0}, // USB#1
-		{0x00,(0x1b<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Audio device
-		{0x00,(0x1c<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x2, 0x0}, // PCIe bridge
-		{0x04,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Firewire
-		{0x04,(0x01<<3)|0x0, {{0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0x0dcf8}}, 0x1, 0x0}, // PCI Bridge
-		{0x04,(0x02<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x2, 0x0},
-		{0x04,(0x03<<3)|0x0, {{0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0x0dcf8}}, 0x3, 0x0},
-		{0x04,(0x04<<3)|0x0, {{0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0x0dcf8}}, 0x4, 0x0},
-		{0x04,(0x05<<3)|0x0, {{0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0x0dcf8}}, 0x5, 0x0},
-		{0x04,(0x06<<3)|0x0, {{0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0x0dcd8}}, 0x6, 0x0},
-		{0x04,(0x09<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x9, 0x0},
-		{0x01,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // Ethernet 8168
-		{0x02,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x9, 0x0},
-		{0x03,(0x00<<3)|0x0, {{0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x60, 0x0dcf8}}, 0xa, 0x0},
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/intel/d945gclf/romstage.c b/src/mainboard/intel/d945gclf/romstage.c
index 0c48247..4508968 100644
--- a/src/mainboard/intel/d945gclf/romstage.c
+++ b/src/mainboard/intel/d945gclf/romstage.c
@@ -159,9 +159,7 @@ static void early_ich7_init(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0, boot_mode = 0;
 
 	if (bist == 0)
 		enable_lapic();
@@ -187,21 +185,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-        /* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -210,7 +194,7 @@ void main(unsigned long bist)
 	dump_spd_registers();
 #endif
 
-	sdram_initialize(boot_mode, NULL);
+	sdram_initialize(s3resume ? 2 : boot_mode, NULL);
 
 	/* Perform some initialization that must run before stage2 */
 	early_ich7_init();
@@ -224,29 +208,5 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD, SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 }
diff --git a/src/mainboard/kontron/986lcd-m/irq_tables.c b/src/mainboard/kontron/986lcd-m/irq_tables.c
deleted file mode 100644
index a585122..0000000
--- a/src/mainboard/kontron/986lcd-m/irq_tables.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,  /* u32 signature */
-	PIRQ_VERSION,    /* u16 version   */
-	32+16*CONFIG_IRQ_SLOT_COUNT,	 /* There can be total CONFIG_IRQ_SLOT_COUNT devices on the bus */
-	0x00,		 /* Where the interrupt router lies (bus) */
-	(0x1f<<3)|0x0,   /* Where the interrupt router lies (dev) */
-	0,		 /* IRQs devoted exclusively to PCI usage */
-	0x8086,		 /* Vendor */
-	0x27b0,		 /* Device */
-	0,		 /* miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf,		 /* u8 checksum. */
-	{
-		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
-		{0x00,(0x01<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // PCIe?
-		{0x00,(0x02<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // VGA
-		{0x00,(0x1e<<3)|0x0, {{0x61, 0xdcf8}, {0x68, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // PCI bridge
-		{0x00,(0x1f<<3)|0x0, {{0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // LPC
-		{0x00,(0x1d<<3)|0x0, {{0x6b, 0xdcf8}, {0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x60, 0x0dcf8}}, 0x0, 0x0}, // USB#1
-		{0x00,(0x1b<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Audio device
-		{0x00,(0x1c<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x2, 0x0}, // PCIe bridge
-		{0x04,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Firewire
-		{0x04,(0x01<<3)|0x0, {{0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0x0dcf8}}, 0x1, 0x0}, // PCI Bridge
-		{0x04,(0x02<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x2, 0x0},
-		{0x04,(0x03<<3)|0x0, {{0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0x0dcf8}}, 0x3, 0x0},
-		{0x04,(0x04<<3)|0x0, {{0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0x0dcf8}}, 0x4, 0x0},
-		{0x04,(0x05<<3)|0x0, {{0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0x0dcf8}}, 0x5, 0x0},
-		{0x04,(0x06<<3)|0x0, {{0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0x0dcd8}}, 0x6, 0x0},
-		{0x04,(0x09<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x9, 0x0},
-		{0x01,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // Ethernet 8168
-		{0x02,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x9, 0x0},
-		{0x03,(0x00<<3)|0x0, {{0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x60, 0x0dcf8}}, 0xa, 0x0},
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/kontron/986lcd-m/romstage.c b/src/mainboard/kontron/986lcd-m/romstage.c
index 2c12c5d..2c89e6c 100644
--- a/src/mainboard/kontron/986lcd-m/romstage.c
+++ b/src/mainboard/kontron/986lcd-m/romstage.c
@@ -332,9 +332,7 @@ static void early_ich7_init(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0;
 
 	if (bist == 0)
 		enable_lapic();
@@ -364,21 +362,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -387,7 +371,7 @@ void main(unsigned long bist)
 	dump_spd_registers();
 #endif
 
-	sdram_initialize(boot_mode, NULL);
+	sdram_initialize(s3resume ? 2 : 0, NULL);
 
 	/* Perform some initialization that must run before stage2 */
 	early_ich7_init();
@@ -401,31 +385,5 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-	quick_ram_check();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD, SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 }
diff --git a/src/mainboard/lenovo/t60/irq_tables.c b/src/mainboard/lenovo/t60/irq_tables.c
deleted file mode 100644
index 8991d7f..0000000
--- a/src/mainboard/lenovo/t60/irq_tables.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (c) 2011 Sven Schnelle <svens at 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
- */
-
-#include <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,		/* u32 signature */
-	PIRQ_VERSION,		/* u16 version */
-	32 + 16 * 15,		/* Max. number of devices on the bus */
-	0x00,			/* Interrupt router bus */
-	(0x1f << 3) | 0x0,	/* Interrupt router dev */
-	0,			/* IRQs devoted exclusively to PCI usage */
-	0x8086,			/* Vendor */
-	0x122e,			/* Device */
-	0,			/* Miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf5,			/* Checksum (has to be set to some value that
-				 * would give 0 after the sum of all bytes
-				 * for this structure (including checksum).
-                                 */
-	{
-		/* bus,        dev | fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
-		{0x00, (0x02 << 3) | 0x0, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* VGA       0:02.0 */
-		{0x00, (0x1b << 3) | 0x0, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* HD Audio  0:1b.0 */
-		{0x00, (0x1c << 3) | 0x0, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.0 */
-		{0x00, (0x1c << 3) | 0x1, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.1 */
-		{0x00, (0x1c << 3) | 0x2, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.2 */
-		{0x00, (0x1c << 3) | 0x3, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.3 */
-		{0x00, (0x1d << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.0 */
-		{0x00, (0x1d << 3) | 0x1, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.1 */
-		{0x00, (0x1d << 3) | 0x2, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.2 */
-		{0x00, (0x1d << 3) | 0x3, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.3 */
-		{0x00, (0x1e << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* PCI       0:1e.0 */
-		{0x00, (0x1f << 3) | 0x0, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* LPC       0:1f.0 */
-		{0x00, (0x1f << 3) | 0x1, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* IDE       0:1f.1 */
-		{0x00, (0x1f << 3) | 0x2, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* SATA      0:1f.2 */
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/lenovo/t60/romstage.c b/src/mainboard/lenovo/t60/romstage.c
index f11b33e..f0ebcbc 100644
--- a/src/mainboard/lenovo/t60/romstage.c
+++ b/src/mainboard/lenovo/t60/romstage.c
@@ -209,9 +209,8 @@ static void early_ich7_init(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0, dock_err;
-	int cbmem_was_initted;
+	int s3resume = 0;
+	int dock_err;
 	const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x52, 0x51, 0x53 };
 
 
@@ -262,21 +261,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -286,7 +271,7 @@ void main(unsigned long bist)
 #endif
 
 	timestamp_add_now(TS_BEFORE_INITRAM);
-	sdram_initialize(boot_mode, spd_addrmap);
+	sdram_initialize(s3resume ? 2 : 0, spd_addrmap);
 	timestamp_add_now(TS_AFTER_INITRAM);
 
 	/* Perform some initialization that must run before stage2 */
@@ -301,32 +286,7 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD, SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 
 	timestamp_add_now(TS_END_ROMSTAGE);
-
 }
diff --git a/src/mainboard/lenovo/x60/irq_tables.c b/src/mainboard/lenovo/x60/irq_tables.c
deleted file mode 100644
index 8991d7f..0000000
--- a/src/mainboard/lenovo/x60/irq_tables.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (c) 2011 Sven Schnelle <svens at 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
- */
-
-#include <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,		/* u32 signature */
-	PIRQ_VERSION,		/* u16 version */
-	32 + 16 * 15,		/* Max. number of devices on the bus */
-	0x00,			/* Interrupt router bus */
-	(0x1f << 3) | 0x0,	/* Interrupt router dev */
-	0,			/* IRQs devoted exclusively to PCI usage */
-	0x8086,			/* Vendor */
-	0x122e,			/* Device */
-	0,			/* Miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf5,			/* Checksum (has to be set to some value that
-				 * would give 0 after the sum of all bytes
-				 * for this structure (including checksum).
-                                 */
-	{
-		/* bus,        dev | fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
-		{0x00, (0x02 << 3) | 0x0, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* VGA       0:02.0 */
-		{0x00, (0x1b << 3) | 0x0, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* HD Audio  0:1b.0 */
-		{0x00, (0x1c << 3) | 0x0, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.0 */
-		{0x00, (0x1c << 3) | 0x1, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.1 */
-		{0x00, (0x1c << 3) | 0x2, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.2 */
-		{0x00, (0x1c << 3) | 0x3, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, /* PCIe      0:1c.3 */
-		{0x00, (0x1d << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.0 */
-		{0x00, (0x1d << 3) | 0x1, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.1 */
-		{0x00, (0x1d << 3) | 0x2, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.2 */
-		{0x00, (0x1d << 3) | 0x3, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* USB       0:1d.3 */
-		{0x00, (0x1e << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, /* PCI       0:1e.0 */
-		{0x00, (0x1f << 3) | 0x0, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* LPC       0:1f.0 */
-		{0x00, (0x1f << 3) | 0x1, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* IDE       0:1f.1 */
-		{0x00, (0x1f << 3) | 0x2, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, /* SATA      0:1f.2 */
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c
index 943143a..1310b33 100644
--- a/src/mainboard/lenovo/x60/romstage.c
+++ b/src/mainboard/lenovo/x60/romstage.c
@@ -216,9 +216,7 @@ static void early_ich7_init(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0;
 	const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x52, 0x51, 0x53 };
 
 
@@ -264,21 +262,7 @@ void main(unsigned long bist)
 	 */
 	i945_early_initialization();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -288,7 +272,7 @@ void main(unsigned long bist)
 #endif
 
 	timestamp_add_now(TS_BEFORE_INITRAM);
-	sdram_initialize(boot_mode, spd_addrmap);
+	sdram_initialize(s3resume ? 2 : 0, spd_addrmap);
 	timestamp_add_now(TS_AFTER_INITRAM);
 
 	/* Perform some initialization that must run before stage2 */
@@ -303,33 +287,7 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD,
-				   SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 
 	timestamp_add_now(TS_END_ROMSTAGE);
 
diff --git a/src/mainboard/roda/rk886ex/irq_tables.c b/src/mainboard/roda/rk886ex/irq_tables.c
deleted file mode 100644
index 0f838af..0000000
--- a/src/mainboard/roda/rk886ex/irq_tables.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 <arch/pirq_routing.h>
-
-static const struct irq_routing_table intel_irq_routing_table = {
-	PIRQ_SIGNATURE,  /* u32 signature */
-	PIRQ_VERSION,    /* u16 version   */
-	32+16*18,	 /* There can be total 18 devices on the bus */
-	0x00,		 /* Where the interrupt router lies (bus) */
-	(0x1f<<3)|0x0,   /* Where the interrupt router lies (dev) */
-	0,		 /* IRQs devoted exclusively to PCI usage */
-	0x8086,		 /* Vendor */
-	0x27b0,		 /* Device */
-	0,		 /* miniport */
-	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
-	0xf,		 /* u8 checksum. */
-	{
-		/* bus,     dev|fn,   {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap},  slot, rfu */
-		{0x00,(0x01<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // PCIe?
-		{0x00,(0x02<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // VGA
-		{0x00,(0x1e<<3)|0x0, {{0x61, 0xdcf8}, {0x68, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // PCI bridge
-		{0x00,(0x1f<<3)|0x0, {{0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // LPC
-		{0x00,(0x1d<<3)|0x0, {{0x6b, 0xdcf8}, {0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x60, 0x0dcf8}}, 0x0, 0x0}, // USB#1
-		{0x00,(0x1b<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Audio device
-		{0x00,(0x1c<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x2, 0x0}, // PCIe bridge
-		{0x04,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, // Firewire
-		{0x04,(0x01<<3)|0x0, {{0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0x0dcf8}}, 0x1, 0x0}, // PCI Bridge
-		{0x04,(0x02<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x2, 0x0},
-		{0x04,(0x03<<3)|0x0, {{0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0x0dcf8}}, 0x3, 0x0},
-		{0x04,(0x04<<3)|0x0, {{0x6b, 0xdcf8}, {0x68, 0xdcf8}, {0x69, 0xdcf8}, {0x6a, 0x0dcf8}}, 0x4, 0x0},
-		{0x04,(0x05<<3)|0x0, {{0x63, 0xdcd8}, {0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0x0dcf8}}, 0x5, 0x0},
-		{0x04,(0x06<<3)|0x0, {{0x62, 0xdcf8}, {0x61, 0xdcf8}, {0x60, 0xdcf8}, {0x63, 0x0dcd8}}, 0x6, 0x0},
-		{0x04,(0x09<<3)|0x0, {{0x69, 0xdcf8}, {0x6a, 0xdcf8}, {0x6b, 0xdcf8}, {0x68, 0x0dcf8}}, 0x9, 0x0},
-		{0x01,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x0, 0x0}, // Ethernet 8168
-		{0x02,(0x00<<3)|0x0, {{0x60, 0xdcf8}, {0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0x0dcd8}}, 0x9, 0x0},
-		{0x03,(0x00<<3)|0x0, {{0x61, 0xdcf8}, {0x62, 0xdcf8}, {0x63, 0xdcd8}, {0x60, 0x0dcf8}}, 0xa, 0x0},
-	}
-};
-
-unsigned long write_pirq_routing_table(unsigned long addr)
-{
-	return copy_pirq_routing_table(addr, &intel_irq_routing_table);
-}
diff --git a/src/mainboard/roda/rk886ex/romstage.c b/src/mainboard/roda/rk886ex/romstage.c
index 7cc1a1d..071fa2a 100644
--- a/src/mainboard/roda/rk886ex/romstage.c
+++ b/src/mainboard/roda/rk886ex/romstage.c
@@ -254,9 +254,7 @@ static void init_artec_dongle(void)
 #include <cpu/intel/romstage.h>
 void main(unsigned long bist)
 {
-	u32 reg32;
-	int boot_mode = 0;
-	int cbmem_was_initted;
+	int s3resume = 0;
 
 	if (bist == 0)
 		enable_lapic();
@@ -289,21 +287,7 @@ void main(unsigned long bist)
 	/* This has to happen after i945_early_initialization() */
 	init_artec_dongle();
 
-	/* Read PM1_CNT */
-	reg32 = inl(DEFAULT_PMBASE + 0x04);
-	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
-	if (((reg32 >> 10) & 7) == 5) {
-		if (acpi_s3_resume_allowed()) {
-			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
-			boot_mode = 2;
-			/* Clear SLP_TYPE. This will break stage2 but
-			 * we care for that when we get there.
-			 */
-			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
-		} else {
-			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
-		}
-	}
+	s3resume = southbridge_detect_s3_resume();
 
 	/* Enable SPD ROMs and DDR-II DRAM */
 	enable_smbus();
@@ -312,7 +296,7 @@ void main(unsigned long bist)
 	dump_spd_registers();
 #endif
 
-	sdram_initialize(boot_mode, NULL);
+	sdram_initialize(s3resume ? 2 : 0, NULL);
 
 	/* Perform some initialization that must run before stage2 */
 	early_ich7_init();
@@ -326,29 +310,5 @@ void main(unsigned long bist)
 	fixup_i945_errata();
 
 	/* Initialize the internal PCIe links before we go into stage2 */
-	i945_late_initialization();
-
-	MCHBAR16(SSKPD) = 0xCAFE;
-
-	cbmem_was_initted = !cbmem_recovery(boot_mode==2);
-
-#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 ((boot_mode == 2) && cbmem_was_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, 0x00, 0), SKPAD, SKPAD_ACPI_S3_MAGIC);
-	}
-#endif
+	i945_late_initialization(s3resume);
 }
diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c
index 24054bd..1715c47 100644
--- a/src/northbridge/intel/i945/early_init.c
+++ b/src/northbridge/intel/i945/early_init.c
@@ -22,6 +22,8 @@
 #include <console/console.h>
 #include <arch/io.h>
 #include <device/pci_def.h>
+#include <cbmem.h>
+#include <string.h>
 #include "i945.h"
 
 int i945_silicon_revision(void)
@@ -887,7 +889,34 @@ void i945_early_initialization(void)
 	RCBA32(0x2010) |= (1 << 10);
 }
 
-void i945_late_initialization(void)
+static void i945_prepare_resume(int s3resume)
+{
+	int cbmem_was_initted;
+
+	cbmem_was_initted = !cbmem_recovery(s3resume);
+
+	/* 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_was_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, 0x00, 0), SKPAD,
+				   SKPAD_ACPI_S3_MAGIC);
+	}
+}
+
+void i945_late_initialization(int s3resume)
 {
 	i945_setup_egress_port();
 
@@ -902,4 +931,25 @@ void i945_late_initialization(void)
 	i945_setup_pci_express_x16();
 
 	i945_setup_root_complex_topology();
+
+#if !CONFIG_HAVE_ACPI_RESUME
+#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8
+#if CONFIG_DEBUG_RAM_SETUP
+	sdram_dump_mchbar_registers();
+
+	{
+		/* This will not work if TSEG is in place! */
+		u32 tom = pci_read_config32(PCI_DEV(0, 2, 0), 0x5c);
+
+		printk(BIOS_DEBUG, "TOM: 0x%08x\n", tom);
+		ram_check(0x00000000, 0x000a0000);
+		ram_check(0x00100000, tom);
+	}
+#endif
+#endif
+#endif
+
+	MCHBAR16(SSKPD) = 0xCAFE;
+
+	i945_prepare_resume(s3resume);
 }
diff --git a/src/northbridge/intel/i945/i945.h b/src/northbridge/intel/i945/i945.h
index 9be9379..8573b0c 100644
--- a/src/northbridge/intel/i945/i945.h
+++ b/src/northbridge/intel/i945/i945.h
@@ -350,7 +350,7 @@ static inline void barrier(void) { asm("" ::: "memory"); }
 
 int i945_silicon_revision(void);
 void i945_early_initialization(void);
-void i945_late_initialization(void);
+void i945_late_initialization(int s3resume);
 
 /* provided by mainboard code */
 void setup_ich7_gpios(void);
diff --git a/src/southbridge/intel/i82801gx/early_lpc.c b/src/southbridge/intel/i82801gx/early_lpc.c
index 9f80d41..69bbfb2 100644
--- a/src/southbridge/intel/i82801gx/early_lpc.c
+++ b/src/southbridge/intel/i82801gx/early_lpc.c
@@ -20,6 +20,9 @@
 
 #include <arch/io.h>
 #include <timestamp.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+#include "i82801gx.h"
 
 #if CONFIG_COLLECT_TIMESTAMPS
 tsc_t get_initial_timestamp(void)
@@ -31,3 +34,26 @@ tsc_t get_initial_timestamp(void)
 	return base_time;
 }
 #endif
+
+int southbridge_detect_s3_resume(void)
+{
+	u32 reg32;
+
+	/* Read PM1_CNT */
+	reg32 = inl(DEFAULT_PMBASE + 0x04);
+	printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32);
+	if (((reg32 >> 10) & 7) == 5) {
+		if (acpi_s3_resume_allowed()) {
+			printk(BIOS_DEBUG, "Resume from S3 detected.\n");
+			/* Clear SLP_TYPE. This will break stage2 but
+			 * we care for that when we get there.
+			 */
+			outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
+			return 1;
+		} else {
+			printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
+		}
+	}
+
+	return 0;
+}
diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h
index 1064dde..ee13b7d 100644
--- a/src/southbridge/intel/i82801gx/i82801gx.h
+++ b/src/southbridge/intel/i82801gx/i82801gx.h
@@ -44,6 +44,7 @@ extern void i82801gx_enable(device_t dev);
 #else
 void enable_smbus(void);
 int smbus_read_byte(unsigned device, unsigned address);
+int southbridge_detect_s3_resume(void);
 #endif
 #endif
 



More information about the coreboot-gerrit mailing list