Patchwork fix S3 support on AMD K8 famF

login
register
about
Submitter Rudolf Marek
Date 2010-11-21 23:39:29
Message ID <4CE9ADB1.9050200@assembler.cz>
Download mbox | patch
Permalink /patch/2343/
State Accepted
Headers show

Comments

Rudolf Marek - 2010-11-21 23:39:29
Hi all,

I think I fixed the S3 suspend/resume on AMD which was broken since Stephan did 
the change with cbmem :)

The patch does following:

1) wraps the s3 parts of chipset code/memory init code with if 
CONFIG_HAVE_ACPI_RESUME == 1 getting rid of ugly define in romstage.c

2) the patch implements get_cbmem_toc in chipset specific way if defined.
On Intel targets it should be unchanged. On K8T890 the the cbmem_toc is read 
from NVRAM. Why you ask? Because we cannot do it as on intel, because the 
framebuffer might be there making it hard to look for it in memory (and remember 
we need it so early that everying is uncached)

3) The patch removes hardcoded limits for suspend/resume save area (it was 1MB) 
on intel. Now it computes right numbers itself.

4) it impelements saving the memory during CAR to reserved range in sane way. 
First the sysinfo area (CAR data) is copied, then the rest after car is disabled 
(cached copy is used). I changed bit also the the copy of CAR area is now done 
uncached for target which I feel is more right.

I think I did not change the Intel suspend/resume behaviour but best would be if 
someone can test it. Please note this patch was unfinished on my drive since 
ages and it would be very nice to get it in to prevent bit rotten it again.
Now I feel it is done good way and should not break anything. I did a test with 
abuild and it seems fine.

The Rachmann did suspend/resume support for Asus M2V he will post the patch soon.

Signed-off-by: Rudolf Marek <r.marek@assembler.cz>

Thanks,
Rudolf
Tobias Diedrich - 2010-11-22 00:31:19
Rudolf Marek wrote:
> Hi all,
>
> I think I fixed the S3 suspend/resume on AMD which was broken since 
> Stephan did the change with cbmem :)
>
> The patch does following:
>
> 1) wraps the s3 parts of chipset code/memory init code with if  
> CONFIG_HAVE_ACPI_RESUME == 1 getting rid of ugly define in romstage.c
>
> 2) the patch implements get_cbmem_toc in chipset specific way if defined.
> On Intel targets it should be unchanged. On K8T890 the the cbmem_toc is 
> read from NVRAM. Why you ask? Because we cannot do it as on intel, 
> because the framebuffer might be there making it hard to look for it in 
> memory (and remember we need it so early that everying is uncached)
>
> 3) The patch removes hardcoded limits for suspend/resume save area (it 
> was 1MB) on intel. Now it computes right numbers itself.
>
> 4) it impelements saving the memory during CAR to reserved range in sane 
> way. First the sysinfo area (CAR data) is copied, then the rest after car 
> is disabled (cached copy is used). I changed bit also the the copy of CAR 
> area is now done uncached for target which I feel is more right.
>
> I think I did not change the Intel suspend/resume behaviour but best 
> would be if someone can test it. Please note this patch was unfinished on 
> my drive since ages and it would be very nice to get it in to prevent bit 
> rotten it again.
> Now I feel it is done good way and should not break anything. I did a 
> test with abuild and it seems fine.
>
> The Rachmann did suspend/resume support for Asus M2V he will post the patch soon.
>
> Signed-off-by: Rudolf Marek <r.marek@assembler.cz>

Tested and works fine for me on my M2V with patch to add
board-specific init and dsdt parts.

Acked-by: Tobias Diedrich <ranma+coreboot@tdiedrich.de>
Stefan Reinauer - 2010-11-22 08:05:21
On 11/21/10 3:39 PM, Rudolf Marek wrote:
> 2) the patch implements get_cbmem_toc in chipset specific way if defined.
> On Intel targets it should be unchanged. On K8T890 the the cbmem_toc
> is read from NVRAM. Why you ask? Because we cannot do it as on intel,
> because the framebuffer might be there making it hard to look for it
> in memory (and remember we need it so early that everying is uncached)
Can't we read the size of the framebuffer on resume? Maybe the register
is  connected to the resume power well?

> 3) The patch removes hardcoded limits for suspend/resume save area (it
> was 1MB) on intel. Now it computes right numbers itself.
This is good. We should look into reducing this size on most platforms
though. I think some AMD boards use incredibly high numbers for RAM_TOP
> I think I did not change the Intel suspend/resume behaviour but best
> would be if someone can test it. 
Unfortunately I can not, at the moment. Hopefully someone can step in?

