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_gnvs.h>
5 #include <acpi/acpi_pm.h>
6 #include <bootstate.h>
7 #include <console/console.h>
8 #include <cpu/intel/microcode.h>
9 #include <cpu/x86/cr.h>
10 #include <cpu/x86/msr.h>
11 #include <device/device.h>
12 #include <device/pci_def.h>
13 #include <device/pci_ops.h>
14 
15 #include <soc/device_nvs.h>
16 #include <soc/gpio.h>
17 #include <soc/lpc.h>
18 #include <soc/msr.h>
19 #include <soc/nvs.h>
20 #include <soc/pattrs.h>
21 #include <soc/pci_devs.h>
22 #include <soc/pm.h>
23 #include <soc/ramstage.h>
24 #include <soc/iosf.h>
25 
26 #define SHOW_PATTRS 1
27 
28 struct pattrs __global_pattrs;
29 
30 static void detect_num_cpus(struct pattrs *attrs)
31 {
32  int ecx = 0;
33 
34  while (1) {
35  struct cpuid_result leaf_b;
36 
37  leaf_b = cpuid_ext(0xb, ecx);
38 
39  /* Bay Trail doesn't have hyperthreading so just determine the
40  * number of cores by from level type (ecx[15:8] == * 2). */
41  if ((leaf_b.ecx & 0xff00) == 0x0200) {
42  attrs->num_cpus = leaf_b.ebx & 0xffff;
43  break;
44  }
45  ecx++;
46  }
47 }
48 
49 static inline void fill_in_msr(msr_t *msr, int idx)
50 {
51  *msr = rdmsr(idx);
52  if (SHOW_PATTRS) {
53  printk(BIOS_DEBUG, "msr(%x) = %08x%08x\n",
54  idx, msr->hi, msr->lo);
55  }
56 }
57 
58 static const char *stepping_str[] = {
59  "A0", "A1", "B0", "B1", "B2", "B3", "C0", "D0",
60 };
61 
62 static void fill_in_pattrs(void)
63 {
64  struct device *dev;
65  msr_t msr;
66  struct pattrs *attrs = (struct pattrs *)pattrs_get();
67 
68  attrs->cpuid = cpuid_eax(1);
70  attrs->revid = pci_read_config8(dev, REVID);
71  /* The revision to stepping IDs have two values per metal stepping. */
72  if (attrs->revid >= RID_D_STEPPING_START) {
73  attrs->stepping = (attrs->revid - RID_D_STEPPING_START) / 2;
74  attrs->stepping += STEP_D0;
75  } else if (attrs->revid >= RID_C_STEPPING_START) {
76  attrs->stepping = (attrs->revid - RID_C_STEPPING_START) / 2;
77  attrs->stepping += STEP_C0;
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  } else {
82  attrs->stepping = (attrs->revid - RID_A_STEPPING_START) / 2;
83  attrs->stepping += STEP_A0;
84  }
85 
86  attrs->microcode_patch = intel_microcode_find();
87  attrs->address_bits = cpuid_eax(0x80000008) & 0xff;
89 
90  if (SHOW_PATTRS) {
91  printk(BIOS_DEBUG, "BYT: cpuid %08x cpus %d rid %02x step %s\n",
92  attrs->cpuid, attrs->num_cpus, attrs->revid,
93  (attrs->stepping >= ARRAY_SIZE(stepping_str)) ? "??" :
94  stepping_str[attrs->stepping]);
95  }
96 
97  fill_in_msr(&attrs->platform_id, IA32_PLATFORM_ID);
98  fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO);
99 
100  /* Set IA core speed ratio and voltages */
101  msr = rdmsr(MSR_IACORE_RATIOS);
102  attrs->iacore_ratios[IACORE_MIN] = msr.lo & 0x7f;
103  attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
104  attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
106  attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
107 
108  msr = rdmsr(MSR_IACORE_VIDS);
109  attrs->iacore_vids[IACORE_MIN] = msr.lo & 0x7f;
110  attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f;
111  attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f;
113  attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */
114 
115  /* Set bus clock speed */
116  attrs->bclk_khz = bus_freq_khz();
117 }
118 
119 size_t size_of_dnvs(void)
120 {
121  return sizeof(struct device_nvs);
122 }
123 
124 /* Save bit index for first enabled event in PM1_STS for \_SB._SWS */
125 static void pm_fill_gnvs(struct global_nvs *gnvs, const struct chipset_power_state *ps)
126 {
127  uint16_t pm1;
128  int index;
129 
130  pm1 = ps->pm1_sts & ps->pm1_en;
131 
132  /* Scan for first set bit in PM1 */
133  for (index = 0; index < 16; index++) {
134  if (pm1 & 1)
135  break;
136  pm1 >>= 1;
137  }
138 
139  if (index < 16)
140  gnvs->pm1i = index;
141 }
142 
143 static void acpi_save_wake_source(void *unused)
144 {
145  const struct chipset_power_state *ps;
146  struct global_nvs *gnvs;
147 
148  if (acpi_reset_gnvs_for_wake(&gnvs) < 0)
149  return;
150  if (acpi_pm_state_for_wake(&ps) < 0)
151  return;
152 
153  pm_fill_gnvs(gnvs, ps);
154 
155  printk(BIOS_DEBUG, "ACPI System Wake Source is PM1 Index %d\n",
156  gnvs->pm1i);
157 }
158 
160 
162 {
163  u32 reg;
164  reg = iosf_dunit_read(0x8);
165  reg = reg & ~0x7000;
166  reg = reg | 0x2000;
167  iosf_dunit_write(0x8, reg);
168 }
169 
171 {
173 
174  fill_in_pattrs();
175 
176  if (!config->disable_ddr_2x_refresh_rate)
178 
179  /* Allow for SSE instructions to be executed. */
181 
182  /* Run reference code. */
184 
185  /* Get GPIO initial states from mainboard */
187  setup_soc_gpios(gpio_config, config->enable_xdp_tap);
188 
190 }
int acpi_reset_gnvs_for_wake(struct global_nvs **gnvs_)
Definition: gnvs.c:84
int acpi_pm_state_for_wake(const struct chipset_power_state **ps)
Definition: acpi_pm.c:61
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
uint32_t iosf_dunit_read(int reg)
Definition: iosf.c:49
void iosf_dunit_write(int reg, uint32_t val)
Definition: iosf.c:66
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
@ BS_PRE_DEVICE
Definition: bootstate.h:78
@ BS_ON_ENTRY
Definition: bootstate.h:95
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
#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
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, init_store, NULL)
#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
struct global_nvs * gnvs
#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_D0
Definition: lpc.h:32
@ 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
unsigned int bus_freq_khz(void)
Definition: tsc_freq.c:7
#define MSR_IACORE_VIDS
Definition: msr.h:19
void baytrail_init_scc(void)
Definition: scc.c:54
void baytrail_run_reference_code(void)
Definition: refcode.c:45
struct pattrs __global_pattrs
Definition: ramstage.c:28
#define SHOW_PATTRS
Definition: ramstage.c:26
static const char * stepping_str[]
Definition: ramstage.c:58
void baytrail_init_pre_device(struct soc_intel_baytrail_config *config)
Definition: ramstage.c:170
static void pm_fill_gnvs(struct global_nvs *gnvs, const struct chipset_power_state *ps)
Definition: ramstage.c:125
static void acpi_save_wake_source(void *unused)
Definition: ramstage.c:143
static void detect_num_cpus(struct pattrs *attrs)
Definition: ramstage.c:30
static void fill_in_pattrs(void)
Definition: ramstage.c:62
size_t size_of_dnvs(void)
Definition: ramstage.c:119
static void baytrail_enable_2x_refresh_rate(void)
Definition: ramstage.c:161
static void fill_in_msr(msr_t *msr, int idx)
Definition: ramstage.c:49
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
uint32_t u32
Definition: stdint.h:51
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
Definition: nvs.h:14
uint64_t pm1i
Definition: nvs.h:20
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111
Definition: pattrs.h:22