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