]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.c
fa94cc74e8630c35557232101a20b61380950050
[mirror_edk2.git] / Vlv2TbltDevicePkg / Library / EfiRegTableLib / EfiRegTableLib.c
1 /*++
2
3 Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
4
5 This program and the accompanying materials are licensed and made available under
6 the terms and conditions of the BSD License that accompanies this distribution.
7 The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13
14
15 Module Name:
16
17 EfiRegTableLib.c
18
19 Abstract:
20
21 Lib function for table driven register initialization.
22
23 Revision History
24
25 --*/
26
27 #include <Library/EfiRegTableLib.h>
28 #include <Library/S3BootScriptLib.h>
29
30 //
31 // Local Functions
32 //
33
34 /**
35 Local worker function to process PCI_WRITE table entries. Performs write and
36 may also call BootScriptSave protocol if indicated in the Entry flags
37
38 @param Entry A pointer to the PCI_WRITE entry to process
39
40 @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
41 when processing the entry.
42
43 @retval Nothing.
44
45 **/
46 STATIC
47 VOID
48 PciWrite (
49 EFI_REG_TABLE_PCI_WRITE *Entry,
50 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
51 )
52 {
53 EFI_STATUS Status;
54
55 Status = PciRootBridgeIo->Pci.Write (
56 PciRootBridgeIo,
57 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
58 (UINT64) Entry->PciAddress,
59 1,
60 &Entry->Data
61 );
62 ASSERT_EFI_ERROR (Status);
63
64 if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
65 Status = S3BootScriptSavePciCfgWrite (
66 (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
67 (UINT64) Entry->PciAddress,
68 1,
69 &Entry->Data
70 );
71 ASSERT_EFI_ERROR (Status);
72 }
73 }
74
75 /**
76 Local worker function to process PCI_READ_MODIFY_WRITE table entries.
77 Performs RMW write and may also call BootScriptSave protocol if indicated in
78 the Entry flags.
79
80 @param Entry A pointer to the PCI_READ_MODIFY_WRITE entry to process.
81
82 @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
83 when processing the entry.
84
85 @retval Nothing.
86
87 **/
88 STATIC
89 VOID
90 PciReadModifyWrite (
91 EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
92 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
93 )
94 {
95 EFI_STATUS Status;
96 UINT32 TempData;
97
98 Status = PciRootBridgeIo->Pci.Read (
99 PciRootBridgeIo,
100 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
101 (UINT64) Entry->PciAddress,
102 1,
103 &TempData
104 );
105 ASSERT_EFI_ERROR (Status);
106
107 Entry->OrMask &= Entry->AndMask;
108 TempData &= ~Entry->AndMask;
109 TempData |= Entry->OrMask;
110
111 Status = PciRootBridgeIo->Pci.Write (
112 PciRootBridgeIo,
113 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
114 (UINT64) Entry->PciAddress,
115 1,
116 &TempData
117 );
118 ASSERT_EFI_ERROR (Status);
119
120 if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
121 Status = S3BootScriptSavePciCfgReadWrite (
122 (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
123 (UINT64) Entry->PciAddress,
124 &Entry->OrMask,
125 &Entry->AndMask
126 );
127 ASSERT_EFI_ERROR (Status);
128 }
129 }
130
131 /**
132 Local worker function to process MEM_READ_MODIFY_WRITE table entries.
133 Performs RMW write and may also call BootScriptSave protocol if indicated in
134 the Entry flags.
135
136 @param Entry A pointer to the MEM_READ_MODIFY_WRITE entry to process.
137
138 @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
139 when processing the entry.
140
141 @retval Nothing.
142
143 **/
144 STATIC
145 VOID
146 MemReadModifyWrite (
147 EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
148 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
149 )
150 {
151 EFI_STATUS Status;
152 UINT32 TempData;
153
154 Status = PciRootBridgeIo->Mem.Read (
155 PciRootBridgeIo,
156 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
157 (UINT64) Entry->MemAddress,
158 1,
159 &TempData
160 );
161 ASSERT_EFI_ERROR (Status);
162
163 Entry->OrMask &= Entry->AndMask;
164 TempData &= ~Entry->AndMask;
165 TempData |= Entry->OrMask;
166
167 Status = PciRootBridgeIo->Mem.Write (
168 PciRootBridgeIo,
169 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
170 (UINT64) Entry->MemAddress,
171 1,
172 &TempData
173 );
174 ASSERT_EFI_ERROR (Status);
175
176 if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
177 Status = S3BootScriptSaveMemReadWrite (
178 (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
179 Entry->MemAddress,
180 &Entry->OrMask,
181 &Entry->AndMask
182 );
183 ASSERT_EFI_ERROR (Status);
184 }
185 }
186
187 //
188 // Exported functions
189 //
190
191 /**
192 Processes register table assuming which may contain PCI, IO, MEM, and STALL
193 entries.
194
195 No parameter checking is done so the caller must be careful about omitting
196 values for PciRootBridgeIo or CpuIo parameters. If the regtable does
197 not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
198 NULL). If the regtable does not contain any IO or Mem entries, it is safe to
199 omit the CpuIo (supply NULL).
200
201 The RegTableEntry parameter is not checked, but is required.
202
203 gBS is assumed to have been defined and is used when processing stalls.
204
205 The function processes each entry sequentially until an OP_TERMINATE_TABLE
206 entry is encountered.
207
208 @param RegTableEntry A pointer to the register table to process
209
210 @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
211 when processing PCI table entries
212
213 @param CpuIo A pointer to the instance of CpuIo that is used when processing IO and
214 MEM table entries
215
216 @retval Nothing.
217
218 **/
219 VOID
220 ProcessRegTablePci (
221 EFI_REG_TABLE *RegTableEntry,
222 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
223 EFI_CPU_IO_PROTOCOL *CpuIo
224 )
225 {
226 while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
227 switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
228 case OP_PCI_WRITE:
229 PciWrite ((EFI_REG_TABLE_PCI_WRITE *) RegTableEntry, PciRootBridgeIo);
230 break;
231
232 case OP_PCI_READ_MODIFY_WRITE:
233 PciReadModifyWrite ((EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
234 break;
235
236 case OP_MEM_READ_MODIFY_WRITE:
237 MemReadModifyWrite ((EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
238 break;
239
240 default:
241 DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
242 ASSERT (0);
243 break;
244 }
245
246 RegTableEntry++;
247 }
248 }
249
250 /**
251 Processes register table assuming which may contain IO, MEM, and STALL
252 entries, but must NOT contain any PCI entries. Any PCI entries cause an
253 ASSERT in a DEBUG build and are skipped in a free build.
254
255 No parameter checking is done. Both RegTableEntry and CpuIo parameters are
256 required.
257
258 gBS is assumed to have been defined and is used when processing stalls.
259
260 The function processes each entry sequentially until an OP_TERMINATE_TABLE
261 entry is encountered.
262
263 @param RegTableEntry A pointer to the register table to process
264
265 @param CpuIo A pointer to the instance of CpuIo that is used when processing IO and
266 MEM table entries
267
268 @retval Nothing.
269
270 **/
271 VOID
272 ProcessRegTableCpu (
273 EFI_REG_TABLE *RegTableEntry,
274 EFI_CPU_IO_PROTOCOL *CpuIo
275 )
276 {
277 while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
278 switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
279 default:
280 DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
281 ASSERT (0);
282 break;
283 }
284
285 RegTableEntry++;
286 }
287 }