> Please note this patch was unfinished on my drive since ages and it
> would be very nice to get it in to prevent bit rotten it again.
> Now I feel it is done good way and should not break anything. I did a
> test with abuild and it seems fine.
>
> The Rachmann did suspend/resume support for Asus M2V he will post the
> patch soon.
>
> Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
Awesome! Thanks a lot for cleaning up behind me ;)

Acked-by: Stefan Reinauer <stepan@coreboot.org>

Stefan
Rudolf Marek - 2010-11-22 22:08:17
> Can't we read the size of the framebuffer on resume? Maybe the register
> is  connected to the resume power well?

Nope it is not, and if we have a CMOS option for FB size we don't know how big 
it is. This solution is therefore most easy and straightforward.

Committed revision 6117.

Thanks,
Rudolf

Patch

Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c
===================================================================
--- src/southbridge/via/vt8237r/vt8237r_early_smbus.c.orig	2010-11-14 14:45:01.000000000 +0100
+++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c	2010-11-21 17:59:01.000000000 +0100
@@ -316,9 +316,7 @@ 
 	pci_write_config8(dev, 0x41, 0x7f);
 }
 
-#ifdef CONFIG_NORTHBRIDGE_AMD_K8 /* CN700 doesn't have the support yet */
-#define ACPI_IS_WAKEUP_EARLY 1
-
+#if CONFIG_HAVE_ACPI_RESUME == 1
 static int acpi_is_wakeup_early(void) {
 	device_t dev;
 	u16 tmp;
Index: src/southbridge/via/k8t890/k8t890.h
===================================================================
--- src/southbridge/via/k8t890/k8t890.h.orig	2010-11-14 14:45:01.000000000 +0100
+++ src/southbridge/via/k8t890/k8t890.h	2010-11-22 00:32:18.000000000 +0100
@@ -31,6 +31,7 @@ 
 
 /* The 256 bytes of NVRAM for S3 storage, 256B aligned */
 #define K8T890_NVRAM_IO_BASE	0xf00
+#define K8T890_NVRAM_CBMEM_TOC	0xfc
 
 #define K8T890_MMCONFIG_MBAR	0x61
 #define K8T890_MULTIPLE_FN_EN	0x4f
Index: src/southbridge/via/k8t890/k8t890_early_car.c
===================================================================
--- src/southbridge/via/k8t890/k8t890_early_car.c.orig	2010-11-14 14:45:01.000000000 +0100
+++ src/southbridge/via/k8t890/k8t890_early_car.c	2010-11-22 00:05:59.000000000 +0100
@@ -23,16 +23,14 @@ 
  */
 
 #include <stdlib.h>
+#include <cbmem.h>
+#include <arch/io.h>
 #include "k8t890.h"
 
 /* The 256 bytes of NVRAM for S3 storage, 256B aligned */
 #define K8T890_NVRAM_IO_BASE	0xf00
 #define K8T890_MULTIPLE_FN_EN	0x4f
 
-/* we provide S3 NVRAM to system */
-#define S3_NVRAM_EARLY	1
-
-
 /* AMD K8 LDT0, LDT1, LDT2 Link Control Registers */
 static u8 ldtreg[3] = {0x86, 0xa6, 0xc6};
 
@@ -155,3 +153,9 @@ 
 	printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", * old_dword, size, nvram_pos-size);
 	return nvram_pos;
 }
+
+/* this should be a function
+struct cbmem_entry *get_cbmem_toc(void) {
+*/
+
+#define get_cbmem_toc() ((struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC))
Index: src/southbridge/via/k8t890/k8t890_host_ctrl.c
===================================================================
--- src/southbridge/via/k8t890/k8t890_host_ctrl.c.orig	2010-11-14 14:45:01.000000000 +0100
+++ src/southbridge/via/k8t890/k8t890_host_ctrl.c	2010-11-21 17:19:11.000000000 +0100
@@ -22,6 +22,8 @@ 
 #include <device/pci_ops.h>
 #include <device/pci_ids.h>
 #include <console/console.h>
+#include <cbmem.h>
+#include <arch/io.h>
 #include "k8t890.h"
 
 /* this may be later merged */
@@ -111,6 +113,14 @@ 
 	pci_write_config8(dev, 0xa6, 0x83);
 
 }
