[coreboot-gerrit] Patch set updated for coreboot: soc/intel/quark: MTRR support

Leroy P Leahy (leroy.p.leahy@intel.com) gerrit at coreboot.org
Mon Feb 8 00:03:45 CET 2016


Leroy P Leahy (leroy.p.leahy at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13530

-gerrit

commit ffe8913f2dbb34362094d9ec4679afa09c7c910d
Author: Lee Leahy <leroy.p.leahy at intel.com>
Date:   Sun Feb 7 14:52:22 2016 -0800

    soc/intel/quark: MTRR support
    
    Add the SoC specific routines to access the MTRR registers.  These
    registers exist in the host bridge and are not accessible via the
    rdmsr/wrmsr instructions.
    
    Testing on Galileo:
    *  Edit the src/mainboard/intel/galileo/Makefile.inc file
       *  Add "select ADD_FSP_PDAT_FILE"
       *  Add "select ADD_FSP_RAW_BIN"
       *  Add "select ADD_RMU_FILE"
       *  Add "select DISPLAY_MTRRS"
    *  Place the FSP.bin file in the location specified by CONFIG_FSP_FILE
    *  Place the pdat.bin files in the location specified by
    CONFIG_FSP_PDAT_FILE
    *  Place the rmu.bin file in the location specified by CONFIG_RMU_FILE
    *  Testing is successful if:
       *  The message "FSP TempRamInit successful" is displayed
    
    Change-Id: I7c124145429ae1d1365a6222a68853edbef4ff69
    Signed-off-by: Lee Leahy <leroy.p.leahy at intel.com>
---
 src/soc/intel/quark/Kconfig                   |   2 +
 src/soc/intel/quark/include/soc/pci_devs.h    |   6 +
 src/soc/intel/quark/include/soc/romstage.h    |   6 +
 src/soc/intel/quark/romstage/cache_as_ram.inc |   7 +
 src/soc/intel/quark/romstage/romstage.c       | 184 ++++++++++++++++++++++++++
 5 files changed, 205 insertions(+)

diff --git a/src/soc/intel/quark/Kconfig b/src/soc/intel/quark/Kconfig
index d99cd54..08272f0 100644
--- a/src/soc/intel/quark/Kconfig
+++ b/src/soc/intel/quark/Kconfig
@@ -27,8 +27,10 @@ config CPU_SPECIFIC_OPTIONS
 	select ARCH_ROMSTAGE_X86_32
 	select ARCH_VERSTAGE_X86_32
 	select SOC_INTEL_COMMON
+	select SOC_SETS_MTRRS
 	select TSC_CONSTANT_RATE
 	select UDELAY_TSC
+	select UNCOMPRESSED_RAMSTAGE
 	select USE_MARCH_586
 
 #####
diff --git a/src/soc/intel/quark/include/soc/pci_devs.h b/src/soc/intel/quark/include/soc/pci_devs.h
index 0543a05..4ab23b9 100644
--- a/src/soc/intel/quark/include/soc/pci_devs.h
+++ b/src/soc/intel/quark/include/soc/pci_devs.h
@@ -18,6 +18,12 @@
 #ifndef _QUARK_PCI_DEVS_H_
 #define _QUARK_PCI_DEVS_H_
 
+#include <device/pci.h>
+#include <soc/QuarkNcSocId.h>
+
+/* DEVICE 0 (Memroy Controller Hub) */
+#define MC_BDF		PCI_DEV(PCI_BUS_NUMBER_QNC, MC_DEV, MC_FUN)
+
 /* IO Fabric 1 */
 #define SIO1_DEV 0x14
 # define HSUART1_DEV SIO1_DEV
diff --git a/src/soc/intel/quark/include/soc/romstage.h b/src/soc/intel/quark/include/soc/romstage.h
index a35f4a6..3a1320c 100644
--- a/src/soc/intel/quark/include/soc/romstage.h
+++ b/src/soc/intel/quark/include/soc/romstage.h
@@ -22,8 +22,14 @@
 #error "Don't include romstage.h from a ramstage compilation unit!"
 #endif
 
+#include <fsp/romstage.h>
 #include <fsp/util.h>
+#include <soc/QuarkNcSocId.h>
 
+void mcr_write(uint8_t opcode, uint8_t port, uint32_t reg_address);
+uint32_t mdr_read(void);
+void mdr_write(uint32_t value);
+void mea_write(uint32_t reg_address);
 int set_base_address_and_enable_uart(u8 bus, u8 dev, u8 func, u32 mmio_base);
 
 #endif /* _QUARK_ROMSTAGE_H_ */
diff --git a/src/soc/intel/quark/romstage/cache_as_ram.inc b/src/soc/intel/quark/romstage/cache_as_ram.inc
index 4fc60e2..a935bdf 100644
--- a/src/soc/intel/quark/romstage/cache_as_ram.inc
+++ b/src/soc/intel/quark/romstage/cache_as_ram.inc
@@ -154,6 +154,13 @@ before_romstage:
 
 	/* Call cache_as_ram_main(struct cache_as_ram_params *) */
 	call	cache_as_ram_main
+
+/* One will never return from cache_as_ram_main() in verstage so there's
+ * no such thing as after ram init. */
+#if !ENV_VERSTAGE
+#include "src/drivers/intel/fsp1_1/after_raminit.S"
+#endif
+
 	movb	$0x69, %ah
 	jmp	.Lhlt
 
diff --git a/src/soc/intel/quark/romstage/romstage.c b/src/soc/intel/quark/romstage/romstage.c
index 19d0642..495e454 100644
--- a/src/soc/intel/quark/romstage/romstage.c
+++ b/src/soc/intel/quark/romstage/romstage.c
@@ -16,7 +16,12 @@
 
 #include <arch/early_variables.h>
 #include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <device/pci_def.h>
 #include <fsp/car.h>
+#include <fsp/util.h>
+#include <soc/intel/common/util.h>
 #include <soc/iomap.h>
 #include <soc/pci_devs.h>
 #include <soc/pm.h>
@@ -39,3 +44,182 @@ struct chipset_power_state *fill_power_state(void)
 	printk(BIOS_DEBUG, "prev_sleep_state %d\n", ps->prev_sleep_state);
 	return ps;
 }
