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 <cf9_reset.h>
5 #include <device/pnp_ops.h>
6 #include <console/console.h>
7 #include <cpu/intel/speedstep.h>
8 #include <cpu/x86/msr.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 
41 static int setup_sio_gpio(void)
42 {
43  int need_reset = 0;
44  u8 reg, old_reg;
45 
46  u8 bsel = msr_get_fsb();
47  switch (bsel) {
48  case 0:
49  case 2:
50  case 4:
51  break;
52  default:
54  "BSEL: Unsupported FSB frequency, using 800MHz\n");
55  bsel = 2; /* 800MHz */
56  break;
57  }
58 
61 
62  if (CONFIG(BOARD_ASUS_P5QPL_AM)) {
63  /*
64  * P5QPL-AM:
65  * BSEL0 -> not hooked up (not supported anyways)
66  * BSEL1 -> GPIO33
67  * BSEL2 -> GPIO40
68  */
69  reg = 0x92;
70  old_reg = pnp_read_config(GPIO_DEV, 0x2c);
71  pnp_write_config(GPIO_DEV, 0x2c, reg);
72  need_reset = (reg != old_reg);
73 
74  pnp_write_config(GPIO_DEV, 0x30, 0x06);
75  pnp_write_config(GPIO_DEV, 0xf0, 0xf3); /* GPIO3 direction */
76  pnp_write_config(GPIO_DEV, 0xf4, 0x00); /* GPIO4 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);
82  pnp_write_config(GPIO_DEV, 0xf1, old_reg | reg);
83  need_reset += ((reg & 0x8) != (old_reg & 0x8));
84 
85  reg = gpio40;
86  old_reg = pnp_read_config(GPIO_DEV, 0xf5);
87  pnp_write_config(GPIO_DEV, 0xf5, old_reg | reg);
88  need_reset += ((reg & 0x1) != (old_reg & 0x1));
89  } else {
90  /*
91  * P5G41T-M LX:
92  * BSEL0 -> not hooked up
93  * BSEL1 -> GPIO43 (inverted)
94  * BSEL2 -> GPIO44
95  */
96  reg = 0xf2;
97  old_reg = pnp_read_config(GPIO_DEV, 0x2c);
98  pnp_write_config(GPIO_DEV, 0x2c, reg);
99  need_reset = (reg != old_reg);
100  pnp_write_config(GPIO_DEV, 0x30, 0x05);
101  pnp_write_config(GPIO_DEV, 0xf6, 0x08); /* invert GPIO43 */
102  pnp_write_config(GPIO_DEV, 0xf4, 0xa4); /* GPIO4 direction */
103 
104  const int gpio43 = (bsel & 2) >> 1;
105  const int gpio44 = (bsel & 4) >> 2;
106  reg = (gpio43 << 3) | (gpio44 << 4);
107  old_reg = pnp_read_config(GPIO_DEV, 0xf5);
108  pnp_write_config(GPIO_DEV, 0xf5, old_reg | reg);
109  need_reset += ((reg & 0x18) != (old_reg & 0x18));
110  }
112 
113  return need_reset;
114 }
115 
116 void mb_pre_raminit_setup(int s3_resume)
117 {
118  if (!s3_resume && setup_sio_gpio()) {
119  printk(BIOS_DEBUG, "Needs reset to configure CPU BSEL straps\n");
120  full_reset();
121  }
122 }
123 
124 void mb_get_spd_map(u8 spd_map[4])
125 {
126  spd_map[0] = 0x50;
127  spd_map[2] = 0x52;
128 }
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
@ CONFIG
Definition: dsi_common.h:201
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
void mb_pre_raminit_setup(int s3_resume)
Definition: early_init.c:95
#define GPIO_DEV
Definition: early_init.c:14
static u8 msr_get_fsb(void)
Definition: early_init.c:21
#define SERIAL_DEV
Definition: early_init.c:13
static int setup_sio_gpio(void)
Definition: early_init.c:41
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