+#if 0
+struct cbmem_entry *get_cbmem_toc(void) {
+		return (struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
+}
+#endif
+void set_cbmem_toc(struct cbmem_entry *toc) {
+		outl((u32) toc, K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
+}
 
 static const struct device_operations host_ctrl_ops_t = {
 	.read_resources		= pci_dev_read_resources,
Index: src/include/cbmem.h
===================================================================
--- src/include/cbmem.h.orig	2010-11-14 14:45:09.000000000 +0100
+++ src/include/cbmem.h	2010-11-21 17:39:22.000000000 +0100
@@ -24,7 +24,7 @@ 
 #define HIGH_MEMORY_TABLES	( 64 * 1024 )
 
 #if CONFIG_HAVE_ACPI_RESUME
-#define HIGH_MEMORY_SIZE	( 1024 * 1024 )
+#define HIGH_MEMORY_SIZE	((CONFIG_RAMTOP - CONFIG_RAMBASE) + HIGH_MEMORY_TABLES)
 #define HIGH_MEMORY_SAVE	( HIGH_MEMORY_SIZE - HIGH_MEMORY_TABLES )
 #else
 #define HIGH_MEMORY_SIZE	HIGH_MEMORY_TABLES
@@ -48,4 +48,6 @@ 
 void cbmem_list(void);
 void cbmem_arch_init(void);
 
+struct cbmem_entry *get_cbmem_toc(void);
+void set_cbmem_toc(struct cbmem_entry *);
 #endif
Index: src/cpu/amd/car/post_cache_as_ram.c
===================================================================
--- src/cpu/amd/car/post_cache_as_ram.c.orig	2010-11-14 14:45:10.000000000 +0100
+++ src/cpu/amd/car/post_cache_as_ram.c	2010-11-21 18:00:31.000000000 +0100
@@ -27,6 +27,45 @@ 
 			: "0" (bytes / 4), "g" (bytes), "1" ((long)dest), "2" ((long)src)
 			: "memory", "cc");
 }
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+
+static inline void *backup_resume(void) {
+	unsigned long high_ram_base;
+	void *resume_backup_memory;
+	int suspend = acpi_is_wakeup_early();
+
+	if (!suspend)
+		return NULL;
+
+	/* Start address of high memory tables */
+	high_ram_base = (u32) get_cbmem_toc();
+
+	print_debug_pcar("CBMEM TOC is at: ", (uint32_t)high_ram_base);
+	print_debug_pcar("CBMEM TOC 0-size: ",(uint32_t)(high_ram_base + HIGH_MEMORY_SIZE + 4096));
+
+	cbmem_reinit((u64)high_ram_base);
+
+	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) {
+		print_debug_pcar("Will copy coreboot region to: ", (uint32_t) resume_backup_memory);
+		/* copy only backup only memory used for CAR */
+		memcopy(resume_backup_memory+HIGH_MEMORY_SAVE-CONFIG_DCACHE_RAM_SIZE,
+			(void *)((CONFIG_RAMTOP)-CONFIG_DCACHE_RAM_SIZE),
+			 CONFIG_DCACHE_RAM_SIZE); //inline
+	}
+
+	return resume_backup_memory;
+}
+#endif
+
 /* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33 */
 
 static void vErrata343(void)
