coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
early_init.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <bootblock_common.h>
4 #include <stdint.h>
5 #include <cf9_reset.h>
6 #include <device/pnp_ops.h>
9 #include <console/console.h>
12 #include <cpu/x86/msr.h>
13 #include <cpu/intel/speedstep.h>
14 #include <arch/cpu.h>
15 
16 #define SERIAL_DEV PNP_DEV(0x2e, W83627DHG_SP1)
17 #define GPIO_DEV PNP_DEV(0x2e, W83627DHG_GPIO2345_V)
18 
19 /*
20  * BSEL0 is connected with GPIO32
21  * BSEL1 is connected with GPIO33 with inversed logic
22  * BSEL2 is connected with GPIO55
23  */
24 static int setup_sio_gpio(u8 bsel)
25 {
26  int need_reset = 0;
27  u8 reg, old_reg;
28 
31 
32  reg = 0x9a;
33  old_reg = pnp_read_config(GPIO_DEV, 0x2c);
34  pnp_write_config(GPIO_DEV, 0x2c, reg);
35  need_reset = (reg != old_reg);
36 
37  pnp_write_config(GPIO_DEV, 0x30, 0x0e);
38  pnp_write_config(GPIO_DEV, 0xe0, 0xde);
39  pnp_write_config(GPIO_DEV, 0xf0, 0xf3);
40  pnp_write_config(GPIO_DEV, 0xf4, 0x80);
41  pnp_write_config(GPIO_DEV, 0xf5, 0x80);
42 
43  /* Invert GPIO33 */
44  pnp_write_config(GPIO_DEV, 0xf2, 0x08);
45 
46  reg = (bsel & 3) << 2;
47  old_reg = pnp_read_config(GPIO_DEV, 0xf1);
48  pnp_write_config(GPIO_DEV, 0xf1, reg);
49  need_reset += ((reg & 0xc) != (old_reg & 0xc));
50 
51  reg = (bsel >> 2) << 5;
52  old_reg = pnp_read_config(GPIO_DEV, 0xe1);
53  pnp_write_config(GPIO_DEV, 0xe1, reg);
54  need_reset += ((reg & 0x20) != (old_reg & 0x20));
55 
57 
58  return need_reset;
59 }
60 
61 static u8 msr_get_fsb(void)
62 {
63  u8 fsbcfg;
64  msr_t msr;
65  const u32 eax = cpuid_eax(1);
66 
67  /* Netburst */
68  if (((eax >> 8) & 0xf) == 0xf) {
70  fsbcfg = (msr.lo >> 16) & 0x7;
71  } else { /* Intel Core 2 */
72  msr = rdmsr(MSR_FSB_FREQ);
73  fsbcfg = msr.lo & 0x7;
74  }
75 
76  return fsbcfg;
77 }
78 
80 {
81  /* Enable only PCIe Root Port Clock Gate */
82  RCBA32(CG) = 0x00000001;
83 }
84 
85 void mainboard_pre_raminit_config(int s3_resume)
86 {
87  u8 c_bsel = msr_get_fsb();
88  /*
89  * Result is that FSB is incorrect on s3 resume (fixed at 800MHz).
90  * Some CPU accept this others don't.
91  */
92  if (!s3_resume && setup_sio_gpio(c_bsel)) {
94  "Needs reset to configure CPU BSEL straps\n");
95  full_reset();
96  }
97 }
98 
100 {
101  winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
102 }
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
void full_reset(void)
Definition: cf9_reset.c:45
#define printk(level,...)
Definition: stdlib.h:16
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
void bootblock_mainboard_early_init(void)
Definition: early_init.c:11
void mainboard_late_rcba_config(void)
Definition: early_init.c:6
static int setup_sio_gpio(u8 bsel)
Definition: early_init.c:24
#define GPIO_DEV
Definition: early_init.c:17
static u8 msr_get_fsb(void)
Definition: early_init.c:61
void mainboard_pre_raminit_config(int s3_resume)
Definition: early_init.c:85
#define SERIAL_DEV
Definition: early_init.c:16
static void pnp_enter_ext_func_mode(pnp_devfn_t dev)
Definition: early_init.c:52
static void pnp_exit_ext_func_mode(pnp_devfn_t dev)
Definition: early_init.c:58
void pnp_set_logical_device(struct device *dev)
Definition: pnp_device.c:59
u8 pnp_read_config(struct device *dev, u8 reg)
Definition: pnp_device.c:44
void pnp_write_config(struct device *dev, u8 reg, u8 value)
Definition: pnp_device.c:38
#define CG
Definition: rcba.h:129
#define RCBA32(x)
Definition: rcba.h:14
#define MSR_FSB_FREQ
Definition: speedstep.h:24
#define MSR_EBC_FREQUENCY_ID
Definition: speedstep.h:23
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
unsigned int lo
Definition: msr.h:111
void winbond_enable_serial(pnp_devfn_t dev, u16 iobase)
Definition: early_init.c:47