soc/intel/bdw: Remove spurious comment
[coreboot.git] / src / soc / intel / broadwell / bootblock / cpu.c
blob2f1ac51981fefadc704f7c8b3e86261bd194f25e
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <stdint.h>
17 #include <cpu/x86/cache.h>
18 #include <cpu/x86/msr.h>
19 #include <cpu/x86/mtrr.h>
20 #include <arch/io.h>
21 #include <halt.h>
22 #include <cpu/intel/microcode/microcode.c>
23 #include <soc/rcba.h>
24 #include <soc/msr.h>
26 static void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size,
27 unsigned int type)
29 /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
30 msr_t basem, maskm;
31 basem.lo = base | type;
32 basem.hi = 0;
33 wrmsr(MTRR_PHYS_BASE(reg), basem);
34 maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID;
35 maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
36 wrmsr(MTRR_PHYS_MASK(reg), maskm);
39 static void enable_rom_caching(void)
41 msr_t msr;
43 disable_cache();
44 set_var_mtrr(1, CACHE_ROM_BASE, CACHE_ROM_SIZE, MTRR_TYPE_WRPROT);
45 enable_cache();
47 /* Enable Variable MTRRs */
48 msr.hi = 0x00000000;
49 msr.lo = 0x00000800;
50 wrmsr(MTRR_DEF_TYPE_MSR, msr);
53 static void bootblock_mdelay(int ms)
55 u32 target = ms * 24 * 1000;
56 msr_t current;
57 msr_t start = rdmsr(MSR_COUNTER_24_MHZ);
59 do {
60 current = rdmsr(MSR_COUNTER_24_MHZ);
61 } while ((current.lo - start.lo) < target);
64 static void set_flex_ratio_to_tdp_nominal(void)
66 msr_t flex_ratio, msr;
67 u32 soft_reset;
68 u8 nominal_ratio;
70 /* Check for Flex Ratio support */
71 flex_ratio = rdmsr(MSR_FLEX_RATIO);
72 if (!(flex_ratio.lo & FLEX_RATIO_EN))
73 return;
75 /* Check for >0 configurable TDPs */
76 msr = rdmsr(MSR_PLATFORM_INFO);
77 if (((msr.hi >> 1) & 3) == 0)
78 return;
80 /* Use nominal TDP ratio for flex ratio */
81 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
82 nominal_ratio = msr.lo & 0xff;
84 /* See if flex ratio is already set to nominal TDP ratio */
85 if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
86 return;
88 /* Set flex ratio to nominal TDP ratio */
89 flex_ratio.lo &= ~0xff00;
90 flex_ratio.lo |= nominal_ratio << 8;
91 flex_ratio.lo |= FLEX_RATIO_LOCK;
92 wrmsr(MSR_FLEX_RATIO, flex_ratio);
94 /* Set flex ratio in soft reset data register bits 11:6.
95 * RCBA region is enabled in southbridge bootblock */
96 soft_reset = RCBA32(SOFT_RESET_DATA);
97 soft_reset &= ~(0x3f << 6);
98 soft_reset |= (nominal_ratio & 0x3f) << 6;
99 RCBA32(SOFT_RESET_DATA) = soft_reset;
101 /* Set soft reset control to use register value */
102 RCBA32_OR(SOFT_RESET_CTRL, 1);
104 /* Delay before reset to avoid potential TPM lockout */
105 bootblock_mdelay(30);
107 /* Issue warm reset, will be "CPU only" due to soft reset data */
108 outb(0x0, 0xcf9);
109 outb(0x6, 0xcf9);
110 halt();
113 static void check_for_clean_reset(void)
115 msr_t msr;
116 msr = rdmsr(MTRR_DEF_TYPE_MSR);
118 /* Use the MTRR default type MSR as a proxy for detecting INIT#.
119 * Reset the system if any known bits are set in that MSR. That is
120 * an indication of the CPU not being properly reset. */
121 if (msr.lo & (MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN)) {
122 outb(0x0, 0xcf9);
123 outb(0x6, 0xcf9);
124 halt();
128 static void bootblock_cpu_init(void)
130 /* Set flex ratio and reset if needed */
131 set_flex_ratio_to_tdp_nominal();
132 check_for_clean_reset();
133 enable_rom_caching();
134 intel_update_microcode_from_cbfs();