summaryrefslogtreecommitdiff
path: root/arch/x86
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2011-11-03 10:55:28 -0700
committerStefan Reinauer <reinauer@chromium.org>2011-11-03 14:52:31 -0700
commitf749f16593e24eaddb3c11017429b2c0751ddf18 (patch)
tree0acfe817dede8de23fd289c016cdac9bb46dace4 /arch/x86
parentff7f9647c491066feedd8dcee9c7c3b0fd466394 (diff)
Clean up MTRR 7 right before jumping to the kernel
This cleans up the rom caching optimization implemented in coreboot (and needed throughout u-boot runtime. Signed-off-by: Stefan Reinauer <reinauer@google.com> BUG=chrome-os-partner:6585 TEST=boot coreboot on stumpy Change-Id: I7242c9c2b0546c633be8fb8ebc815ed6e6fda4d1 Reviewed-on: https://gerrit.chromium.org/gerrit/11138 Tested-by: Stefan Reinauer <reinauer@chromium.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/cache.h67
-rw-r--r--arch/x86/include/asm/msr.h24
-rw-r--r--arch/x86/lib/zimage.c15
3 files changed, 106 insertions, 0 deletions
diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h
new file mode 100644
index 0000000000..21e17f97df
--- /dev/null
+++ b/arch/x86/include/asm/cache.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Eric W. 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
+ */
+
+#ifndef CPU_X86_ASM_CACHE
+#define CPU_X86_ASM_CACHE
+
+/* The memory clobber prevents the GCC from reordering the read/write order
+ * of CR0
+ */
+static inline unsigned long read_cr0(void)
+{
+ unsigned long cr0;
+ asm volatile ("movl %%cr0, %0" : "=r" (cr0) : : "memory");
+ return cr0;
+}
+
+static inline void write_cr0(unsigned long cr0)
+{
+ asm volatile ("movl %0, %%cr0" : : "r" (cr0) : "memory");
+}
+
+static inline void wbinvd(void)
+{
+ asm volatile ("wbinvd" : : : "memory");
+}
+
+static inline void invd(void)
+{
+ asm volatile("invd" : : : "memory");
+}
+
+static inline void enable_cache(void)
+{
+ unsigned long cr0;
+ cr0 = read_cr0();
+ cr0 &= 0x9fffffff;
+ write_cr0(cr0);
+}
+
+static inline void disable_cache(void)
+{
+ /* Disable and write back the cache */
+ unsigned long cr0;
+ cr0 = read_cr0();
+ cr0 |= 0x40000000;
+ wbinvd();
+ write_cr0(cr0);
+ wbinvd();
+}
+
+#endif /* CPU_X86_ASM_CACHE */
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
new file mode 100644
index 0000000000..e8e2e4172b
--- /dev/null
+++ b/arch/x86/include/asm/msr.h
@@ -0,0 +1,24 @@
+#ifndef CPU_X86_ASM_MSR_H
+#define CPU_X86_ASM_MSR_H
+
+static inline uint64_t rdmsr(unsigned index)
+{
+ uint64_t result;
+ asm volatile (
+ "rdmsr"
+ : "=A" (result)
+ : "c" (index)
+ );
+ return result;
+}
+
+static inline void wrmsr(unsigned index, uint64_t msr)
+{
+ asm volatile (
+ "wrmsr"
+ : /* No outputs */
+ : "c" (index), "A" (msr)
+ );
+}
+
+#endif /* CPU_X86_ASM_MSR_H */
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 353abbcb08..e6ce69353c 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -285,8 +285,23 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
return 0;
}
+/*
+ * Implement a weak default function for boards that optionally
+ * need to clean up the system before jumping to the kernel.
+ */
+int __board_final_cleanup(void)
+{
+ /* As default, don't skip */
+ return 0;
+}
+int board_final_cleanup(void)
+ __attribute__((weak, alias("__board_final_cleanup")));
+
+
void boot_zimage(void *setup_base, void *load_address)
{
+ board_final_cleanup();
+
printf("\nStarting kernel ...\n\n");
timestamp_add_now(TS_U_BOOT_START_KERNEL);