@@ -43,7 +82,9 @@ 
 
 static void post_cache_as_ram(void)
 {
-
+#if CONFIG_HAVE_ACPI_RESUME == 1
+	void *resume_backup_memory;
+#endif
 #if 1
 	{
 	/* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
@@ -66,17 +107,16 @@ 
 	#error "You need to set CONFIG_RAMTOP greater than 1M"
 #endif
 
-	/* So we can access RAM from [1M, CONFIG_RAMTOP) */
-	set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK);
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ 	resume_backup_memory = backup_resume();
+#endif
 
-//	dump_mem(CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x8000, CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x7c00);
 	print_debug("Copying data from cache to RAM -- switching to use RAM as stack... ");
 
 	/* from here don't store more data in CAR */
 	vErrata343();
 
 	memcopy((void *)((CONFIG_RAMTOP)-CONFIG_DCACHE_RAM_SIZE), (void *)CONFIG_DCACHE_RAM_BASE, CONFIG_DCACHE_RAM_SIZE); //inline
-//	dump_mem((CONFIG_RAMTOP) - 0x8000, (CONFIG_RAMTOP) - 0x7c00);
 
 	__asm__ volatile (
 		/* set new esp */ /* before CONFIG_RAMBASE */
@@ -94,9 +134,25 @@ 
 	print_debug_pcar("testx = ", testx);
 
 	print_debug("Disabling cache as ram now \n");
+
 	disable_cache_as_ram_bsp();
 
+	disable_cache();
+	set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK);
+	enable_cache();
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+	/* now copy the rest of the area, using the WB method because we already
+	   run normal RAM */
+	if (resume_backup_memory) {
+		memcopy(resume_backup_memory,
+				(void *)(CONFIG_RAMBASE),
+				(CONFIG_RAMTOP) - CONFIG_RAMBASE - CONFIG_DCACHE_RAM_SIZE);
+	}
+#endif
+
 	print_debug("Clearing initial memory region: ");
+
 #if CONFIG_HAVE_ACPI_RESUME == 1
 	/* clear only coreboot used region of memory. Note: this may break ECC enabled boards */
 	memset((void*) CONFIG_RAMBASE, 0, (CONFIG_RAMTOP) - CONFIG_RAMBASE - CONFIG_DCACHE_RAM_SIZE);
@@ -105,8 +161,6 @@ 
 #endif
 	print_debug("Done\n");
 
-//	dump_mem((CONFIG_RAMTOP) - 0x8000, (CONFIG_RAMTOP) - 0x7c00);
-
 	set_sysinfo_in_ram(1); // So other core0 could start to train mem
 
 #if CONFIG_MEM_TRAIN_SEQ == 1
Index: src/mainboard/asus/m2v-mx_se/Kconfig
===================================================================
--- src/mainboard/asus/m2v-mx_se/Kconfig.orig	2010-11-21 13:04:07.000000000 +0100
+++ src/mainboard/asus/m2v-mx_se/Kconfig	2010-11-21 13:18:25.000000000 +0100
@@ -35,6 +35,7 @@ 
 	select RAMINIT_SYSINFO
 	select VGA
 	select TINY_BOOTBLOCK
+	select HAVE_ACPI_RESUME
 	select HAVE_MAINBOARD_RESOURCES
 	select QRANK_DIMM_SUPPORT
 	select SET_FIDVID
Index: src/mainboard/asus/m2v-mx_se/romstage.c
===================================================================
--- src/mainboard/asus/m2v-mx_se/romstage.c.orig	2010-11-21 13:02:32.000000000 +0100
+++ src/mainboard/asus/m2v-mx_se/romstage.c	2010-11-21 17:57:04.000000000 +0100
@@ -67,7 +67,6 @@ 
 {
 }
 
-// defines S3_NVRAM_EARLY:
 #include "southbridge/via/k8t890/k8t890_early_car.c"
 
 #include "northbridge/amd/amdk8/amdk8.h"
@@ -83,6 +82,15 @@ 
 
 #define SB_VFSMAF 0
 
+
+// Now, this needs to be included because it relies on the symbol
+// __PRE_RAM__ being set during CAR stage (in order to compile the
+// BSS free versions of the functions). Either rewrite the code
+// to be always BSS free, or invent a flag that's better suited than
+// __PRE_RAM__ to determine whether we're in ram init stage (stage 1)
+//
+#include "lib/cbmem.c"
+
 /* this function might fail on some K8 CPUs with errata #181 */
 static void ldtstop_sb(void)
 {
Index: src/mainboard/asus/m2v-mx_se/mainboard.c
===================================================================
--- src/mainboard/asus/m2v-mx_se/mainboard.c.orig	2010-11-17 12:15:57.000000000 +0100
+++ src/mainboard/asus/m2v-mx_se/mainboard.c	2010-11-22 00:21:01.000000000 +0100
@@ -34,13 +34,6 @@ 
 	lb_add_memory_range(mem, LB_MEM_RESERVED,
 		uma_memory_base, uma_memory_size);
 #endif
-
-#if CONFIG_HAVE_ACPI_RESUME == 1
-	lb_add_memory_range(mem, LB_MEM_RESERVED,
-		CONFIG_RAMBASE, ((CONFIG_RAMTOP) - CONFIG_RAMBASE));
-	lb_add_memory_range(mem, LB_MEM_RESERVED,
-		CONFIG_DCACHE_RAM_BASE, CONFIG_DCACHE_RAM_SIZE);
-#endif
 	return 0;
 }
 
Index: src/lib/cbmem.c
===================================================================
--- src/lib/cbmem.c.orig	2010-11-14 14:45:09.000000000 +0100
+++ src/lib/cbmem.c	2010-11-22 00:04:06.000000000 +0100
@@ -36,11 +36,32 @@ 
 	u64 size;
 } __attribute__((packed));
 
