[U-Boot] [PATCH] x86: quark: Configure MTRR to enable cache

Bin Meng bmeng.cn at gmail.com
Mon Sep 14 09:07:41 CEST 2015


Quark SoC does not support MSR MTRRs. Fixed and variable range MTRRs
are accessed indirectly via the message port and not the traditional
MSR mechanism. Only UC, WT and WB cache types are supported.

We configure all the fixed range MTRRs with common values (VGA RAM
as UC, others as WB) and 3 variable range MTRRs for ROM/eSRAM/RAM as
WB, which significantly improves the boot time performance.

With this commit, it takes only 2 seconds for U-Boot to boot to shell
on Intel Galileo board. Previously it took about 6 seconds.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
---

 arch/x86/cpu/quark/dram.c               | 10 ++++++
 arch/x86/cpu/quark/quark.c              | 57 +++++++++++++++++++++++++++++++++
 arch/x86/include/asm/arch-quark/quark.h | 44 +++++++++++++++++++++++++
 3 files changed, 111 insertions(+)

diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c
index 9cac846..1b89376 100644
--- a/arch/x86/cpu/quark/dram.c
+++ b/arch/x86/cpu/quark/dram.c
@@ -7,8 +7,10 @@
 #include <common.h>
 #include <errno.h>
 #include <fdtdec.h>
+#include <asm/mtrr.h>
 #include <asm/post.h>
 #include <asm/arch/mrc.h>
+#include <asm/arch/msg_port.h>
 #include <asm/arch/quark.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -111,6 +113,14 @@ int dram_init(void)
 	gd->ram_size = mrc_params.mem_size;
 	post_code(POST_DRAM);
 
+	/* variable range MTRR#2: RAM area */
+	disable_caches();
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_RAM),
+		       0 | MTRR_TYPE_WRBACK);
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_RAM),
+		       (~(gd->ram_size - 1)) | MTRR_PHYS_MASK_VALID);
+	enable_caches();
+
 	return 0;
 }
 
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index 8b78a86..77d644a 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -8,6 +8,7 @@
 #include <mmc.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/mtrr.h>
 #include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/processor.h>
@@ -34,6 +35,55 @@ static void unprotect_spi_flash(void)
 	qrk_pci_write_config_dword(QUARK_LEGACY_BRIDGE, 0xd8, bc);
 }
 
+static void quark_setup_mtrr(void)
+{
+	u32 base, mask;
+	int i;
+
+	disable_caches();
+
+	/* mark the VGA RAM area as uncacheable */
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_A0000,
+		       MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_B0000,
+		       MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
+
+	/* mark other fixed range areas as cacheable */
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_64K_00000,
+		       MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_64K_40000,
+		       MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_80000,
+		       MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_FIX_16K_90000,
+		       MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+	for (i = MTRR_FIX_4K_C0000; i <= MTRR_FIX_4K_FC000; i++)
+		msg_port_write(MSG_PORT_HOST_BRIDGE, i,
+			       MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+
+	/* variable range MTRR#0: ROM area */
+	mask = ~(CONFIG_SYS_MONITOR_LEN - 1);
+	base = CONFIG_SYS_TEXT_BASE & mask;
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_ROM),
+		       base | MTRR_TYPE_WRBACK);
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_ROM),
+		       mask | MTRR_PHYS_MASK_VALID);
+
+	/* variable range MTRR#1: eSRAM area */
+	mask = ~(ESRAM_SIZE - 1);
+	base = CONFIG_ESRAM_BASE & mask;
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYBASE(MTRR_VAR_ESRAM),
+		       base | MTRR_TYPE_WRBACK);
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_VAR_PHYMASK(MTRR_VAR_ESRAM),
+		       mask | MTRR_PHYS_MASK_VALID);
+
+	/* enable both variable and fixed range MTRRs */
+	msg_port_write(MSG_PORT_HOST_BRIDGE, MTRR_DEF_TYPE,
+		       MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN);
+
+	enable_caches();
+}
+
 static void quark_setup_bars(void)
 {
 	/* GPIO - D31:F0:R44h */
@@ -191,6 +241,13 @@ int arch_cpu_init(void)
 		return ret;
 
 	/*
+	 * Quark SoC does not support MSR MTRRs. Fixed and variable range MTRRs
+	 * are accessed indirectly via the message port and not the traditional
+	 * MSR mechanism. Only UC, WT and WB cache types are supported.
+	 */
+	quark_setup_mtrr();
+
+	/*
 	 * Quark SoC has some non-standard BARs (excluding PCI standard BARs)
 	 * which need be initialized with suggested values
 	 */
diff --git a/arch/x86/include/asm/arch-quark/quark.h b/arch/x86/include/asm/arch-quark/quark.h
index f6009f6..7a864c7 100644
--- a/arch/x86/include/asm/arch-quark/quark.h
+++ b/arch/x86/include/asm/arch-quark/quark.h
@@ -37,6 +37,50 @@
 /* Extended Configuration Space */
 #define HEC_REG			0x09
 
+/* MTRR Registers */
+#define MTRR_CAP		0x40
+#define MTRR_DEF_TYPE		0x41
+
+#define MTRR_FIX_64K_00000	0x42
+#define MTRR_FIX_64K_40000	0x43
+#define MTRR_FIX_16K_80000	0x44
+#define MTRR_FIX_16K_90000	0x45
+#define MTRR_FIX_16K_A0000	0x46
+#define MTRR_FIX_16K_B0000	0x47
+#define MTRR_FIX_4K_C0000	0x48
+#define MTRR_FIX_4K_C4000	0x49
+#define MTRR_FIX_4K_C8000	0x4a
+#define MTRR_FIX_4K_CC000	0x4b
+#define MTRR_FIX_4K_D0000	0x4c
+#define MTRR_FIX_4K_D4000	0x4d
+#define MTRR_FIX_4K_D8000	0x4e
+#define MTRR_FIX_4K_DC000	0x4f
+#define MTRR_FIX_4K_E0000	0x50
+#define MTRR_FIX_4K_E4000	0x51
+#define MTRR_FIX_4K_E8000	0x52
+#define MTRR_FIX_4K_EC000	0x53
+#define MTRR_FIX_4K_F0000	0x54
+#define MTRR_FIX_4K_F4000	0x55
+#define MTRR_FIX_4K_F8000	0x56
+#define MTRR_FIX_4K_FC000	0x57
+
+#define MTRR_SMRR_PHYBASE	0x58
+#define MTRR_SMRR_PHYMASK	0x59
+
+#define MTRR_VAR_PHYBASE(n)	(0x5a + 2 * (n))
+#define MTRR_VAR_PHYMASK(n)	(0x5b + 2 * (n))
+
+#ifndef __ASSEMBLY__
+
+/* variable range MTRR usage */
+enum {
+	MTRR_VAR_ROM,
+	MTRR_VAR_ESRAM,
+	MTRR_VAR_RAM
+};
+
+#endif /* __ASSEMBLY__ */
+
 /* Port 0x04: Remote Management Unit Message Port Registers */
 
 /* ACPI PBLK Base Address Register */
-- 
1.8.2.1



More information about the U-Boot mailing list