coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
reg_access.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <arch/io.h>
6 #include <assert.h>
7 #include <cpu/x86/mtrr.h>
8 #include <cpu/x86/cr.h>
9 #include <console/console.h>
10 #include <delay.h>
11 #include <device/pci_ops.h>
12 #include <soc/pci_devs.h>
13 #include <soc/ramstage.h>
14 #include <soc/reg_access.h>
15 
16 static uint16_t get_gpe0_address(uint32_t reg_address)
17 {
18  uint32_t gpe0_base_address;
19 
20  /* Get the GPE0 base address */
21  gpe0_base_address = pci_read_config32(LPC_BDF, R_QNC_LPC_GPE0BLK);
22  ASSERT(gpe0_base_address >= 0x80000000);
23  gpe0_base_address &= B_QNC_LPC_GPE0BLK_MASK;
24 
25  /* Return the GPE0 register address */
26  return (uint16_t)(gpe0_base_address + reg_address);
27 }
28 
29 static uint32_t *get_gpio_address(uint32_t reg_address)
30 {
31  uint32_t gpio_base_address;
32 
33  /* Get the GPIO base address */
34  gpio_base_address = pci_read_config32(I2CGPIO_BDF, PCI_BASE_ADDRESS_1);
35  gpio_base_address &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
36  ASSERT(gpio_base_address != 0x00000000);
37 
38  /* Return the GPIO register address */
39  return (uint32_t *)(gpio_base_address + reg_address);
40 }
41 
42 void *get_i2c_address(void)
43 {
44  uint32_t gpio_base_address;
45 
46  /* Get the GPIO base address */
47  gpio_base_address = pci_read_config32(I2CGPIO_BDF, PCI_BASE_ADDRESS_0);
48  gpio_base_address &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
49  ASSERT(gpio_base_address != 0x00000000);
50 
51  /* Return the GPIO register address */
52  return (void *)gpio_base_address;
53 }
54 
56 {
57  uint32_t gpio_base_address;
58 
59  /* Get the GPIO base address */
60  gpio_base_address = pci_read_config32(LPC_BDF, R_QNC_LPC_GBA_BASE);
61  ASSERT(gpio_base_address >= 0x80000000);
62  gpio_base_address &= B_QNC_LPC_GPA_BASE_MASK;
63 
64  /* Return the GPIO register address */
65  return (uint16_t)(gpio_base_address + reg_address);
66 }
67 
69 {
71 
72  /* Convert from MTRR index to host bridge offset (Datasheet 12.7.2) */
73  if (index == MTRR_CAP_MSR)
75  else if (index == MTRR_DEF_TYPE_MSR)
77  else if (index == MTRR_FIX_64K_00000)
79  else if ((index >= MTRR_FIX_16K_80000) && (index <= MTRR_FIX_16K_A0000))
80  offset = ((index - MTRR_FIX_16K_80000) << 1)
82  else if ((index >= MTRR_FIX_4K_C0000) && (index <= MTRR_FIX_4K_F8000))
83  offset = ((index - MTRR_FIX_4K_C0000) << 1)
85  else if ((index >= MTRR_PHYS_BASE(0)) && (index <= MTRR_PHYS_MASK(7)))
86  offset = (index - MTRR_PHYS_BASE(0))
88  else {
89  printk(BIOS_SPEW, "index: 0x%08lx\n", index);
90  die("Invalid MTRR index specified!\n");
91  }
92  return offset;
93 }
94 
95 void mcr_write(uint8_t opcode, uint8_t port, uint32_t reg_address)
96 {
98  (opcode << QNC_MCR_OP_OFFSET)
100  | ((reg_address & QNC_MCR_MASK) << QNC_MCR_REG_OFFSET)
102 }
103 
105 {
107 }
108 
110 {
112 }
113 
114 void mea_write(uint32_t reg_address)
115 {
117  & QNC_MEA_MASK);
118 }
119 
121 {
122  /* Read the port register */
123  mea_write(offset);
125  return mdr_read();
126 }
127 
129 {
130  /* Write the port register */
131  mea_write(offset);
132  mdr_write(value);
134 }
135 
136 static CRx_TYPE reg_cpu_cr_read(uint32_t reg_address)
137 {
138  /* Read the CPU CRx register */
139  switch (reg_address) {
140  case 0:
141  return read_cr0();
142 
143  case 4:
144  return read_cr4();
145  }
146  die("ERROR - Unsupported CPU register!\n");
147 }
148 
149 static void reg_cpu_cr_write(uint32_t reg_address, CRx_TYPE value)
150 {
151  /* Write the CPU CRx register */
152  switch (reg_address) {
153  default:
154  die("ERROR - Unsupported CPU register!\n");
155 
156  case 0:
157  write_cr0(value);
158  break;
159 
160  case 4:
161  write_cr4(value);
162  break;
163  }
164 }
165 
166 static uint32_t reg_gpe0_read(uint32_t reg_address)
167 {
168  /* Read the GPE0 register */
169  return inl(get_gpe0_address(reg_address));
170 }
171 
172 static void reg_gpe0_write(uint32_t reg_address, uint32_t value)
173 {
174  /* Write the GPE0 register */
175  outl(get_gpe0_address(reg_address), value);
176 }
177 
178 static uint32_t reg_gpio_read(uint32_t reg_address)
179 {
180  /* Read the GPIO register */
181  return *get_gpio_address(reg_address);
182 }
183 
184 static void reg_gpio_write(uint32_t reg_address, uint32_t value)
185 {
186  /* Write the GPIO register */
187  *get_gpio_address(reg_address) = value;
188 }
189 
191 {
192  /* Read the host bridge register */
193  mea_write(reg_address);
195  reg_address);
196  return mdr_read();
197 }
198 
200 {
201  /* Write the host bridge register */
202  mea_write(reg_address);
203  mdr_write(value);
205  reg_address);
206 }
207 
209 {
210  /* Read the legacy GPIO register */
211  return inl(get_legacy_gpio_address(reg_address));
212 }
213 
215 {
216  /* Write the legacy GPIO register */
217  outl(value, get_legacy_gpio_address(reg_address));
218 }
219 
221 {
222  /* Read the PCIE AFE register */
223  mea_write(reg_address);
225  reg_address);
226  return mdr_read();
227 }
228 
229 static void reg_pcie_afe_write(uint32_t reg_address, uint32_t value)
230 {
231  /* Write the PCIE AFE register */
232  mea_write(reg_address);
233  mdr_write(value);
235  reg_address);
236 }
237 
239 {
240  /* Read the RMU temperature register */
241  mea_write(reg_address);
243  return mdr_read();
244 }
245 
246 static void reg_rmu_temp_write(uint32_t reg_address, uint32_t value)
247 {
248  /* Write the RMU temperature register */
249  mea_write(reg_address);
250  mdr_write(value);
252 }
253 
255 {
256  /* Read the temperature sensor register */
257  mea_write(reg_address);
259  reg_address);
260  return mdr_read();
261 }
262 
263 static void reg_soc_unit_write(uint32_t reg_address, uint32_t value)
264 {
265  /* Write the temperature sensor register */
266  mea_write(reg_address);
267  mdr_write(value);
269  reg_address);
270 }
271 
272 static uint32_t reg_usb_read(uint32_t reg_address)
273 {
274  /* Read the USB register */
275  mea_write(reg_address);
277  reg_address);
278  return mdr_read();
279 }
280 
281 static void reg_usb_write(uint32_t reg_address, uint32_t value)
282 {
283  /* Write the USB register */
284  mea_write(reg_address);
285  mdr_write(value);
287  reg_address);
288 }
289 
291 {
292  const struct reg_script *step = ctx->step;
293  uint64_t value = 0;
294 
295  switch (step->id) {
296  default:
298  "ERROR - Unknown register set (0x%08x)!\n",
299  step->id);
301  return 0;
302 
303  case CPU_CR:
304  ctx->display_prefix = "CPU CR";
305  value = reg_cpu_cr_read(step->reg);
306  break;
307 
308  case GPE0_REGS:
309  ctx->display_prefix = "GPE0";
310  value = reg_gpe0_read(step->reg);
311  break;
312 
313  case GPIO_REGS:
314  ctx->display_prefix = "GPIO";
315  value = reg_gpio_read(step->reg);
316  break;
317 
318  case HOST_BRIDGE:
319  ctx->display_prefix = "Host Bridge";
321  break;
322 
323  case LEG_GPIO_REGS:
324  ctx->display_prefix = "Legacy GPIO";
325  value = reg_legacy_gpio_read(step->reg);
326  break;
327 
328  case PCIE_AFE_REGS:
329  ctx->display_prefix = "PCIe AFE";
330  value = reg_pcie_afe_read(step->reg);
331  break;
332 
333  case RMU_TEMP_REGS:
334  ctx->display_prefix = "RMU TEMP";
335  value = reg_rmu_temp_read(step->reg);
336  break;
337 
338  case SOC_UNIT_REGS:
339  ctx->display_prefix = "SOC Unit";
340  value = reg_soc_unit_read(step->reg);
341  break;
342 
343  case USB_PHY_REGS:
344  ctx->display_prefix = "USB PHY";
345  value = reg_usb_read(step->reg);
346  break;
347  }
348  return value;
349 }
350 
351 static void reg_write(struct reg_script_context *ctx)
352 {
353  const struct reg_script *step = ctx->step;
354 
355  switch (step->id) {
356  default:
358  "ERROR - Unknown register set (0x%08x)!\n",
359  step->id);
361  return;
362 
363  case CPU_CR:
364  ctx->display_prefix = "CPU CR";
365  reg_cpu_cr_write(step->reg, step->value);
366  break;
367 
368  case GPE0_REGS:
369  ctx->display_prefix = "GPE0";
370  reg_gpe0_write(step->reg, (uint32_t)step->value);
371  break;
372 
373  case GPIO_REGS:
374  ctx->display_prefix = "GPIO";
375  reg_gpio_write(step->reg, (uint32_t)step->value);
376  break;
377 
378  case HOST_BRIDGE:
379  ctx->display_prefix = "Host Bridge";
381  break;
382 
383  case LEG_GPIO_REGS:
384  ctx->display_prefix = "Legacy GPIO";
385  reg_legacy_gpio_write(step->reg, (uint32_t)step->value);
386  break;
387 
388  case PCIE_AFE_REGS:
389  ctx->display_prefix = "PCIe AFE";
390  reg_pcie_afe_write(step->reg, (uint32_t)step->value);
391  break;
392 
393  case PCIE_RESET:
394  if (ctx->display_features) {
395  ctx->display_prefix = "PCIe reset";
397  }
399  break;
400 
401  case RMU_TEMP_REGS:
402  ctx->display_prefix = "RMU TEMP";
403  reg_rmu_temp_write(step->reg, (uint32_t)step->value);
404  break;
405 
406  case SOC_UNIT_REGS:
407  ctx->display_prefix = "SOC Unit";
408  reg_soc_unit_write(step->reg, (uint32_t)step->value);
409  break;
410 
411  case MICROSECOND_DELAY:
412  /* The actual delay is >= the requested delay */
413  if (ctx->display_features) {
414  /* Higher baud-rates will reduce the impact of
415  * displaying this message
416  */
417  printk(BIOS_INFO, "Delay %lld uSec\n", step->value);
419  }
420  udelay(step->value);
421  break;
422 
423  case USB_PHY_REGS:
424  ctx->display_prefix = "USB PHY";
425  reg_usb_write(step->reg, (uint32_t)step->value);
426  break;
427  }
428 }
429 
430 msr_t soc_msr_read(unsigned int index)
431 {
433  union {
434  uint64_t u64;
435  msr_t msr;
436  } value;
437 
438  /* Read the low 32-bits of the register */
441 
442  /* For 64-bit registers, read the upper 32-bits */
445  offset += 1;
447  offset);
448  }
449  return value.msr;
450 }
451 
452 void soc_msr_write(unsigned int index, msr_t msr)
453 {
455  union {
456  uint32_t u32[2];
457  msr_t msr;
458  } value;
459 
460  /* Write the low 32-bits of the register */
461  value.msr = msr;
464 
465  /* For 64-bit registers, write the upper 32-bits */
468  offset += 1;
470  value.u32[1]);
471  }
472 }
473 
476 };
477 
#define QNC_MCR_BYTE_ENABLES
Definition: QuarkNcSocId.h:80
#define QNC_ACCESS_PORT_MCR
Definition: QuarkNcSocId.h:77
#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE
Definition: QuarkNcSocId.h:289
#define QNC_MCR_MASK
Definition: QuarkNcSocId.h:79
#define QUARK_OPCODE_WRITE
Definition: QuarkNcSocId.h:107
#define QNC_ACCESS_PORT_MEA
Definition: QuarkNcSocId.h:90
#define QUARK_OPCODE_IO_READ
Definition: QuarkNcSocId.h:118
#define B_QNC_LPC_GPE0BLK_MASK
Definition: QuarkNcSocId.h:521
#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP
Definition: QuarkNcSocId.h:288
#define QUARK_SC_USB_AFE_SB_PORT_ID
Definition: QuarkNcSocId.h:136
#define QUARK_OPCODE_READ
Definition: QuarkNcSocId.h:106
#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0
Definition: QuarkNcSocId.h:303
#define QUARK_NC_HOST_BRIDGE_SB_PORT_ID
Definition: QuarkNcSocId.h:133
#define QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000
Definition: QuarkNcSocId.h:290
#define QNC_MCR_OP_OFFSET
Definition: QuarkNcSocId.h:93
#define QUARK_OPCODE_IO_WRITE
Definition: QuarkNcSocId.h:119
#define QNC_MEA_MASK
Definition: QuarkNcSocId.h:91
#define QNC_MCR_PORT_OFFSET
Definition: QuarkNcSocId.h:94
#define QUARK_NC_RMU_SB_PORT_ID
Definition: QuarkNcSocId.h:134
#define QNC_MCR_REG_OFFSET
Definition: QuarkNcSocId.h:95
#define QUARK_ALT_OPCODE_READ
Definition: QuarkNcSocId.h:112
#define QNC_ACCESS_PORT_MDR
Definition: QuarkNcSocId.h:85
#define R_QNC_LPC_GPE0BLK
Definition: QuarkNcSocId.h:520
#define QUARK_SC_PCIE_AFE_SB_PORT_ID
Definition: QuarkNcSocId.h:137
#define QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000
Definition: QuarkNcSocId.h:291
#define B_QNC_LPC_GPA_BASE_MASK
Definition: QuarkNcSocId.h:462
#define R_QNC_LPC_GBA_BASE
Definition: QuarkNcSocId.h:461
#define QUARK_ALT_OPCODE_WRITE
Definition: QuarkNcSocId.h:113
#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000
Definition: QuarkNcSocId.h:300
#define QUARK_SCSS_SOC_UNIT_SB_PORT_ID
Definition: QuarkNcSocId.h:138
pte_t value
Definition: mmu.c:91
#define ASSERT(x)
Definition: assert.h:44
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
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 CRx_TYPE
Definition: cr.h:17
static __always_inline void write_cr0(CRx_TYPE data)
Definition: cr.h:33
static __always_inline CRx_TYPE read_cr0(void)
Definition: cr.h:21
u32 inl(u16 port)
void outl(u32 val, u16 port)
static size_t offset
Definition: flashconsole.c:16
port
Definition: i915.h:29
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
void mainboard_gpio_pcie_reset(uint32_t pin_value)
Definition: gpio.c:53
REG_SCRIPT_BUS_ENTRY(mainboard_reg_script_bus_table)
#define PCI_BASE_ADDRESS_MEM_ATTR_MASK
Definition: pci_def.h:77
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_BASE_ADDRESS_1
Definition: pci_def.h:64
#define REG_SCRIPT_DISPLAY_REGISTER
Definition: reg_script.h:137
#define REG_SCRIPT_DISPLAY_NOTHING
Definition: reg_script.h:139
#define MC_BDF
Definition: pci_devs.h:10
#define LPC_BDF
Definition: pci_devs.h:53
#define I2CGPIO_BDF
Definition: pci_devs.h:38
@ PCIE_RESET
Definition: reg_access.h:21
@ GPE0_REGS
Definition: reg_access.h:22
@ LEG_GPIO_REGS
Definition: reg_access.h:18
@ USB_PHY_REGS
Definition: reg_access.h:14
@ GPIO_REGS
Definition: reg_access.h:19
@ CPU_CR
Definition: reg_access.h:24
@ MICROSECOND_DELAY
Definition: reg_access.h:17
@ RMU_TEMP_REGS
Definition: reg_access.h:16
@ HOST_BRIDGE
Definition: reg_access.h:23
@ SOC_UNIT_REGS
Definition: reg_access.h:15
@ PCIE_AFE_REGS
Definition: reg_access.h:20
@ SOC_TYPE
Definition: reg_access.h:28
static void reg_gpe0_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:172
static uint64_t reg_read(struct reg_script_context *ctx)
Definition: reg_access.c:290
static void reg_pcie_afe_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:229
static uint32_t reg_gpio_read(uint32_t reg_address)
Definition: reg_access.c:178
uint32_t reg_host_bridge_unit_read(uint32_t reg_address)
Definition: reg_access.c:190
void mea_write(uint32_t reg_address)
Definition: reg_access.c:114
static uint32_t reg_pcie_afe_read(uint32_t reg_address)
Definition: reg_access.c:220
static void reg_gpio_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:184
void mcr_write(uint8_t opcode, uint8_t port, uint32_t reg_address)
Definition: reg_access.c:95
static uint32_t reg_gpe0_read(uint32_t reg_address)
Definition: reg_access.c:166
static uint16_t get_legacy_gpio_address(uint32_t reg_address)
Definition: reg_access.c:55
uint32_t reg_legacy_gpio_read(uint32_t reg_address)
Definition: reg_access.c:208
msr_t soc_msr_read(unsigned int index)
Definition: reg_access.c:430
uint32_t port_reg_read(uint8_t port, uint32_t offset)
Definition: reg_access.c:120
static void reg_cpu_cr_write(uint32_t reg_address, CRx_TYPE value)
Definition: reg_access.c:149
static void reg_soc_unit_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:263
static uint32_t * get_gpio_address(uint32_t reg_address)
Definition: reg_access.c:29
void reg_legacy_gpio_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:214
void mdr_write(uint32_t value)
Definition: reg_access.c:109
uint32_t mdr_read(void)
Definition: reg_access.c:104
void soc_msr_write(unsigned int index, msr_t msr)
Definition: reg_access.c:452
static uint32_t reg_usb_read(uint32_t reg_address)
Definition: reg_access.c:272
const struct reg_script_bus_entry soc_reg_script_bus_table
Definition: reg_access.c:474
static uint16_t get_gpe0_address(uint32_t reg_address)
Definition: reg_access.c:16
static void reg_write(struct reg_script_context *ctx)
Definition: reg_access.c:351
static void reg_rmu_temp_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:246
void * get_i2c_address(void)
Definition: reg_access.c:42
static CRx_TYPE reg_cpu_cr_read(uint32_t reg_address)
Definition: reg_access.c:136
static uint32_t mtrr_index_to_host_bridge_register_offset(unsigned long index)
Definition: reg_access.c:68
uint32_t reg_rmu_temp_read(uint32_t reg_address)
Definition: reg_access.c:238
static void reg_host_bridge_unit_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:199
static void reg_usb_write(uint32_t reg_address, uint32_t value)
Definition: reg_access.c:281
void port_reg_write(uint8_t port, uint32_t offset, uint32_t value)
Definition: reg_access.c:128
static uint32_t reg_soc_unit_read(uint32_t reg_address)
Definition: reg_access.c:254
unsigned short uint16_t
Definition: stdint.h:11
uint64_t u64
Definition: stdint.h:54
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
Definition: reg_script.h:97
const struct reg_script * step
Definition: reg_script.h:91
const char * display_prefix
Definition: reg_script.h:94
uint8_t display_features
Definition: reg_script.h:93
uint64_t value
Definition: reg_script.h:70
uint32_t reg
Definition: reg_script.h:68
uint32_t id
Definition: reg_script.h:73
void udelay(uint32_t us)
Definition: udelay.c:15
#define MTRR_FIX_64K_00000
Definition: mtrr.h:45
#define MTRR_PHYS_BASE(reg)
Definition: mtrr.h:39
#define MTRR_PHYS_MASK(reg)
Definition: mtrr.h:40
#define MTRR_FIX_16K_A0000
Definition: mtrr.h:47
#define MTRR_FIX_4K_C0000
Definition: mtrr.h:48
#define MTRR_CAP_MSR
Definition: mtrr.h:17
#define MTRR_FIX_16K_80000
Definition: mtrr.h:46
#define MTRR_FIX_4K_F8000
Definition: mtrr.h:55
#define MTRR_DEF_TYPE_MSR
Definition: mtrr.h:25