-#ifndef __PRE_RAM__
-struct cbmem_entry *bss_cbmem_toc;
-#define get_cbmem_toc()	bss_cbmem_toc
+
+#ifdef __PRE_RAM__
+
+/* note this should be done as weak function but we do #include
+   of C files in the romstage breaking this (in same compile
+   unit is weak and non weak function
+struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void)
+*/
+#ifndef get_cbmem_toc
+	#define get_cbmem_toc()	(struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE)
+#endif
+
 #else
-#define get_cbmem_toc()	(struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE)
+
+static struct cbmem_entry *bss_cbmem_toc;
+
+struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void)
+{
+	return bss_cbmem_toc;
+}
+
+void __attribute__((weak)) set_cbmem_toc(struct cbmem_entry * x)
+{
+	/* do nothing, this should be called by chipset to save TOC in NVRAM */
+}
+
 #endif
 
 /**
@@ -70,6 +91,10 @@ 
 		for (;;) ;
 	}
 
+	/* we don't need to call this in romstage, usefull only from ramstage */
+#ifndef __PRE_RAM__
+	set_cbmem_toc((struct cbmem_entry *)(unsigned long)baseaddr);
+#endif
 	memset(cbmem_toc, 0, CBMEM_TOC_RESERVED);
 
 	cbmem_toc[0] = (struct cbmem_entry) {
Index: src/northbridge/amd/amdk8/northbridge.c
===================================================================
--- src/northbridge/amd/amdk8/northbridge.c.orig	2010-11-21 13:02:36.000000000 +0100
+++ src/northbridge/amd/amdk8/northbridge.c	2010-11-22 00:07:32.000000000 +0100
@@ -822,7 +822,8 @@ 
 #endif
 
 #if CONFIG_WRITE_HIGH_TABLES==1
-#define HIGH_TABLES_SIZE 64	/* maximum size of high tables in KB */
+#include <cbmem.h>
+#define HIGH_TABLES_SIZE ((HIGH_MEMORY_SIZE + 1024) / 1024)
 extern uint64_t high_tables_base, high_tables_size;
 #endif
 
Index: src/arch/i386/boot/tables.c
===================================================================
--- src/arch/i386/boot/tables.c.orig	2010-11-14 14:45:36.000000000 +0100
+++ src/arch/i386/boot/tables.c	2010-11-21 13:18:25.000000000 +0100
@@ -214,7 +214,7 @@ 
 	 * it begin there during reboot time. We don't need the pointer, nor
 	 * the result right now. If it fails, ACPI resume will be disabled.
 	 */
-	cbmem_add(CBMEM_ID_RESUME, 1024 * (1024-64));
+	cbmem_add(CBMEM_ID_RESUME, HIGH_MEMORY_SAVE);
 #endif
 
 #if CONFIG_MULTIBOOT
Index: src/arch/i386/boot/acpi.c
===================================================================
--- src/arch/i386/boot/acpi.c.orig	2010-11-21 17:52:50.000000000 +0100
+++ src/arch/i386/boot/acpi.c	2010-11-21 17:52:59.000000000 +0100
@@ -470,17 +470,6 @@ 
 {
 	void *wake_vec;
 
-#if 0
-#if CONFIG_MEM_TRAIN_SEQ != 0
-	#error "So far it works on AMD and CONFIG_MEM_TRAIN_SEQ == 0"
-#endif
-
-#if CONFIG_RAMBASE < 0x1F00000
-	#error "For ACPI RESUME you need to have CONFIG_RAMBASE at least 31MB"
-	#error "Chipset support (S3_NVRAM_EARLY and ACPI_IS_WAKEUP_EARLY functions and memory ctrl)"
-	#error "And coreboot memory reserved in mainboard.c"
-#endif
-#endif
 	/* If we happen to be resuming find wakeup vector and jump to OS. */
 	wake_vec = acpi_find_wakeup_vector();
 	if (wake_vec)
Index: src/mainboard/asus/a8v-e_deluxe/romstage.c
===================================================================
--- src/mainboard/asus/a8v-e_deluxe/romstage.c.orig	2010-11-21 17:55:02.000000000 +0100
+++ src/mainboard/asus/a8v-e_deluxe/romstage.c	2010-11-21 17:55:04.000000000 +0100
@@ -84,7 +84,6 @@ 
 	}
 }
 
