coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
iobp.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <delay.h>
5 #include "pch.h"
6 #include "iobp.h"
7 
8 #define IOBP_RETRY 1000
9 
10 static inline int iobp_poll(void)
11 {
12  unsigned int try;
13 
14  for (try = IOBP_RETRY; try > 0; try--) {
15  u16 status = RCBA16(IOBPS);
16  if ((status & IOBPS_READY) == 0)
17  return 1;
18  udelay(10);
19  }
20 
21  printk(BIOS_ERR, "IOBP: timeout waiting for transaction to complete\n");
22  return 0;
23 }
24 
26 {
27  u16 status;
28 
29  if (!iobp_poll())
30  return 0;
31 
32  /* Set the address */
34 
35  /* READ OPCODE */
36  status = RCBA16(IOBPS);
37  status &= ~IOBPS_MASK;
38  status |= IOBPS_READ;
39  RCBA16(IOBPS) = status;
40 
41  /* Undocumented magic */
43 
44  /* Set ready bit */
45  status = RCBA16(IOBPS);
46  status |= IOBPS_READY;
47  RCBA16(IOBPS) = status;
48 
49  if (!iobp_poll())
50  return 0;
51 
52  /* Check for successful transaction */
53  status = RCBA16(IOBPS);
54  if (status & IOBPS_TX_MASK) {
55  printk(BIOS_ERR, "IOBP: read 0x%08x failed\n", address);
56  return 0;
57  }
58 
59  /* Read IOBP data */
60  return RCBA32(IOBPD);
61 }
62 
64 {
65  u16 status;
66 
67  if (!iobp_poll())
68  return;
69 
70  /* Set the address */
72 
73  /* WRITE OPCODE */
74  status = RCBA16(IOBPS);
75  status &= ~IOBPS_MASK;
76  status |= IOBPS_WRITE;
77  RCBA16(IOBPS) = status;
78 
79  RCBA32(IOBPD) = data;
80 
81  /* Undocumented magic */
83 
84  /* Set ready bit */
85  status = RCBA16(IOBPS);
86  status |= IOBPS_READY;
87  RCBA16(IOBPS) = status;
88 
89  if (!iobp_poll())
90  return;
91 
92  /* Check for successful transaction */
93  status = RCBA16(IOBPS);
94  if (status & IOBPS_TX_MASK) {
95  printk(BIOS_ERR, "IOBP: write 0x%08x failed\n", address);
96  return;
97  }
98 
99  printk(BIOS_SPEW, "IOBP: set 0x%08x to 0x%08x\n", address, data);
100 }
101 
102 void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
103 {
104  u32 data = pch_iobp_read(address);
105 
106  /* Update the data */
107  data &= andvalue;
108  data |= orvalue;
109 
110  pch_iobp_write(address, data);
111 }
112 
113 void pch_iobp_exec(u32 addr, u16 op_code, u8 route_id, u32 *data, u8 *resp)
114 {
115  if (!data || !resp)
116  return;
117 
118  *resp = -1;
119  if (!iobp_poll())
120  return;
121 
122  /* RCBA2330[31:0] = Address */
123  RCBA32(IOBPIRI) = addr;
124  /* RCBA2338[15:8] = opcode */
125  RCBA16(IOBPS) = (RCBA16(IOBPS) & 0x00ff) | op_code;
126  /* RCBA233A[15:8] = 0xf0 RCBA233A[7:0] = Route ID */
127  RCBA16(IOBPU) = IOBPU_MAGIC | route_id;
128 
129  if (op_code == IOBP_PCICFG_WRITE)
130  RCBA32(IOBPD) = *data;
131  /* Set RCBA2338[0] to trigger IOBP transaction*/
132  RCBA16(IOBPS) = RCBA16(IOBPS) | 0x1;
133 
134  if (!iobp_poll())
135  return;
136 
137  *resp = (RCBA16(IOBPS) & IOBPS_TX_MASK) >> 1;
138  *data = RCBA32(IOBPD);
139 }
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
uint64_t address
Definition: fw_cfg_if.h:0
static int iobp_poll(void)
Definition: iobp.c:10
void pch_iobp_exec(u32 addr, u16 op_code, u8 route_id, u32 *data, u8 *resp)
Definition: iobp.c:113
void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
Definition: iobp.c:102
void pch_iobp_write(u32 address, u32 data)
Definition: iobp.c:63
#define IOBP_RETRY
Definition: iobp.c:8
u32 pch_iobp_read(u32 address)
Definition: iobp.c:25
#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 IOBPU
Definition: rcba.h:51
#define IOBPS_TX_MASK
Definition: rcba.h:47
#define IOBPD
Definition: rcba.h:44
#define IOBPS_WRITE
Definition: rcba.h:50
#define IOBPS_READ
Definition: rcba.h:49
#define IOBPS_MASK
Definition: rcba.h:48
#define IOBPU_MAGIC
Definition: rcba.h:52
#define IOBP_PCICFG_WRITE
Definition: rcba.h:54
#define IOBPS_READY
Definition: rcba.h:46
#define IOBPIRI
Definition: rcba.h:43
#define IOBPS
Definition: rcba.h:45
#define RCBA16(x)
Definition: rcba.h:13
#define RCBA32(x)
Definition: rcba.h:14
uint32_t u32
Definition: stdint.h:51
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void udelay(uint32_t us)
Definition: udelay.c:15