summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/baytrail/Makefile.inc2
-rw-r--r--src/soc/intel/baytrail/baytrail/lpc.h13
-rw-r--r--src/soc/intel/baytrail/baytrail/msr.h7
-rw-r--r--src/soc/intel/baytrail/baytrail/pattrs.h56
-rw-r--r--src/soc/intel/baytrail/baytrail/ramstage.h4
-rw-r--r--src/soc/intel/baytrail/chip.c7
-rw-r--r--src/soc/intel/baytrail/ramstage.c107
7 files changed, 195 insertions, 1 deletions
diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc
index d8dcaf6f41..756fd39f8f 100644
--- a/src/soc/intel/baytrail/Makefile.inc
+++ b/src/soc/intel/baytrail/Makefile.inc
@@ -3,6 +3,7 @@ subdirs-y += romstage
subdirs-y += ../../../cpu/x86/lapic
subdirs-y += ../../../cpu/x86/mtrr
subdirs-y += ../../../cpu/x86/tsc
+subdirs-y += ../../../cpu/intel/microcode
ramstage-y += memmap.c
romstage-y += memmap.c
@@ -16,6 +17,7 @@ ramstage-y += chip.c
ramstage-y += iosf.c
romstage-y += iosf.c
ramstage-y += northcluster.c
+ramstage-y += ramstage.c
# Remove as ramstage gets fleshed out
diff --git a/src/soc/intel/baytrail/baytrail/lpc.h b/src/soc/intel/baytrail/baytrail/lpc.h
index 17dc4b533c..05220e452d 100644
--- a/src/soc/intel/baytrail/baytrail/lpc.h
+++ b/src/soc/intel/baytrail/baytrail/lpc.h
@@ -21,6 +21,7 @@
#define _BAYTRAIL_LPC_H_
/* PCI config registers in LPC bridge. */
+#define REVID 0x08
#define ABASE 0x40
#define PBASE 0x44
#define GBASE 0x48
@@ -31,4 +32,16 @@
#define UART_CONT 0x80
#define RCBA 0xf0
+
+#define RID_A_STEPPING_START 1
+#define RID_B_STEPPING_START 5
+enum baytrail_stepping {
+ STEP_A0,
+ STEP_A1,
+ STEP_B0,
+ STEP_B1,
+ STEP_B2,
+ STEP_B3,
+};
+
#endif /* _BAYTRAIL_LPC_H_ */
diff --git a/src/soc/intel/baytrail/baytrail/msr.h b/src/soc/intel/baytrail/baytrail/msr.h
index 1934a31354..7f3b3b26fd 100644
--- a/src/soc/intel/baytrail/baytrail/msr.h
+++ b/src/soc/intel/baytrail/baytrail/msr.h
@@ -20,6 +20,11 @@
#ifndef _BAYTRAIL_MSR_H_
#define _BAYTRAIL_MSR_H_
-#define MSR_PLATFORM_INFO 0xce
+#define MSR_IA32_PLATFORM_ID 0x17
+#define MSR_PLATFORM_INFO 0xce
+#define MSR_IA32_PERF_CTL 0x199
+#define MSR_IA32_MISC_ENABLES 0x1a0
+#define MSR_IACORE_RATIOS 0x66a
+#define MSR_IACORE_VIDS 0x66b
#endif /* _BAYTRAIL_IOSF_H_ */
diff --git a/src/soc/intel/baytrail/baytrail/pattrs.h b/src/soc/intel/baytrail/baytrail/pattrs.h
new file mode 100644
index 0000000000..7c210b95af
--- /dev/null
+++ b/src/soc/intel/baytrail/baytrail/pattrs.h
@@ -0,0 +1,56 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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 _PATTRS_H_
+#define _PATTRS_H_
+
+#include <stdint.h>
+#include <cpu/x86/msr.h>
+
+/* The pattrs structure is a common place to stash pertinent information
+ * about the processor or platform. Instead of going to the source (msrs, cpuid)
+ * every time an attribute is needed use the pattrs structure.
+ */
+struct pattrs {
+ msr_t platform_id;
+ msr_t platform_info;
+ msr_t iacore_ratios;
+ msr_t iacore_vids;
+ uint32_t cpuid;
+ int revid;
+ int stepping;
+ const void *microcode_patch;
+ int address_bits;
+ int num_cpus;
+};
+
+/* This is just to hide the abstraction w/o relying on how the underlying
+ * storage is allocated. */
+#define PATTRS_GLOB_NAME __global_pattrs
+#define DEFINE_PATTRS struct pattrs PATTRS_GLOB_NAME
+extern DEFINE_PATTRS;
+
+static inline const struct pattrs *pattrs_get(void)
+{
+ return &PATTRS_GLOB_NAME;
+}
+
+
+#endif /* _PATTRS_H_ */
+
diff --git a/src/soc/intel/baytrail/baytrail/ramstage.h b/src/soc/intel/baytrail/baytrail/ramstage.h
index 61fe9c3ff7..d1fe0f1d15 100644
--- a/src/soc/intel/baytrail/baytrail/ramstage.h
+++ b/src/soc/intel/baytrail/baytrail/ramstage.h
@@ -22,6 +22,10 @@
#include <device/device.h>
+/* The baytrail_init_pre_device() function is called prior to device
+ * initialization, but it's after console and cbmem has been reinitialized. */
+void baytrail_init_pre_device(void);
+
extern struct pci_operations soc_pci_ops;
#endif /* _BAYTRAIL_RAMSTAGE_H_ */
diff --git a/src/soc/intel/baytrail/chip.c b/src/soc/intel/baytrail/chip.c
index 09c36dfd5d..5a898f6e31 100644
--- a/src/soc/intel/baytrail/chip.c
+++ b/src/soc/intel/baytrail/chip.c
@@ -68,9 +68,16 @@ static void enable_dev(device_t dev)
}
}
+/* Called at BS_DEV_INIT_CHIPS time -- very early. Just after BS_PRE_DEVICE. */
+static void soc_init(void *chip_info)
+{
+ baytrail_init_pre_device();
+}
+
struct chip_operations soc_intel_baytrail_ops = {
CHIP_NAME("Intel BayTrail SoC")
.enable_dev = enable_dev,
+ .init = soc_init,
};
static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
diff --git a/src/soc/intel/baytrail/ramstage.c b/src/soc/intel/baytrail/ramstage.c
new file mode 100644
index 0000000000..e30fc89bc2
--- /dev/null
+++ b/src/soc/intel/baytrail/ramstage.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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
+ */
+
+#include <arch/cpu.h>
+#include <console/console.h>
+#include <cpu/intel/microcode.h>
+#include <cpu/x86/msr.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <stdlib.h>
+
+#include <baytrail/pattrs.h>
+#include <baytrail/lpc.h>
+#include <baytrail/msr.h>
+#include <baytrail/pci_devs.h>
+#include <baytrail/ramstage.h>
+
+/* Global PATTRS */
+DEFINE_PATTRS;
+
+#define SHOW_PATTRS 1
+
+static void detect_num_cpus(struct pattrs *attrs)
+{
+ int ecx = 0;
+
+ while (1) {
+ struct cpuid_result leaf_b;
+
+ leaf_b = cpuid_ext(0xb, ecx);
+
+ /* Bay Trail doesn't have hyperthreading so just determine the
+ * number of cores by from level type (ecx[15:8] == * 2). */
+ if ((leaf_b.ecx & 0xff00) == 0x0200) {
+ attrs->num_cpus = leaf_b.ebx & 0xffff;
+ break;
+ }
+ ecx++;
+ }
+}
+
+static inline void fill_in_msr(msr_t *msr, int idx)
+{
+ *msr = rdmsr(idx);
+ if (SHOW_PATTRS) {
+ printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
+ idx, msr->hi, msr->lo);
+ }
+}
+
+static const char *stepping_str[] = { "A0", "A1", "B0", "B1", "B2", "B3" };
+
+static void fill_in_pattrs(void)
+{
+ device_t dev;
+ struct pattrs *attrs = (struct pattrs *)pattrs_get();
+
+ attrs->cpuid = cpuid_eax(1);
+ dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC));
+ attrs->revid = pci_read_config8(dev, REVID);
+ /* The revision to stepping IDs have two values per metal stepping. */
+ if (attrs->revid >= RID_B_STEPPING_START) {
+ attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
+ attrs->stepping += STEP_B0;
+ } else {
+ attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
+ attrs->stepping += STEP_A0;
+ }
+
+ attrs->microcode_patch = intel_microcode_find();
+ attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
+ detect_num_cpus(attrs);
+
+ if (SHOW_PATTRS) {
+ printk(BIOS_DEBUG, "BYT: cpuid %08x cpus %d rid %02x step %s\n",
+ attrs->cpuid, attrs->num_cpus, attrs->revid,
+ (attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
+ stepping_str[attrs->stepping]);
+ }
+
+ fill_in_msr(&attrs->platform_id, MSR_IA32_PLATFORM_ID);
+ fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
+ fill_in_msr(&attrs->iacore_ratios, MSR_IACORE_RATIOS);
+ fill_in_msr(&attrs->iacore_vids, MSR_IACORE_VIDS);
+}
+
+void baytrail_init_pre_device(void)
+{
+ fill_in_pattrs();
+}