-// defines S3_NVRAM_EARLY:
 #include "southbridge/via/k8t890/k8t890_early_car.c"
 
 #include "northbridge/amd/amdk8/amdk8.h"
Index: src/mainboard/asus/a8v-e_se/romstage.c
===================================================================
--- src/mainboard/asus/a8v-e_se/romstage.c.orig	2010-11-21 17:55:14.000000000 +0100
+++ src/mainboard/asus/a8v-e_se/romstage.c	2010-11-21 17:55:17.000000000 +0100
@@ -84,7 +84,6 @@ 
 	}
 }
 
-// defines S3_NVRAM_EARLY:
 #include "southbridge/via/k8t890/k8t890_early_car.c"
 
 #include "northbridge/amd/amdk8/amdk8.h"
Index: src/mainboard/asus/m2v/romstage.c
===================================================================
--- src/mainboard/asus/m2v/romstage.c.orig	2010-11-21 17:54:36.000000000 +0100
+++ src/mainboard/asus/m2v/romstage.c	2010-11-21 17:54:38.000000000 +0100
@@ -69,7 +69,6 @@ 
 {
 }
 
-// defines S3_NVRAM_EARLY:
 #include "southbridge/via/k8t890/k8t890_early_car.c"
 
 #include "northbridge/amd/amdk8/amdk8.h"
Index: src/northbridge/amd/amdk8/raminit_f_dqs.c
===================================================================
--- src/northbridge/amd/amdk8/raminit_f_dqs.c.orig	2010-11-21 17:52:19.000000000 +0100
+++ src/northbridge/amd/amdk8/raminit_f_dqs.c	2010-11-22 00:00:32.000000000 +0100
@@ -1826,25 +1826,7 @@ 
 	set_htic_bit(0, val, 9);
 }
 
-#ifdef S3_NVRAM_EARLY
-// Don't define these prototypes as the real functions are already included
-// at this point.
-//
-//int s3_save_nvram_early(u32 dword, int size, int  nvram_pos);
-//int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos);
-#else
-static inline int s3_save_nvram_early(u32 dword, int size, int  nvram_pos)
-{
-	return nvram_pos;
-}
-
-static inline int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
-{
-	die("No memory NVRAM loader for DQS data! Unable to restore memory state\n");
-
-	return nvram_pos; /* Make GCC happy */
-}
-#endif
+#if CONFIG_HAVE_ACPI_RESUME == 1
 
 #if CONFIG_MEM_TRAIN_SEQ == 0
 static int save_index_to_pos(unsigned int dev, int size, int index, int nvram_pos)
@@ -1930,6 +1912,7 @@ 
 	reg |= pci_read_config32(dev, DRAM_CONFIG_HIGH);
 	pci_write_config32(dev, DRAM_CONFIG_HIGH, reg);
 }
+#endif
 
 #if CONFIG_MEM_TRAIN_SEQ == 0
 #if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
@@ -1998,7 +1981,9 @@ 
 		if(train_DqsRcvrEn(ctrl+i, 2, sysinfo)) goto out;
 		printk(BIOS_DEBUG, " done\n");
 		sysinfo->mem_trained[i]=1;
+#if CONFIG_HAVE_ACPI_RESUME == 1
 		dqs_save_MC_NVRAM((ctrl+i)->f2);
+#endif
 	}
 
 out:
Index: src/northbridge/amd/amdk8/raminit_f.c
===================================================================
--- src/northbridge/amd/amdk8/raminit_f.c.orig	2010-11-21 23:58:57.000000000 +0100
+++ src/northbridge/amd/amdk8/raminit_f.c	2010-11-21 23:59:44.000000000 +0100
@@ -2988,14 +2988,15 @@ 
 
 }
 #endif
-
+#if CONFIG_HAVE_ACPI_RESUME == 1
 #include "exit_from_self.c"
+#endif
 
 static void sdram_enable(int controllers, const struct mem_controller *ctrl,
 			  struct sys_info *sysinfo)
 {
 	int i;
-#ifdef ACPI_IS_WAKEUP_EARLY
+#if CONFIG_HAVE_ACPI_RESUME == 1
 	int suspend = acpi_is_wakeup_early();
 #else
 	int suspend = 0;