coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
lpc_lib.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #define __SIMPLE_DEVICE__
4 
5 #include <arch/ioapic.h>
6 #include <assert.h>
7 #include <console/console.h>
8 #include <device/pci.h>
9 #include <device/pci_ops.h>
10 #include <intelblocks/gpmr.h>
11 #include <intelblocks/itss.h>
12 #include <intelblocks/lpc_lib.h>
13 #include <intelblocks/pcr.h>
14 #include <lib.h>
15 #include "lpc_def.h"
16 #include <soc/irq.h>
17 #include <soc/pci_devs.h>
18 #include <soc/pcr_ids.h>
20 
22 {
23  uint16_t reg_io_enables;
24 
25  reg_io_enables = pci_read_config16(PCH_DEV_LPC, LPC_IO_ENABLES);
26  io_enables |= reg_io_enables;
28  if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR))
29  gpmr_write32(GPMR_LPCIOE, io_enables);
30 
31  return io_enables;
32 }
33 
35 {
37 }
38 
40 {
41  uint16_t reg_io_ranges;
42 
43  reg_io_ranges = lpc_get_fixed_io_decode() & ~mask;
44  io_ranges |= reg_io_ranges & mask;
46  if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR))
47  gpmr_write32(GPMR_LPCIOD, io_ranges);
48 
49  return io_ranges;
50 }
51 
52 /*
53  * Find the first unused IO window.
54  * Returns -1 if not found, 0 for reg 0x84, 1 for reg 0x88 ...
55  */
56 static int find_unused_pmio_window(void)
57 {
58  int i;
59  uint32_t lgir;
60 
61  for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
63 
64  if (!(lgir & LPC_LGIR_EN))
65  return i;
66  }
67 
68  return -1;
69 }
70 
72 {
73  int i, lgir_reg_num;
74  uint32_t lgir_reg_offset, lgir, window_size, alignment;
75  resource_t bridged_size, bridge_base;
76 
77  printk(BIOS_SPEW, "LPC: Trying to open IO window from %x size %x\n",
78  base, size);
79 
80  bridged_size = 0;
81  bridge_base = base;
82 
83  while (bridged_size < size) {
84  /* Each IO range register can only open a 256-byte window. */
85  window_size = MIN(size, LPC_LGIR_MAX_WINDOW_SIZE);
86 
87  if (window_size <= 0)
88  return;
89 
90  /* Window size must be a power of two for the AMASK to work. */
91  alignment = 1UL << (log2_ceil(window_size));
92  window_size = ALIGN_UP(window_size, alignment);
93 
94  /* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18]. */
95  lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN;
96  lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK;
97 
98  /* Skip programming if same range already programmed. */
99  for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
100  if (lgir == pci_read_config32(PCH_DEV_LPC,
102  return;
103  }
104 
105  lgir_reg_num = find_unused_pmio_window();
106  if (lgir_reg_num < 0) {
108  "LPC: Cannot open IO window: %llx size %llx\n",
109  bridge_base, size - bridged_size);
110  printk(BIOS_ERR, "No more IO windows\n");
111  return;
112  }
113  lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num);
114 
115  pci_write_config32(PCH_DEV_LPC, lgir_reg_offset, lgir);
116  if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR))
117  gpmr_write32(GPMR_LPCLGIR1 + lgir_reg_num * 4, lgir);
118 
120  "LPC: Opened IO window LGIR%d: base %llx size %x\n",
121  lgir_reg_num, bridge_base, window_size);
122 
123  bridged_size += window_size;
124  bridge_base += window_size;
125  }
126 }
127 
129 {
130  uint32_t lgmr;
131 
133 
134  if (lgmr & LPC_LGMR_EN) {
136  "LPC: Cannot open window to resource %lx size %zx\n",
137  base, size);
138  printk(BIOS_ERR, "LPC: MMIO window already in use\n");
139  return;
140  }
141 
142  if (size > LPC_LGMR_WINDOW_SIZE) {
144  "LPC: Resource %lx size %zx larger than window(%x)\n",
145  base, size, LPC_LGMR_WINDOW_SIZE);
146  }
147 
148  lgmr = (base & LPC_LGMR_ADDR_MASK) | LPC_LGMR_EN;
149 
151  if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR))
152  gpmr_write32(GPMR_LPCGMR, lgmr);
153 }
154 
155 /*
156  * Set LPC BIOS Control register based on input bit field.
157  */
158 static void lpc_set_bios_control_reg(uint8_t bios_cntl_bit)
159 {
160  pci_devfn_t dev = PCH_DEV_LPC;
161  uint8_t bc_cntl;
162 
163  assert(IS_POWER_OF_2(bios_cntl_bit));
164  bc_cntl = pci_read_config8(dev, LPC_BIOS_CNTL);
165  bc_cntl |= bios_cntl_bit;
166  pci_write_config8(dev, LPC_BIOS_CNTL, bc_cntl);
167 
168  /*
169  * Ensure an additional read back after performing lock down
170  */
172 }
173 
174 /*
175 * Set LPC BIOS Control BILD bit.
176 */
178 {
180 }
181 
182 /*
183 * Set LPC BIOS Control LE bit.
184 */
186 {
188 }
189 
190 /*
191 * Set LPC BIOS Control EISS bit.
192 */
193 void lpc_set_eiss(void)
194 {
196 }
197 
198 static void lpc_configure_write_protect(bool status)
199 {
200  const pci_devfn_t dev = PCH_DEV_LPC;
201  uint8_t bios_cntl;
202 
203  bios_cntl = pci_read_config8(dev, LPC_BIOS_CNTL);
204  if (status)
205  bios_cntl &= ~LPC_BC_WPD;
206  else
207  bios_cntl |= LPC_BC_WPD;
208  pci_write_config8(dev, LPC_BIOS_CNTL, bios_cntl);
209 }
210 
211 /* Enable LPC Write Protect. */
212 void lpc_enable_wp(void)
213 {
215 }
216 
217 /* Disable LPC Write Protect. */
218 void lpc_disable_wp(void)
219 {
221 }
222 
223 /*
224 * Set LPC Serial IRQ mode.
225 */
227 {
228  pci_devfn_t dev = PCH_DEV_LPC;
229  uint8_t scnt;
230 
231  scnt = pci_read_config8(dev, LPC_SERIRQ_CTL);
232  scnt &= ~(LPC_SCNT_EN | LPC_SCNT_MODE);
233 
234  switch (mode) {
235  case SERIRQ_QUIET:
236  scnt |= LPC_SCNT_EN;
237  break;
238  case SERIRQ_CONTINUOUS:
239  scnt |= LPC_SCNT_EN | LPC_SCNT_MODE;
240  break;
241  case SERIRQ_OFF:
242  default:
243  break;
244  }
245 
246  pci_write_config8(dev, LPC_SERIRQ_CTL, scnt);
247 }
248 
250 {
251  /* ComA Range 3F8h-3FFh [2:0] */
252  uint16_t com_ranges = LPC_IOD_COMA_RANGE;
253  uint16_t com_enable = LPC_IOE_COMA_EN;
255 
256  /* ComB Range 2F8h-2FFh [6:4] */
257  if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE)) {
258  com_ranges |= LPC_IOD_COMB_RANGE;
259  com_enable |= LPC_IOE_COMB_EN;
260  com_mask |= LPC_IOD_COMB_RANGE_MASK;
261  }
262 
263  /* Setup I/O Decode Range Register for LPC */
264  lpc_set_fixed_io_ranges(com_ranges, com_mask);
265  /* Enable ComA and ComB Port */
266  lpc_enable_fixed_io_ranges(com_enable);
267 }
268 
271 {
272  size_t i;
273 
274  /* Set in PCI generic decode range registers */
275  for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
277  if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR))
278  gpmr_write32(GPMR_LPCLGIR1 + i * 4, gen_io_dec[i]);
279  }
280 }
281 
282 void pch_enable_lpc(void)
283 {
285 
286  soc_get_gen_io_dec_range(gen_io_dec);
287  lpc_set_gen_decode_range(gen_io_dec);
288  if (ENV_PAYLOAD_LOADER)
289  pch_pirq_init();
290 }
291 
293 {
295 }
296 
298 {
301 }
302 
303 /* PCH I/O APIC redirection entries */
304 #define PCH_REDIR_ETR 120
305 
306 /* Enable PCH IOAPIC */
308 {
309  /* affirm full set of redirection table entries ("write once") */
311 
312  setup_ioapic((void *)IO_APIC_ADDR, 0x02);
313 }
314 
316  [0] = PCH_IRQ11, /* PIRQ_A */
317  [1] = PCH_IRQ10, /* PIRQ_B */
318  [2] = PCH_IRQ11, /* PIRQ_C */
319  [3] = PCH_IRQ11, /* PIRQ_D */
320  [4] = PCH_IRQ11, /* PIRQ_E */
321  [5] = PCH_IRQ11, /* PIRQ_F */
322  [6] = PCH_IRQ11, /* PIRQ_G */
323  [7] = PCH_IRQ11, /* PIRQ_H */
324 };
325 
327 {
329  return pch_interrupt_routing;
330 }
331 
332 /*
333  * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
334  * 0x00 - 0000 = Reserved
335  * 0x01 - 0001 = Reserved
336  * 0x02 - 0010 = Reserved
337  * 0x03 - 0011 = IRQ3
338  * 0x04 - 0100 = IRQ4
339  * 0x05 - 0101 = IRQ5
340  * 0x06 - 0110 = IRQ6
341  * 0x07 - 0111 = IRQ7
342  * 0x08 - 1000 = Reserved
343  * 0x09 - 1001 = IRQ9
344  * 0x0A - 1010 = IRQ10
345  * 0x0B - 1011 = IRQ11
346  * 0x0C - 1100 = IRQ12
347  * 0x0D - 1101 = Reserved
348  * 0x0E - 1110 = IRQ14
349  * 0x0F - 1111 = IRQ15
350  * PIRQ[n]_ROUT[7] - PIRQ Routing Control
351  * 0x80 - The PIRQ is not routed.
352  */
353 void pch_pirq_init(void)
354 {
355  const struct device *irq_dev;
357 
358  for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
359  uint8_t int_pin = 0, int_line = 0;
360 
361  if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
362  continue;
363 
364  int_pin = pci_read_config8(PCI_BDF(irq_dev), PCI_INTERRUPT_PIN);
365 
366  switch (int_pin) {
367  case 1: /* INTA# */
368  int_line = PCH_IRQ11;
369  break;
370  case 2: /* INTB# */
371  int_line = PCH_IRQ10;
372  break;
373  case 3: /* INTC# */
374  int_line = PCH_IRQ11;
375  break;
376  case 4: /* INTD# */
377  int_line = PCH_IRQ11;
378  break;
379  }
380 
381  if (!int_line)
382  continue;
383 
384  pci_write_config8(PCI_BDF(irq_dev), PCI_INTERRUPT_LINE, int_line);
385  }
386 }
387 
388 #define PPI_PORT_B 0x61
389 #define SERR_DIS (1 << 2)
390 #define CMOS_NMI 0x70
391 #define NMI_DIS (1 << 7)
392 
393 /* LPC MISC programming */
394 void pch_misc_init(void)
395 {
396  uint8_t reg8;
397 
398  /* Setup NMI on errors, disable SERR */
399  reg8 = (inb(PPI_PORT_B)) & 0xf0;
400  outb((reg8 | SERR_DIS), PPI_PORT_B);
401 
402  /* Disable NMI sources */
404 }
@ PIRQ_COUNT
Definition: acpi_pirq_gen.h:30
void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES])
Definition: espi.c:23
#define PCH_IRQ10
Definition: irq.h:9
#define PCH_IRQ11
Definition: irq.h:10
#define VIO_APIC_VADDR
Definition: ioapic.h:7
#define IO_APIC_ADDR
Definition: ioapic.h:6
void setup_ioapic(void *ioapic_base, u8 ioapic_id)
Definition: ioapic.c:160
void ioapic_set_max_vectors(void *ioapic_base, int mre_count)
Definition: ioapic.c:51
#define assert(statement)
Definition: assert.h:74
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define MIN(a, b)
Definition: helpers.h:37
#define IS_POWER_OF_2(x)
Definition: helpers.h:50
#define ALIGN_UP(x, a)
Definition: helpers.h:17
void itss_irq_init(const uint8_t pch_interrupt_routing[PIRQ_COUNT])
Definition: itss.c:12
#define printk(level,...)
Definition: stdlib.h:16
u8 inb(u16 port)
void outb(u8 val, u16 port)
DEVTREE_CONST struct device *DEVTREE_CONST all_devices
Linked list of ALL devices.
Definition: device_const.c:13
@ CONFIG
Definition: dsi_common.h:201
void gpmr_write32(uint16_t offset, uint32_t val)
Definition: gpmr.c:15
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
static int log2_ceil(u32 x)
Definition: lib.h:60
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#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
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
#define LPC_PCCTL
Definition: lpc_def.h:31
#define LPC_BC_WPD
Definition: lpc_def.h:29
#define LPC_LGIR_EN
Definition: lpc_def.h:20
#define LPC_LGIR_ADDR_MASK
Definition: lpc_def.h:19
#define LPC_LGIR_MAX_WINDOW_SIZE
Definition: lpc_def.h:21
#define LPC_IOD_COMA_RANGE_MASK
Definition: lpc_def.h:10
#define LPC_SCNT_MODE
Definition: lpc_def.h:8
#define LPC_IOD_COMA_RANGE
Definition: lpc_def.h:12
#define LPC_PCCTL_CLKRUN_EN
Definition: lpc_def.h:32
#define LPC_LGIR_AMASK_MASK
Definition: lpc_def.h:18
#define LPC_SCNT_EN
Definition: lpc_def.h:7
#define LPC_LGMR_ADDR_MASK
Definition: lpc_def.h:23
#define LPC_BC_EISS
Definition: lpc_def.h:30
#define LPC_IOD_COMB_RANGE_MASK
Definition: lpc_def.h:11
#define LPC_IO_ENABLES
Definition: lpc_def.h:16
#define LPC_BC_LE
Definition: lpc_def.h:28
#define LPC_LGMR_WINDOW_SIZE
Definition: lpc_def.h:25
#define LPC_SERIRQ_CTL
Definition: lpc_def.h:6
#define LPC_LGMR_EN
Definition: lpc_def.h:24
#define LPC_GENERIC_IO_RANGE(n)
Definition: lpc_def.h:17
#define LPC_BC_BILD
Definition: lpc_def.h:27
#define LPC_IOD_COMB_RANGE
Definition: lpc_def.h:13
#define LPC_GENERIC_MEM_RANGE
Definition: lpc_def.h:22
#define LPC_BIOS_CNTL
Definition: lpc_def.h:26
#define LPC_IO_DECODE
Definition: lpc_def.h:9
static void lpc_set_bios_control_reg(uint8_t bios_cntl_bit)
Definition: lpc_lib.c:158
static void lpc_set_gen_decode_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES])
Definition: lpc_lib.c:269
static void lpc_configure_write_protect(bool status)
Definition: lpc_lib.c:198
uint16_t lpc_get_fixed_io_decode(void)
Definition: lpc_lib.c:34
void pch_misc_init(void)
Definition: lpc_lib.c:394
void lpc_set_lock_enable(void)
Definition: lpc_lib.c:185
void lpc_enable_pci_clk_cntl(void)
Definition: lpc_lib.c:292
uint16_t lpc_set_fixed_io_ranges(uint16_t io_ranges, uint16_t mask)
Definition: lpc_lib.c:39
void lpc_enable_wp(void)
Definition: lpc_lib.c:212
#define PCH_REDIR_ETR
Definition: lpc_lib.c:304
void lpc_disable_clkrun(void)
Definition: lpc_lib.c:297
void lpc_set_eiss(void)
Definition: lpc_lib.c:193
#define NMI_DIS
Definition: lpc_lib.c:391
void pch_enable_ioapic(void)
Definition: lpc_lib.c:307
void lpc_set_serirq_mode(enum serirq_mode mode)
Definition: lpc_lib.c:226
void pch_pirq_init(void)
Definition: lpc_lib.c:353
void lpc_disable_wp(void)
Definition: lpc_lib.c:218
const uint8_t * lpc_get_pic_pirq_routing(size_t *num)
Definition: lpc_lib.c:326
#define PPI_PORT_B
Definition: lpc_lib.c:388
#define SERR_DIS
Definition: lpc_lib.c:389
void lpc_set_bios_interface_lock_down(void)
Definition: lpc_lib.c:177
void lpc_open_mmio_window(uintptr_t base, size_t size)
Definition: lpc_lib.c:128
static int find_unused_pmio_window(void)
Definition: lpc_lib.c:56
uint16_t lpc_enable_fixed_io_ranges(uint16_t io_enables)
Definition: lpc_lib.c:21
void lpc_io_setup_comm_a_b(void)
Definition: lpc_lib.c:249
void lpc_open_pmio_window(uint16_t base, uint16_t size)
Definition: lpc_lib.c:71
void pch_enable_lpc(void)
Definition: lpc_lib.c:282
static const uint8_t pch_interrupt_routing[PIRQ_COUNT]
Definition: lpc_lib.c:315
#define CMOS_NMI
Definition: lpc_lib.c:390
#define LPC_IOE_COMB_EN
Definition: lpc_lib.h:24
#define LPC_IOE_COMA_EN
Definition: lpc_lib.h:25
serirq_mode
Definition: lpc_lib.h:34
@ SERIRQ_CONTINUOUS
Definition: lpc_lib.h:36
@ SERIRQ_QUIET
Definition: lpc_lib.h:35
@ SERIRQ_OFF
Definition: lpc_lib.h:37
#define LPC_NUM_GENERIC_IO_RANGES
Definition: lpc_lib.h:26
@ DEVICE_PATH_PCI
Definition: path.h:9
#define PCI_INTERRUPT_PIN
Definition: pci_def.h:95
#define PCI_INTERRUPT_LINE
Definition: pci_def.h:94
#define PCI_BDF(dev)
Definition: pci_type.h:28
u32 pci_devfn_t
Definition: pci_type.h:8
#define GPMR_LPCGMR
Definition: pcr_gpmr.h:9
#define GPMR_LPCLGIR1
Definition: pcr_gpmr.h:6
#define GPMR_LPCIOE
Definition: pcr_gpmr.h:13
#define GPMR_LPCIOD
Definition: pcr_gpmr.h:12
u64 resource_t
Definition: resource.h:43
#define ENV_PAYLOAD_LOADER
Definition: rules.h:260
uintptr_t base
Definition: uart.c:17
#define PCH_DEV_LPC
Definition: pci_devs.h:224
static const int mask[4]
Definition: gpio.c:308
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned char uint8_t
Definition: stdint.h:8
enum device_path_type type
Definition: path.h:114
Definition: device.h:107
struct device_path path
Definition: device.h:115
DEVTREE_CONST struct device * next
Definition: device.h:113
unsigned int enabled
Definition: device.h:122