[coreboot] [PATCH] v3: Add writeback_range() to K8 code

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Thu Nov 20 03:54:49 CET 2008


We will need writeback_range() to implement S3 suspend properly on K8,
GeodeLX and Qemu. C7 and Core2 are not affected.
Either way, writeback_range() is a good thing to have, so start
implementing it on K8.
I uncovered a bug in the AMD manuals. That bug is annotated in the code
as well to make sure nobody wants to "fix" this code.

Compile tested on DBM690T and Qemu.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

Index: corebootv3-writeback_range/include/arch/x86/cpu.h
===================================================================
--- corebootv3-writeback_range/include/arch/x86/cpu.h	(Revision 1046)
+++ corebootv3-writeback_range/include/arch/x86/cpu.h	(Arbeitskopie)
@@ -329,5 +329,6 @@
 void setup_resource_map(const struct rmap *rm, u32 max);
 EXPORT_SYMBOL(setup_resource_map);
 
+void writeback_range(unsigned long start, unsigned long len);
 
 #endif /* ARCH_X86_CPU_H */
Index: corebootv3-writeback_range/arch/x86/amd/k8/stage1.c
===================================================================
--- corebootv3-writeback_range/arch/x86/amd/k8/stage1.c	(Revision 1046)
+++ corebootv3-writeback_range/arch/x86/amd/k8/stage1.c	(Arbeitskopie)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the coreboot project.
  *
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008 Carl-Daniel Hailfinger
  *
  * 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
@@ -39,6 +39,33 @@
 }
 
 /**
+ * This function is processor specific.
+ */
+void writeback_range(unsigned long start, unsigned long len)
+{
+	unsigned long cachelinesize, i;
+	/* Number of quadwords flushed by CLFLUSH in bit 8..15
+	 * NOTE: The AMD64 Architecture Programmer's Manual Volume 3 rev 3.14
+	 * CLFLUSH section contradicts the AMD CPUID Specification rev 2.28
+	 * about where to find CLFLUSH size.
+	 * I'm using the CPUID spec definition.
+	 */
+	cachelinesize = (cpuid_ebx(0x00000001) & 0xff00) >> 8;
+	/* Convert quadwords to bytes */
+	cachelinesize <<= 3;
+	/* MFENCE before and after CLFLUSH is needed according to
+	 * AMD64 Architecture Programmer's Manual Volume 3: CLFLUSH
+	 */
+	__asm__ volatile ("mfence");
+	for (i = start; i < start + len; i += cachelinesize) {
+		__asm__ volatile (
+			"clflush (%0)	\n"
+			::"a" (i));
+	}
+	__asm__ volatile ("mfence");
+}
+
+/**
  * Disable Cache As RAM (CAR) after memory is setup.
  *
  * Unknown how to do this just yet. 


-- 
http://www.hailfinger.org/





More information about the coreboot mailing list