1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
/** @file
Prototype of the SideBandLib library.
Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _SB_LIB_H_
#define _SB_LIB_H_
/**
General SideBandLib Information
Note: IOSF-SideBand prior to v2.0 is not supported.
All future versions will be supported with backward support to v2.0. The latest
version supported is specified in VERSION_IOSF_SIDEBAND_SUPPORT.
Note: IOSF-SideBand access via MMIO is not valid prior to SBREG_BAR (P2SB BAR)
being set. By calling the generic SideBandRead() and SideBandWrite() library
functions, the appropriate method will be used based on SBREG_BAR availability.
In the case SBREG_BAR is not set, the SBMI (SideBand Message Interface) functions
will be used which read/write to SideBand using private PCI CFG registers in P2SB.
**/
#define VERSION_IOSF_SIDEBAND_SUPPORT 2.0 ///< Guaranteed IOSF-SideBand Supported Version
//
// Internal Library Defines
//
#define P2SB_SBI_ADDR 0xD0
#define P2SB_SBI_DATA 0xD4
#define P2SB_SBI_STAT 0xD8
#define P2SB_SBI_RID 0xDA
#define P2SB_SBI_EXTADDR 0xDC
#define B_ADDR_DEST_PORT_MASK (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 | \
BIT25 | BIT24)
#define B_ADDR_OFFSET_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | \
BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | \
BIT2 | BIT1 | BIT0)
#define B_ADDR_RSVD_MASK (BIT23 | BIT22 | BIT21 | BIT20)
#define B_ADDR_ROOT_MASK (BIT19 | BIT18 | BIT17 | BIT16)
#define B_STAT_INITIATE_MASK BIT0
#define B_STAT_INITRDY_MASK BIT0
#define B_STAT_OPCODE_MASK (BIT15 | BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | \
BIT9 | BIT8)
#define B_STAT_POSTED_MASK BIT7
#define B_STAT_RSVD_RESP (BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1)
#define V_INITIATE 0x01
#define V_INITRDY 0x01
#define V_OPCODE_CFGRD 0x04
#define V_OPCODE_CFGWR 0x05
#define V_OPCODE_CRRD 0x06
#define V_OPCODE_CRWR 0x07
#define V_OPCODE_IORD 0x02
#define V_OPCODE_IOWR 0x03
#define V_OPCODE_MRD 0x00
#define V_OPCODE_MWR 0x01
#define V_POSTED 0x01
#define V_RID_FBE 0xF000
#define V_RSVD_RESP 0x00
#define V_RID_BAR_DBC 0x05
//
// Main SideBand Interface Functions
//
/**
Determines whether to call a SideBand read via MMIO or SBMI (MMCFG) based on whether
SBREG_REG is set up.
This is the standard Read function that should be used for SideBand transactions.
For MMIO Access:
In a single MMIO transaction, the "SBREG_BAR" is used
to form a system address to access chipset registers.
Transactions using this method will read using Private Control Register opcode CRRd(06h).
All accesses using this method must be DWORD aligned DWORDs.
For SBMI Access: Refer to SideBandSbmiRead32()
@param[in] TargetPortId Target port to read.
@param[in] TargetRegister Target register to read.
@retval UINT32 The value read from Target Register.
**/
UINT32
EFIAPI
SideBandRead32 (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister
);
/**
Determines whether to call a SideBand write via MMIO or SBMI (MMCFG) based on whether
SBREG_REG is set up.
This is the standard Write function that should be used for SideBand transactions.
For MMIO Access:
In a single MMIO transaction, the "SBREG_BAR" is used
to form a system address to access chipset registers.
Transactions using this method will write using Private Control Register opcode CRWr(07h).
All accesses using this method must be DWORD aligned DWORDs.
For SBMI Access: Refer to SideBandSbmiWrite32()
@param[in] TargetPortId Target port to write.
@param[in] TargetRegister Target register to write.
@param[in] Value The value to write.
@retval None.
**/
VOID
EFIAPI
SideBandWrite32 (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister,
IN UINT32 Value
);
/**
Determines whether to call SideBand operations via MMIO or SBMI (MMCFG) based on whether
SBREG_REG is set up.
This is the standard AndThenOr function that should be used for SideBand transactions.
Reads the value in the Target Register of the Target Port Id, performs a bitwise AND followed
by a bitwise OR between the read result and the value specified by AndData, and writes the
32-bit value to the configuration register specified by Target Register.
@param[in] TargetPortId Target port to read/write.
@param[in] TargetRegister Target register to read/write.
@param[in] AndData The value to AND with Target Register data.
@param[in] OrData The value to OR with Target Register data.
@retval None.
**/
VOID
EFIAPI
SideBandAndThenOr32 (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister,
IN UINT32 AndData,
IN UINT32 OrData
);
//
// Special Case SideBand Interface Functions
//
/**
This function is reserved for special case sideband access:
Non-private control register opcode
In multiple MMIO transactions, this access method uses a mechanism provided in PCI
Configuration space to send IOSF-SB messages. This method should be used prior to
full PCI enumeration. Since multiple messages are sent this method is not thread-safe
but this is not an issue for single-threaded IAFW.
Transactions using this method will read using the OpCode parameter.
All accesses using this method must be DWORD aligned DWORDs.
@param[in] TargetPortId Target port to read.
@param[in] TargetRegister Target register to read.
@param[in] OpCode Opcode to use.
@param[in] Bar Target register access BAR.
@retval The value read from Target Register.
**/
UINT32
EFIAPI
SideBandReadReserved32 (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister,
IN UINT8 OpCode,
IN UINT8 Bar
);
/**
This function is reserved for special case sideband access:
Non-private control register opcode
In multiple MMIO transactions, this access method uses a mechanism provided in PCI
Configuration space to send IOSF-SB messages. This method should be used prior to
full PCI enumeration. Since multiple messages are sent this method is not thread-safe
but this is not an issue for single-threaded IAFW.
Transactions using this method will write using the OpCode parameter.
All accesses using this method must be DWORD aligned DWORDs.
@param[in] TargetPortId Target port to write.
@param[in] TargetRegister Target register to write.
@param[in] OpCode Opcode to use.
@param[in] Bar Target register access BAR.
@param[in] Value The value to write.
@retval None.
**/
VOID
EFIAPI
SideBandWriteReserved32 (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister,
IN UINT8 OpCode,
IN UINT8 Bar,
IN UINT32 Value
);
/**
This function is reserved for special case sideband access:
Non-private control register opcode
Reads the value in the Target Register of the Target Port Id, performs a bitwise AND followed
by a bitwise OR between the read result and the value specified by AndData, and writes the
32-bit value to the configuration register specified by Target Register.
@param[in] TargetPortId Target port to read/write.
@param[in] TargetRegister Target register to read/write.
@param[in] ReadOpCode Opcode to use for read.
@param[in] WriteOpCode Opcode to use for write.
@param[in] Bar Target register access BAR.
@param[in] AndData The value to AND with Target Register data.
@param[in] OrData The value to OR with Target Register data.
@retval None.
**/
VOID
EFIAPI
SideBandAndThenOrReserved32 (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister,
IN UINT8 ReadOpCode,
IN UINT8 WriteOpCode,
IN UINT8 Bar,
IN UINT32 AndData,
IN UINT32 OrData
);
//
// Helper Functions
//
/**
Returns if SideBand access using MMIO is valid.
@param None.
@retval BOOLEAN Returns true if SideBand access via P2SB MMIO is valid else returns false
**/
BOOLEAN
EFIAPI
SideBandMmioValid (
VOID
);
/**
Library utility function.
Returns the MMIO Address used to access the register over P2SB.
This function doesn't check if SB MMIO is enabled or not. Caller has to make sure
SB MMIO is enabled, this is exposed to meet timing constraints of SDQ protocol in less than 10us
@param[in] TargetPortId Target port.
@param[in] TargetRegister Target register
@retval UINT32 The MMIO address to access TargetRegister in TargetPortId with P2SB.
**/
UINT32
EFIAPI
GetSideBandMmioAddress (
IN UINT8 TargetPortId,
IN UINT16 TargetRegister
);
#endif // _SB_LIB_H_
|