]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/CpuRuntimeDxe/CpuIo.c
BaseTools/BinToPcd: Fix Python 2.7.x compatibility issue
[mirror_edk2.git] / EmulatorPkg / CpuRuntimeDxe / CpuIo.c
CommitLineData
949f388f 1/*++ @file\r
2 This is the code that publishes the CPU I/O Protocol.\r
3 The intent herein is to have a single I/O service that can load\r
d18d8a1d 4 as early as possible, extend into runtime, and be layered upon by\r
949f388f 5 the implementations of architectural protocols and the PCI Root\r
6 Bridge I/O Protocol.\r
7\r
8\r
e148512e 9Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
949f388f 10Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
d18d8a1d 11This program and the accompanying materials\r
12are licensed and made available under the terms and conditions of the BSD License\r
13which accompanies this distribution. The full text of the license may be found at\r
14http://opensource.org/licenses/bsd-license.php\r
15\r
16THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
17WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
949f388f 18\r
19**/\r
20\r
a0af6b27 21#include <PiDxe.h>\r
949f388f 22#include <Protocol/Cpu.h>\r
949f388f 23#include <Protocol/CpuIo2.h>\r
949f388f 24\r
25#include <Library/BaseLib.h>\r
26#include <Library/DebugLib.h>\r
27#include <Library/HiiLib.h>\r
28#include <Library/UefiLib.h>\r
29#include <Library/UefiDriverEntryPoint.h>\r
30#include <Library/BaseMemoryLib.h>\r
31#include <Library/MemoryAllocationLib.h>\r
32#include <Library/UefiBootServicesTableLib.h>\r
33#include <CpuDriver.h>\r
34\r
35#define IA32_MAX_IO_ADDRESS 0xFFFF\r
36#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF\r
37\r
38EFI_STATUS\r
39CpuIoCheckAddressRange (\r
40 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
41 IN UINT64 Address,\r
42 IN UINTN Count,\r
43 IN VOID *Buffer,\r
44 IN UINT64 Limit\r
45 );\r
46\r
47EFI_STATUS\r
48EFIAPI\r
49CpuMemoryServiceRead (\r
50 IN EFI_CPU_IO2_PROTOCOL *This,\r
51 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
52 IN UINT64 Address,\r
53 IN UINTN Count,\r
54 IN OUT VOID *Buffer\r
55 )\r
56/*++\r
57\r
58Routine Description:\r
59\r
60 Perform the Memory Access Read service for the CPU I/O Protocol\r
61\r
62Arguments:\r
63\r
64 Pointer to an instance of the CPU I/O Protocol\r
65 Width of the Memory Access\r
66 Address of the Memory access\r
67 Count of the number of accesses to perform\r
68 Pointer to the buffer to read or write from memory\r
69\r
70Returns:\r
71\r
72 Status\r
73\r
d18d8a1d 74 EFI_SUCCESS - The data was read from or written to the EFI\r
949f388f 75 System.\r
76 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
77 EFI_INVALID_PARAMETER - Buffer is NULL.\r
78 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 79 EFI_UNSUPPORTED - The address range specified by Address, Width,\r
949f388f 80 and Count is not valid for this EFI System.\r
81\r
82**/\r
83{\r
84 EFI_STATUS Status;\r
85\r
86 if (!Buffer) {\r
87 return EFI_INVALID_PARAMETER;\r
88 }\r
89\r
90 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
91 if (EFI_ERROR (Status)) {\r
92 return Status;\r
93 }\r
94\r
95 //\r
96 // Do nothing for Nt32 version\r
97 //\r
98 return EFI_SUCCESS;\r
99}\r
100\r
101EFI_STATUS\r
102EFIAPI\r
103CpuMemoryServiceWrite (\r
104 IN EFI_CPU_IO2_PROTOCOL *This,\r
105 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
106 IN UINT64 Address,\r
107 IN UINTN Count,\r
108 IN OUT VOID *Buffer\r
109 )\r
110/*++\r
111\r
112Routine Description:\r
113\r
114 Perform the Memory Access Read service for the CPU I/O Protocol\r
115\r
116Arguments:\r
117\r
118 Pointer to an instance of the CPU I/O Protocol\r
119 Width of the Memory Access\r
120 Address of the Memory access\r
121 Count of the number of accesses to perform\r
122 Pointer to the buffer to read or write from memory\r
123\r
124Returns:\r
125\r
126 Status\r
127\r
128 EFI_SUCCESS - The data was read from or written to the EFI System.\r
129 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
130 EFI_INVALID_PARAMETER - Buffer is NULL.\r
131 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 132 EFI_UNSUPPORTED - The address range specified by Address, Width, and\r
949f388f 133 Count is not valid for this EFI System.\r
134\r
135**/\r
136{\r
137 EFI_STATUS Status;\r
138\r
139 if (!Buffer) {\r
140 return EFI_INVALID_PARAMETER;\r
141 }\r
142\r
143 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
144 if (EFI_ERROR (Status)) {\r
145 return Status;\r
146 }\r
147\r
148 //\r
149 // Do nothing for Nt32 version\r
150 //\r
151 return EFI_SUCCESS;\r
152}\r
153\r
154EFI_STATUS\r
155EFIAPI\r
156CpuIoServiceRead (\r
157 IN EFI_CPU_IO2_PROTOCOL *This,\r
158 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
159 IN UINT64 UserAddress,\r
160 IN UINTN Count,\r
161 IN OUT VOID *UserBuffer\r
162 )\r
163/*++\r
164\r
165Routine Description:\r
d18d8a1d 166\r
949f388f 167 This is the service that implements the I/O read\r
168\r
169Arguments:\r
170\r
171 Pointer to an instance of the CPU I/O Protocol\r
172 Width of the Memory Access\r
173 Address of the I/O access\r
174 Count of the number of accesses to perform\r
175 Pointer to the buffer to read or write from I/O space\r
176\r
177Returns:\r
178\r
179 Status\r
180 EFI_SUCCESS - The data was read from or written to the EFI System.\r
181 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
182 EFI_INVALID_PARAMETER - Buffer is NULL.\r
183 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 184 EFI_UNSUPPORTED - The address range specified by Address, Width, and\r
949f388f 185 Count is not valid for this EFI System.\r
186**/\r
187{\r
188 UINTN Address;\r
189 EFI_STATUS Status;\r
190\r
191 if (!UserBuffer) {\r
192 return EFI_INVALID_PARAMETER;\r
193 }\r
194\r
195 Address = (UINTN) UserAddress;\r
196\r
197 if (Width >= EfiCpuIoWidthMaximum) {\r
198 return EFI_INVALID_PARAMETER;\r
199 }\r
200\r
201 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
202 if (EFI_ERROR (Status)) {\r
203 return Status;\r
204 }\r
205\r
206 //\r
207 // Do nothing for Nt32 version\r
208 //\r
209 return EFI_SUCCESS;\r
210}\r
211\r
212EFI_STATUS\r
213EFIAPI\r
214CpuIoServiceWrite (\r
215 IN EFI_CPU_IO2_PROTOCOL *This,\r
216 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
217 IN UINT64 UserAddress,\r
218 IN UINTN Count,\r
219 IN OUT VOID *UserBuffer\r
220 )\r
221/*++\r
222\r
223Routine Description:\r
224\r
d18d8a1d 225\r
949f388f 226 This is the service that implements the I/O Write\r
227\r
228Arguments:\r
229\r
230 Pointer to an instance of the CPU I/O Protocol\r
231 Width of the Memory Access\r
232 Address of the I/O access\r
233 Count of the number of accesses to perform\r
234 Pointer to the buffer to read or write from I/O space\r
235\r
236Returns:\r
237\r
238 Status\r
239\r
240 Status\r
241 EFI_SUCCESS - The data was read from or written to the EFI System.\r
242 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
243 EFI_INVALID_PARAMETER - Buffer is NULL.\r
244 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 245 EFI_UNSUPPORTED - The address range specified by Address, Width, and\r
949f388f 246 Count is not valid for this EFI System.\r
247\r
248**/\r
249{\r
250 UINTN Address;\r
251 EFI_STATUS Status;\r
252\r
253 if (!UserBuffer) {\r
254 return EFI_INVALID_PARAMETER;\r
255 }\r
256\r
257 Address = (UINTN) UserAddress;\r
258\r
259 if (Width >= EfiCpuIoWidthMaximum) {\r
260 return EFI_INVALID_PARAMETER;\r
261 }\r
262\r
263 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
264 if (EFI_ERROR (Status)) {\r
265 return Status;\r
266 }\r
267\r
268 //\r
269 // Do nothing for Nt32 version\r
270 //\r
271 return EFI_SUCCESS;\r
272}\r
273\r
274\r
275/*++\r
276\r
277Routine Description:\r
278\r
279Arguments:\r
280\r
281 Width - TODO: add argument description\r
282 Address - TODO: add argument description\r
283 Count - TODO: add argument description\r
284 Buffer - TODO: add argument description\r
285 Limit - TODO: add argument description\r
286\r
287Returns:\r
288\r
289 EFI_UNSUPPORTED - TODO: Add description for return value\r
290 EFI_UNSUPPORTED - TODO: Add description for return value\r
291 EFI_UNSUPPORTED - TODO: Add description for return value\r
292 EFI_SUCCESS - TODO: Add description for return value\r
293\r
294**/\r
295EFI_STATUS\r
296CpuIoCheckAddressRange (\r
297 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
298 IN UINT64 Address,\r
299 IN UINTN Count,\r
300 IN VOID *Buffer,\r
301 IN UINT64 Limit\r
302 )\r
303{\r
304 UINTN AlignMask;\r
305\r
306 if (Address > Limit) {\r
307 return EFI_UNSUPPORTED;\r
308 }\r
309\r
310 //\r
311 // For FiFo type, the target address won't increase during the access, so treat count as 1\r
312 //\r
313 if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {\r
314 Count = 1;\r
315 }\r
316\r
317 Width = Width & 0x03;\r
e148512e 318 if ((Address - 1 + LShiftU64 (Count, Width)) > Limit) {\r
949f388f 319 return EFI_UNSUPPORTED;\r
320 }\r
321\r
322 AlignMask = (1 << Width) - 1;\r
323 if ((UINTN) Buffer & AlignMask) {\r
324 return EFI_UNSUPPORTED;\r
325 }\r
326\r
327 return EFI_SUCCESS;\r
328}\r
329\r
330\r