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