+
+void mcr_write(uint8_t opcode, uint8_t port, uint32_t reg_address)
+{
+	pci_write_config32(MC_BDF, QNC_ACCESS_PORT_MCR,
+		(opcode << QNC_MCR_OP_OFFSET)
+		| ((uint32_t)port << QNC_MCR_PORT_OFFSET)
+		| ((reg_address & QNC_MCR_MASK) << QNC_MCR_REG_OFFSET)
+		| QNC_MCR_BYTE_ENABLES);
+}
+
+uint32_t mdr_read(void)
+{
+	return pci_read_config32(MC_BDF, QNC_ACCESS_PORT_MDR);
+}
+
+void mdr_write(uint32_t value)
+{
+	pci_write_config32(MC_BDF, QNC_ACCESS_PORT_MDR, value);
+}
+
+void mea_write(uint32_t reg_address)
+{
+	pci_write_config32(MC_BDF, QNC_ACCESS_PORT_MEA, reg_address
+		& QNC_MEA_MASK);
+}
+
+static uint32_t mtrr_index_to_host_bridge_register_offset(unsigned long index)
+{
+	uint32_t offset;
+
+	/* Convert from MTRR index to host brigde offset (Datasheet 12.7.2) */
+	if (index == MTRR_CAP_MSR)
+		offset = QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP;
+	else if (index == MTRR_DEF_TYPE_MSR)
+		offset = QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE;
+	else if (index == MTRR_FIX_64K_00000)
+		offset = QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000;
+	else if ((index >= MTRR_FIX_16K_80000) && (index <= MTRR_FIX_16K_A0000))
+		offset = ((index - MTRR_FIX_16K_80000) << 1)
+			+ QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000;
+	else if ((index >= MTRR_FIX_4K_C0000) && (index <= MTRR_FIX_4K_F8000))
+		offset = ((index - MTRR_FIX_4K_C0000) << 1)
+			+ QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0;
+	else if ((index >= MTRR_PHYS_BASE(0)) && (index <= MTRR_PHYS_MASK(7)))
+		offset = (index - MTRR_PHYS_BASE(0))
+			+ QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0;
+	else {
+		printk(BIOS_DEBUG, "index: 0x%08lx\n", index);
+		die("Invalid MTRR index specified!\n");
+	}
+	return offset;
+}
+
+msr_t soc_mtrr_read(unsigned long index)
+{
+	uint32_t offset;
+	union {
+		uint64_t u64;
+		msr_t msr;
+	} value;
+
+	/* Read the low 32-bits of the register */
+	offset = mtrr_index_to_host_bridge_register_offset(index);
+	mea_write(offset);
+	mcr_write(QUARK_OPCODE_READ, QUARK_NC_HOST_BRIDGE_SB_PORT_ID, offset);
+	value.u64 = mdr_read();
+
+	/* For 64-bit registers, read the upper 32-bits */
+	if ((offset >=  QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000)
+		&& (offset <= QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000)) {
+		offset += 1;
+		mea_write(offset);
+		mcr_write(QUARK_OPCODE_READ, QUARK_NC_HOST_BRIDGE_SB_PORT_ID,
+			offset);
+		value.u64 |= mdr_read();
+	}
+	return value.msr;
+}
+
+void soc_mtrr_write(unsigned long index, msr_t msr)
+{
+	uint32_t offset;
+	union {
+		uint32_t u32[2];
+		msr_t msr;
+	} value;
+
+	/* Write the low 32-bits of the register */
+	value.msr = msr;
+	offset = mtrr_index_to_host_bridge_register_offset(index);
+	mea_write(offset);
+	mdr_write(value.u32[0]);
+	mcr_write(QUARK_OPCODE_WRITE, QUARK_NC_HOST_BRIDGE_SB_PORT_ID, offset);
+
+	/* For 64-bit registers, write the upper 32-bits */
+	if ((offset >=  QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000)
+		&& (offset <= QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000)) {
+		offset += 1;
+		mea_write(offset);
+		mdr_write(value.u32[1]);
+		mcr_write(QUARK_OPCODE_WRITE, QUARK_NC_HOST_BRIDGE_SB_PORT_ID,
+			offset);
+	}
+}
+
+asmlinkage void *soc_set_mtrrs(void *top_of_stack)
+{
+	union {
+		uint32_t u32[2];
+		uint64_t u64;
+		msr_t msr;
+	} data;
+	uint32_t mtrr_count;
+	uint32_t *mtrr_data;
+	uint32_t mtrr_reg;
+
+	/*
+	 * The stack contents are initialized in src/soc/intel/common/stack.c
+	 * to be the following:
+	 *
+	 *				*
+	 *				*
+	 *				*
+	 *		   +36: MTRR mask 1 63:32
+	 *		   +32: MTRR mask 1 31:0
+	 *		   +28: MTRR base 1 63:32
+	 *		   +24: MTRR base 1 31:0
+	 *		   +20: MTRR mask 0 63:32
+	 *		   +16: MTRR mask 0 31:0
+	 *		   +12: MTRR base 0 63:32
+	 *		    +8: MTRR base 0 31:0
+	 *		    +4: Number of MTRRs to setup (described above)
+	 * top_of_stack --> +0: Number of variable MTRRs to clear
+	 *
+	 * This routine:
+	 *	* Clears all of the variable MTRRs
+	 *	* Initializes the variable MTRRs with the data passed in
+	 *	* Returns the new top of stack after removing all of the
+	 *	  data passed in.
+	 */
+
+	/* Clear all of the variable MTRRs (base and mask). */
+	mtrr_reg = MTRR_PHYS_BASE(0);
+	mtrr_data = top_of_stack;
+	mtrr_count = (*mtrr_data++) * 2;
+	data.u64 = 0;
+	while (mtrr_count-- > 0)
+		soc_mtrr_write(mtrr_reg++, data.msr);
+
+	/* Setup the specified variable MTRRs */
+	mtrr_reg = MTRR_PHYS_BASE(0);
+	mtrr_count = *mtrr_data++;
+	while (mtrr_count-- > 0) {
+		data.u32[0] = *mtrr_data++;
+		data.u32[1] = *mtrr_data++;
+		soc_mtrr_write(mtrr_reg++, data.msr); /* Base */
+		data.u32[0] = *mtrr_data++;
+		data.u32[1] = *mtrr_data++;
+		soc_mtrr_write(mtrr_reg++, data.msr); /* Mask */
+	}
+
+	/* Remove setup_stack_and_mtrrs data and return the new top_of_stack */
+	top_of_stack = mtrr_data;
+	return top_of_stack;
+}
+
+asmlinkage void soc_enable_mtrrs(void)
+{
+	union {
+		uint32_t u32[2];
+		uint64_t u64;
+		msr_t msr;
+	} data;
+
+	/* Enable MTRR. */
+	data.msr = soc_mtrr_read(MTRR_DEF_TYPE_MSR);
+	data.u32[0] |= MTRR_DEF_TYPE_EN;
+	soc_mtrr_write(MTRR_DEF_TYPE_MSR, data.msr);
+}



More information about the coreboot-gerrit mailing list