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-or-later */
2 
3 #include <bootblock_common.h>
4 #include <device/pnp_ops.h>
5 #include <console/console.h>
7 #include <cpu/x86/msr.h>
8 #include <cpu/intel/speedstep.h>
9 #include <cf9_reset.h>
12 
13 #define SERIAL_DEV PNP_DEV(0x2e, W83627DHG_SP1)
14 #define GPIO_DEV PNP_DEV(0x2e, W83627DHG_GPIO2345_V)
15 
17 {
18  winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
19 }
20 
21 static u8 msr_get_fsb(void)
22 {
23  u8 fsbcfg;
24  msr_t msr;
25  const u32 eax = cpuid_eax(1);
26 
27  /* Netburst */
28  if (((eax >> 8) & 0xf) == 0xf) {
30  fsbcfg = (msr.lo >> 16) & 0x7;
31  } else { /* Intel Core 2 */
32  msr = rdmsr(MSR_FSB_FREQ);
33  fsbcfg = msr.lo & 0x7;
34  }
35 
36  return fsbcfg;
37 }
38 
39 /* BSEL MCH straps are not hooked up to the CPU as usual but to the SIO */
40 static int setup_sio_gpio(void)
41 {
42  int need_reset = 0;
43  u8 reg, old_reg;
44 
45  u8 bsel = msr_get_fsb();
46  switch (bsel) {
47  case 0:
48  case 2:
49  case 4:
50  break;
51  default:
53  "BSEL: Unsupported FSB frequency, using 800MHz\n");
54  bsel = 2; /* 800MHz */
55  break;
56  }
57 
60 
61  /*
62  * P5QL-EM:
63  * BSEL0 -> not hooked up (not supported anyways)
64  * BSEL1 -> GPIO33 (inverted)
65  * BSEL2 -> GPIO40
66  */
67  reg = 0x92;
68  /* Multi-function Pin Selection */
69  old_reg = pnp_read_config(GPIO_DEV, 0x2c);
70  pnp_write_config(GPIO_DEV, 0x2c, reg);
71  need_reset = (reg != old_reg);
72 
73  pnp_write_config(GPIO_DEV, 0x30, 0x0e); /* Enable GPIO3x,4x,5x */
74  pnp_write_config(GPIO_DEV, 0xf0, 0xf3); /* GPIO3x direction */
75  pnp_write_config(GPIO_DEV, 0xf2, 0x08); /* GPIO3x inversion */
76  pnp_write_config(GPIO_DEV, 0xf4, 0x06); /* GPIO4x direction */
77 
78  const int gpio33 = (bsel & 2) >> 1;
79  const int gpio40 = (bsel & 4) >> 2;
80  reg = (gpio33 << 3);
81  old_reg = pnp_read_config(GPIO_DEV, 0xf1); /* GPIO3x data */
82  /* Set GPIO32 high like vendor firmware */
83  pnp_write_config(GPIO_DEV, 0xf1, old_reg | reg | 4);
84  need_reset += ((reg & 0x8) != (old_reg & 0x8));
85 
86  reg = gpio40;
87  old_reg = pnp_read_config(GPIO_DEV, 0xf5); /* GPIO4x data */
88  pnp_write_config(GPIO_DEV, 0xf5, old_reg | reg);
89  need_reset += ((reg & 0x1) != (old_reg & 0x1));
91 
92  return need_reset;
93 }
94 
95 void mb_pre_raminit_setup(int s3_resume)
96 {
97  if (!s3_resume && setup_sio_gpio()) {
98  printk(BIOS_DEBUG, "Needs reset to configure CPU BSEL straps\n");
99  full_reset();
100  }
101 }
102 
103 void mb_get_spd_map(u8 spd_map[4])
104 {
105  /* This board has first dimm slot of each channel hooked up to
106  rank0 and rank1, while the second dimm slot is only connected
107  to rank1. The raminit does not support such setups. So only the
108  first dimms of each channel are used. */
109  spd_map[0] = 0x50;
110  spd_map[2] = 0x52;
111 }
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
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
void bootblock_mainboard_early_init(void)
Definition: early_init.c:11
void mb_get_spd_map(u8 spd_map[4])
Definition: early_init.c:27
#define GPIO_DEV
Definition: early_init.c:14
static u8 msr_get_fsb(void)
Definition: early_init.c:21
void mb_pre_raminit_setup(int s3_resume)
Definition: early_init.c:95
#define SERIAL_DEV
Definition: early_init.c:13
static int setup_sio_gpio(void)
Definition: early_init.c:40
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 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