From 452d31ad752cff53776b1780e2dac76c67575997 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Tue, 24 Sep 2013 16:47:49 -0500 Subject: baytrail: introduce pattrs The pattrs structure is intended for the supporting coreboot code to reference instead of going back to the source of the values (msrs, cpuid, etc). It essentially serves as a global structure for collecting attributes about the platform/processor. Additionally, the implementation provides a point during boot to hoook work before device enumeration/initialization by providing a init() function to soc_intel_baytrail_ops that is called before device work in the boot state machine. BUG=chrome-os-partner:22862 BUG=chrome-os-partner:22863 BRANCH=None TEST=Built and booted. Noted pattrs output. Change-Id: I073da8aca29635146fb0d4a2625b2b7564fd8414 Signed-off-by: Aaron Durbin Reviewed-on: https://chromium-review.googlesource.com/170403 Reviewed-by: Shawn Nematbakhsh Reviewed-on: http://review.coreboot.org/4854 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/intel/baytrail/Makefile.inc | 2 + src/soc/intel/baytrail/baytrail/lpc.h | 13 ++++ src/soc/intel/baytrail/baytrail/msr.h | 7 +- src/soc/intel/baytrail/baytrail/pattrs.h | 56 +++++++++++++++ src/soc/intel/baytrail/baytrail/ramstage.h | 4 ++ src/soc/intel/baytrail/chip.c | 7 ++ src/soc/intel/baytrail/ramstage.c | 107 +++++++++++++++++++++++++++++ 7 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 src/soc/intel/baytrail/baytrail/pattrs.h create mode 100644 src/soc/intel/baytrail/ramstage.c (limited to 'src/soc') 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 +#include + +/* 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 +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* 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(); +} -- cgit v1.2.3