summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorLee Leahy <leroy.p.leahy@intel.com>2016-03-03 16:48:22 -0800
committerMartin Roth <martinroth@google.com>2016-03-07 04:20:22 +0100
commitfba78bf8972b2fbc9e9089bc41226dcc79953804 (patch)
tree453d7d7ff5bf05ff0967a5e7b58f1b403e5ae1b3 /src/soc
parent6d3cd08252534dfe9a6f49ed772419d8765f0c71 (diff)
soc/intel/quark: Split out MTRR support
Split out the MTRR support into a new module: mtrr.c. TEST=Build and run on Galileo Change-Id: Ib9ec479d171dbbc062509e14fbe246f6d90e903a Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com> Reviewed-on: https://review.coreboot.org/13895 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/quark/romstage/Makefile.inc1
-rw-r--r--src/soc/intel/quark/romstage/mtrr.c201
-rw-r--r--src/soc/intel/quark/romstage/romstage.c181
3 files changed, 202 insertions, 181 deletions
diff --git a/src/soc/intel/quark/romstage/Makefile.inc b/src/soc/intel/quark/romstage/Makefile.inc
index 47972662a9..fc7bd6aeb4 100644
--- a/src/soc/intel/quark/romstage/Makefile.inc
+++ b/src/soc/intel/quark/romstage/Makefile.inc
@@ -16,6 +16,7 @@
cpu_incs-y += $(src)/soc/intel/quark/romstage/esram_init.inc
cpu_incs-y += $(src)/soc/intel/quark/romstage/cache_as_ram.inc
+romstage-y += mtrr.c
romstage-y += report_platform.c
romstage-y += romstage.c
romstage-$(CONFIG_ENABLE_BUILTIN_HSUART1) += uart.c
diff --git a/src/soc/intel/quark/romstage/mtrr.c b/src/soc/intel/quark/romstage/mtrr.c
new file mode 100644
index 0000000000..a0313fb0a0
--- /dev/null
+++ b/src/soc/intel/quark/romstage/mtrr.c
@@ -0,0 +1,201 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * 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.
+ */
+
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <soc/intel/common/util.h>
+#include <soc/pci_devs.h>
+#include <soc/romstage.h>
+
+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);
+}
diff --git a/src/soc/intel/quark/romstage/romstage.c b/src/soc/intel/quark/romstage/romstage.c
index 28d0b034ea..731e52975d 100644
--- a/src/soc/intel/quark/romstage/romstage.c
+++ b/src/soc/intel/quark/romstage/romstage.c
@@ -16,8 +16,6 @@
#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>
@@ -49,182 +47,3 @@ 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);
-}