coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ramstage.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/cpu.h>
4 #include <acpi/acpi_pm.h>
5 #include <console/console.h>
6 #include <cpu/intel/microcode.h>
7 #include <cpu/x86/cr.h>
8 #include <cpu/x86/msr.h>
9 #include <device/device.h>
10 #include <device/pci_def.h>
11 #include <device/pci_ops.h>
13 #include <fsp/util.h>
14 #include <soc/gpio.h>
15 #include <soc/lpc.h>
16 #include <soc/msr.h>
17 #include <soc/pattrs.h>
18 #include <soc/pci_devs.h>
19 #include <soc/pm.h>
20 #include <soc/ramstage.h>
21 
22 #define SHOW_PATTRS 1
23 
24 struct pattrs __global_pattrs;
25 
26 static void detect_num_cpus(struct pattrs *attrs)
27 {
28  int ecx = 0;
29 
30  while (1) {
31  struct cpuid_result leaf_b;
32 
33  leaf_b = cpuid_ext(0xb, ecx);
34 
35  /*
36  * The SOC doesn't have hyperthreading so just determine the
37  * number of cores by from level type (ecx[15:8] == * 2).
38  */
39  if ((leaf_b.ecx & 0xff00) == 0x0200) {
40  attrs->num_cpus = leaf_b.ebx & 0xffff;
41  break;
42  }
43  ecx++;
44  }
45 }
46 
47 static inline void fill_in_msr(msr_t *msr, int idx)
48 {
49  *msr = rdmsr(idx);
50  if (SHOW_PATTRS) {
51  printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
52  idx, msr->hi, msr->lo);
53  }
54 }
55 
56 static const char *const stepping_str[] = {
57  "A0", "A1", "B0", "B1", "B2", "B3", "C0", "D1"
58 };
59 
60 static void fill_in_pattrs(void)
61 {
62  struct device *dev;
63  msr_t msr;
64  struct pattrs *attrs = (struct pattrs *)pattrs_get();
65 
66  attrs->cpuid = cpuid_eax(1);
68  attrs->revid = pci_read_config8(dev, REVID);
69  /* The revision to stepping IDs have two values per metal stepping. */
70  if (attrs->revid >= RID_D_STEPPING_START) {
71  attrs->stepping = (attrs->revid - RID_D_STEPPING_START) / 2;
72  attrs->stepping += STEP_D1;
73 
74  } else if (attrs->revid >= RID_C_STEPPING_START) {
75  attrs->stepping = (attrs->revid - RID_C_STEPPING_START) / 2;
76  attrs->stepping += STEP_C0;
77 
78  } else if (attrs->revid >= RID_B_STEPPING_START) {
79  attrs->stepping = (attrs->revid - RID_B_STEPPING_START) / 2;
80  attrs->stepping += STEP_B0;
81 
82  } else {
83  attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
84  attrs->stepping += STEP_A0;
85  }
86 
87  attrs->microcode_patch = intel_microcode_find();
88  attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
90 
91  if (SHOW_PATTRS) {
92  printk(BIOS_DEBUG, "Cpuid %08x cpus %d rid %02x step %s\n",
93  attrs->cpuid, attrs->num_cpus, attrs->revid,
94  (attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
95  stepping_str[attrs->stepping]);
96  }
97 
98  fill_in_msr(&attrs->platform_id, IA32_PLATFORM_ID);
99  fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
100 
101  /* Set IA core speed ratio and voltages */
103  attrs->iacore_ratios[IACORE_MIN] = (msr.lo >> 0) & 0x7f;
104  attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
105  attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
107  attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
108 
110  attrs->iacore_vids[IACORE_MIN] = (msr.lo >> 0) & 0x7f;
111  attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
112  attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
114  attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
115 
116  /* Set bus clock speed */
117  attrs->bclk_khz = cpu_bus_freq_khz();
118 }
119 
120 /* Save wake source information for calculating ACPI _SWS values */
121 int soc_fill_acpi_wake(const struct chipset_power_state *ps, uint32_t *pm1, uint32_t **gpe0)
122 {
123  static uint32_t gpe0_sts;
124 
125  *pm1 = ps->pm1_sts & ps->pm1_en;
126 
127  gpe0_sts = ps->gpe0_sts & ps->gpe0_en;
128  *gpe0 = &gpe0_sts;
129 
130  return 1;
131 }
132 
134 {
136 
137  fill_in_pattrs();
138 
139  /* Allow for SSE instructions to be executed. */
141 
142  /* Perform silicon specific init. */
144  set_max_freq();
145 
146  /* Get GPIO initial states from mainboard */
148  setup_soc_gpios(gpio_config, config->enable_xdp_tap);
149 }
static struct @1 attrs[]
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
static struct cpuid_result cpuid_ext(int op, unsigned int ecx)
Definition: cpu.h:59
static const struct pattrs * pattrs_get(void)
Definition: pattrs.h:41
@ IACORE_TURBO
Definition: pattrs.h:13
@ IACORE_MAX
Definition: pattrs.h:12
@ IACORE_MIN
Definition: pattrs.h:10
@ IACORE_LFM
Definition: pattrs.h:11
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
void set_max_freq(void)
Definition: romstage.c:7
#define CR4_OSXMMEXCPT
Definition: cr.h:124
static __always_inline void write_cr4(CRx_TYPE data)
Definition: cr.h:88
static __always_inline CRx_TYPE read_cr4(void)
Definition: cr.h:76
#define CR4_OSFXSR
Definition: cr.h:123
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
void intel_silicon_init(void)
Definition: ramstage.c:155
#define MSR_PLATFORM_INFO
Definition: fsb.c:16
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
#define IA32_PLATFORM_ID
Definition: msr.h:18
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
struct soc_gpio_config * mainboard_get_gpios(void)
Definition: gpio.c:207
static struct soc_gpio_config gpio_config
Definition: gpio.c:199
enum board_config config
Definition: memory.c:448
const void * intel_microcode_find(void)
Definition: microcode.c:223
#define LPC_DEV
Definition: romstage.c:15
#define LPC_FUNC
Definition: pci_devs.h:122
void setup_soc_gpios(struct soc_gpio_config *config, u8 enable_xdp_tap)
Definition: gpio.c:202
#define RID_A_STEPPING_START
Definition: lpc.h:19
@ STEP_A0
Definition: lpc.h:25
@ STEP_B0
Definition: lpc.h:27
@ STEP_C0
Definition: lpc.h:31
#define RID_B_STEPPING_START
Definition: lpc.h:20
#define RID_D_STEPPING_START
Definition: lpc.h:22
#define REVID
Definition: lpc.h:7
#define RID_C_STEPPING_START
Definition: lpc.h:21
#define MSR_IACORE_TURBO_VIDS
Definition: msr.h:20
#define MSR_IACORE_TURBO_RATIOS
Definition: msr.h:18
#define MSR_IACORE_RATIOS
Definition: msr.h:17
#define MSR_IACORE_VIDS
Definition: msr.h:19
struct pattrs __global_pattrs
Definition: ramstage.c:28
@ STEP_D1
Definition: lpc.h:39
unsigned int cpu_bus_freq_khz(void)
Definition: tsc_freq.c:19
#define SHOW_PATTRS
Definition: ramstage.c:22
int soc_fill_acpi_wake(const struct chipset_power_state *ps, uint32_t *pm1, uint32_t **gpe0)
Definition: ramstage.c:121
void soc_init_pre_device(struct soc_intel_braswell_config *config)
Definition: ramstage.c:133
static void detect_num_cpus(struct pattrs *attrs)
Definition: ramstage.c:26
static void fill_in_pattrs(void)
Definition: ramstage.c:60
static const char *const stepping_str[]
Definition: ramstage.c:56
static void fill_in_msr(msr_t *msr, int idx)
Definition: ramstage.c:47
unsigned int uint32_t
Definition: stdint.h:14
uint32_t gpe0_en[4]
Definition: pm.h:148
uint32_t gpe0_sts[4]
Definition: pm.h:147
uint16_t pm1_en
Definition: pm.h:143
uint16_t pm1_sts
Definition: pm.h:142
uint32_t ecx
Definition: cpu.h:32
uint32_t ebx
Definition: cpu.h:31
Definition: device.h:107
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111
Definition: pattrs.h:22