]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/CpuRuntimeDxe/CpuIo.c
EmulatorPkg: Remove all trailing whitespace
[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
9Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
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
21#include <FrameworkDxe.h>\r
22#include <Protocol/Cpu.h>\r
23#include <Protocol/DataHub.h>\r
24#include <Guid/DataHubRecords.h>\r
25#include <Protocol/CpuIo2.h>\r
26#include <Protocol/FrameworkHii.h>\r
27\r
28#include <Library/BaseLib.h>\r
29#include <Library/DebugLib.h>\r
30#include <Library/HiiLib.h>\r
31#include <Library/UefiLib.h>\r
32#include <Library/UefiDriverEntryPoint.h>\r
33#include <Library/BaseMemoryLib.h>\r
34#include <Library/MemoryAllocationLib.h>\r
35#include <Library/UefiBootServicesTableLib.h>\r
36#include <CpuDriver.h>\r
37\r
38#define IA32_MAX_IO_ADDRESS 0xFFFF\r
39#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF\r
40\r
41EFI_STATUS\r
42CpuIoCheckAddressRange (\r
43 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
44 IN UINT64 Address,\r
45 IN UINTN Count,\r
46 IN VOID *Buffer,\r
47 IN UINT64 Limit\r
48 );\r
49\r
50EFI_STATUS\r
51EFIAPI\r
52CpuMemoryServiceRead (\r
53 IN EFI_CPU_IO2_PROTOCOL *This,\r
54 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
55 IN UINT64 Address,\r
56 IN UINTN Count,\r
57 IN OUT VOID *Buffer\r
58 )\r
59/*++\r
60\r
61Routine Description:\r
62\r
63 Perform the Memory Access Read service for the CPU I/O Protocol\r
64\r
65Arguments:\r
66\r
67 Pointer to an instance of the CPU I/O Protocol\r
68 Width of the Memory Access\r
69 Address of the Memory access\r
70 Count of the number of accesses to perform\r
71 Pointer to the buffer to read or write from memory\r
72\r
73Returns:\r
74\r
75 Status\r
76\r
d18d8a1d 77 EFI_SUCCESS - The data was read from or written to the EFI\r
949f388f 78 System.\r
79 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
80 EFI_INVALID_PARAMETER - Buffer is NULL.\r
81 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 82 EFI_UNSUPPORTED - The address range specified by Address, Width,\r
949f388f 83 and Count is not valid for this EFI System.\r
84\r
85**/\r
86{\r
87 EFI_STATUS Status;\r
88\r
89 if (!Buffer) {\r
90 return EFI_INVALID_PARAMETER;\r
91 }\r
92\r
93 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
94 if (EFI_ERROR (Status)) {\r
95 return Status;\r
96 }\r
97\r
98 //\r
99 // Do nothing for Nt32 version\r
100 //\r
101 return EFI_SUCCESS;\r
102}\r
103\r
104EFI_STATUS\r
105EFIAPI\r
106CpuMemoryServiceWrite (\r
107 IN EFI_CPU_IO2_PROTOCOL *This,\r
108 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
109 IN UINT64 Address,\r
110 IN UINTN Count,\r
111 IN OUT VOID *Buffer\r
112 )\r
113/*++\r
114\r
115Routine Description:\r
116\r
117 Perform the Memory Access Read service for the CPU I/O Protocol\r
118\r
119Arguments:\r
120\r
121 Pointer to an instance of the CPU I/O Protocol\r
122 Width of the Memory Access\r
123 Address of the Memory access\r
124 Count of the number of accesses to perform\r
125 Pointer to the buffer to read or write from memory\r
126\r
127Returns:\r
128\r
129 Status\r
130\r
131 EFI_SUCCESS - The data was read from or written to the EFI System.\r
132 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
133 EFI_INVALID_PARAMETER - Buffer is NULL.\r
134 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 135 EFI_UNSUPPORTED - The address range specified by Address, Width, and\r
949f388f 136 Count is not valid for this EFI System.\r
137\r
138**/\r
139{\r
140 EFI_STATUS Status;\r
141\r
142 if (!Buffer) {\r
143 return EFI_INVALID_PARAMETER;\r
144 }\r
145\r
146 Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
147 if (EFI_ERROR (Status)) {\r
148 return Status;\r
149 }\r
150\r
151 //\r
152 // Do nothing for Nt32 version\r
153 //\r
154 return EFI_SUCCESS;\r
155}\r
156\r
157EFI_STATUS\r
158EFIAPI\r
159CpuIoServiceRead (\r
160 IN EFI_CPU_IO2_PROTOCOL *This,\r
161 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
162 IN UINT64 UserAddress,\r
163 IN UINTN Count,\r
164 IN OUT VOID *UserBuffer\r
165 )\r
166/*++\r
167\r
168Routine Description:\r
d18d8a1d 169\r
949f388f 170 This is the service that implements the I/O read\r
171\r
172Arguments:\r
173\r
174 Pointer to an instance of the CPU I/O Protocol\r
175 Width of the Memory Access\r
176 Address of the I/O access\r
177 Count of the number of accesses to perform\r
178 Pointer to the buffer to read or write from I/O space\r
179\r
180Returns:\r
181\r
182 Status\r
183 EFI_SUCCESS - The data was read from or written to the EFI System.\r
184 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
185 EFI_INVALID_PARAMETER - Buffer is NULL.\r
186 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 187 EFI_UNSUPPORTED - The address range specified by Address, Width, and\r
949f388f 188 Count is not valid for this EFI System.\r
189**/\r
190{\r
191 UINTN Address;\r
192 EFI_STATUS Status;\r
193\r
194 if (!UserBuffer) {\r
195 return EFI_INVALID_PARAMETER;\r
196 }\r
197\r
198 Address = (UINTN) UserAddress;\r
199\r
200 if (Width >= EfiCpuIoWidthMaximum) {\r
201 return EFI_INVALID_PARAMETER;\r
202 }\r
203\r
204 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
205 if (EFI_ERROR (Status)) {\r
206 return Status;\r
207 }\r
208\r
209 //\r
210 // Do nothing for Nt32 version\r
211 //\r
212 return EFI_SUCCESS;\r
213}\r
214\r
215EFI_STATUS\r
216EFIAPI\r
217CpuIoServiceWrite (\r
218 IN EFI_CPU_IO2_PROTOCOL *This,\r
219 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
220 IN UINT64 UserAddress,\r
221 IN UINTN Count,\r
222 IN OUT VOID *UserBuffer\r
223 )\r
224/*++\r
225\r
226Routine Description:\r
227\r
d18d8a1d 228\r
949f388f 229 This is the service that implements the I/O Write\r
230\r
231Arguments:\r
232\r
233 Pointer to an instance of the CPU I/O Protocol\r
234 Width of the Memory Access\r
235 Address of the I/O access\r
236 Count of the number of accesses to perform\r
237 Pointer to the buffer to read or write from I/O space\r
238\r
239Returns:\r
240\r
241 Status\r
242\r
243 Status\r
244 EFI_SUCCESS - The data was read from or written to the EFI System.\r
245 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
246 EFI_INVALID_PARAMETER - Buffer is NULL.\r
247 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
d18d8a1d 248 EFI_UNSUPPORTED - The address range specified by Address, Width, and\r
949f388f 249 Count is not valid for this EFI System.\r
250\r
251**/\r
252{\r
253 UINTN Address;\r
254 EFI_STATUS Status;\r
255\r
256 if (!UserBuffer) {\r
257 return EFI_INVALID_PARAMETER;\r
258 }\r
259\r
260 Address = (UINTN) UserAddress;\r
261\r
262 if (Width >= EfiCpuIoWidthMaximum) {\r
263 return EFI_INVALID_PARAMETER;\r
264 }\r
265\r
266 Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
267 if (EFI_ERROR (Status)) {\r
268 return Status;\r
269 }\r
270\r
271 //\r
272 // Do nothing for Nt32 version\r
273 //\r
274 return EFI_SUCCESS;\r
275}\r
276\r
277\r
278/*++\r
279\r
280Routine Description:\r
281\r
282Arguments:\r
283\r
284 Width - TODO: add argument description\r
285 Address - TODO: add argument description\r
286 Count - TODO: add argument description\r
287 Buffer - TODO: add argument description\r
288 Limit - TODO: add argument description\r
289\r
290Returns:\r
291\r
292 EFI_UNSUPPORTED - TODO: Add description for return value\r
293 EFI_UNSUPPORTED - TODO: Add description for return value\r
294 EFI_UNSUPPORTED - TODO: Add description for return value\r
295 EFI_SUCCESS - TODO: Add description for return value\r
296\r
297**/\r
298EFI_STATUS\r
299CpuIoCheckAddressRange (\r
300 IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
301 IN UINT64 Address,\r
302 IN UINTN Count,\r
303 IN VOID *Buffer,\r
304 IN UINT64 Limit\r
305 )\r
306{\r
307 UINTN AlignMask;\r
308\r
309 if (Address > Limit) {\r
310 return EFI_UNSUPPORTED;\r
311 }\r
312\r
313 //\r
314 // For FiFo type, the target address won't increase during the access, so treat count as 1\r
315 //\r
316 if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {\r
317 Count = 1;\r
318 }\r
319\r
320 Width = Width & 0x03;\r
321 if (Address - 1 + (1 << Width) * Count > Limit) {\r
322 return EFI_UNSUPPORTED;\r
323 }\r
324\r
325 AlignMask = (1 << Width) - 1;\r
326 if ((UINTN) Buffer & AlignMask) {\r
327 return EFI_UNSUPPORTED;\r
328 }\r
329\r
330 return EFI_SUCCESS;\r
331}\r
332\r
333\r