3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
4 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
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.
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
26 #include <CpuDriver.h>
28 #define IA32_MAX_IO_ADDRESS 0xFFFF
29 #define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF
32 CpuIoCheckAddressRange (
33 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
42 CpuMemoryServiceRead (
43 IN EFI_CPU_IO2_PROTOCOL
*This
,
44 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
53 Perform the Memory Access Read service for the CPU I/O Protocol
57 Pointer to an instance of the CPU I/O Protocol
58 Width of the Memory Access
59 Address of the Memory access
60 Count of the number of accesses to perform
61 Pointer to the buffer to read or write from memory
67 EFI_SUCCESS - The data was read from or written to the EFI
69 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
70 EFI_INVALID_PARAMETER - Buffer is NULL.
71 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
72 EFI_UNSUPPORTED - The address range specified by Address, Width,
73 and Count is not valid for this EFI System.
76 // TODO: This - add argument and description to function comment
81 return EFI_INVALID_PARAMETER
;
84 if ((Width
< 0) || (Width
>= EfiCpuIoWidthMaximum
)) {
85 return EFI_INVALID_PARAMETER
;
88 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
89 if (EFI_ERROR (Status
)) {
94 // Do nothing for Nt32 version
96 return EFI_UNSUPPORTED
;
101 CpuMemoryServiceWrite (
102 IN EFI_CPU_IO2_PROTOCOL
*This
,
103 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
112 Perform the Memory Access Read service for the CPU I/O Protocol
116 Pointer to an instance of the CPU I/O Protocol
117 Width of the Memory Access
118 Address of the Memory access
119 Count of the number of accesses to perform
120 Pointer to the buffer to read or write from memory
126 EFI_SUCCESS - The data was read from or written to the EFI System.
127 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
128 EFI_INVALID_PARAMETER - Buffer is NULL.
129 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
130 EFI_UNSUPPORTED - The address range specified by Address, Width, and
131 Count is not valid for this EFI System.
134 // TODO: This - add argument and description to function comment
139 return EFI_INVALID_PARAMETER
;
142 if ((Width
< 0) || (Width
>= EfiCpuIoWidthMaximum
)) {
143 return EFI_INVALID_PARAMETER
;
146 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
147 if (EFI_ERROR (Status
)) {
152 // Do nothing for Nt32 version
154 return EFI_UNSUPPORTED
;
160 IN EFI_CPU_IO2_PROTOCOL
*This
,
161 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
162 IN UINT64 UserAddress
,
164 IN OUT VOID
*UserBuffer
170 This is the service that implements the I/O read
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
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.
190 // TODO: This - add argument and description to function comment
191 // TODO: UserAddress - add argument and description to function comment
192 // TODO: UserBuffer - add argument and description to function comment
198 return EFI_INVALID_PARAMETER
;
201 Address
= (UINTN
) UserAddress
;
203 if ((Width
< 0) || (Width
>= EfiCpuIoWidthMaximum
)) {
204 return EFI_INVALID_PARAMETER
;
207 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
208 if (EFI_ERROR (Status
)) {
213 // Do nothing for Nt32 version
215 return EFI_UNSUPPORTED
;
221 IN EFI_CPU_IO2_PROTOCOL
*This
,
222 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
223 IN UINT64 UserAddress
,
225 IN OUT VOID
*UserBuffer
232 This is the service that implements the I/O Write
236 Pointer to an instance of the CPU I/O Protocol
237 Width of the Memory Access
238 Address of the I/O access
239 Count of the number of accesses to perform
240 Pointer to the buffer to read or write from I/O space
247 EFI_SUCCESS - The data was read from or written to the EFI System.
248 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
249 EFI_INVALID_PARAMETER - Buffer is NULL.
250 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
251 EFI_UNSUPPORTED - The address range specified by Address, Width, and
252 Count is not valid for this EFI System.
255 // TODO: This - add argument and description to function comment
256 // TODO: UserAddress - add argument and description to function comment
257 // TODO: UserBuffer - add argument and description to function comment
263 return EFI_INVALID_PARAMETER
;
266 Address
= (UINTN
) UserAddress
;
268 if ((Width
< 0) || (Width
>= EfiCpuIoWidthMaximum
)) {
269 return EFI_INVALID_PARAMETER
;
272 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
273 if (EFI_ERROR (Status
)) {
278 // Do nothing for Nt32 version
280 return EFI_UNSUPPORTED
;
285 CpuIoCheckAddressRange (
286 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
296 TODO: Add function description
300 Width - TODO: add argument description
301 Address - TODO: add argument description
302 Count - TODO: add argument description
303 Buffer - TODO: add argument description
304 Limit - TODO: add argument description
308 EFI_UNSUPPORTED - TODO: Add description for return value
309 EFI_UNSUPPORTED - TODO: Add description for return value
310 EFI_UNSUPPORTED - TODO: Add description for return value
311 EFI_SUCCESS - TODO: Add description for return value
317 if (Address
> Limit
) {
318 return EFI_UNSUPPORTED
;
322 // For FiFo type, the target address won't increase during the access, so treat count as 1
324 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
328 Width
= (EFI_CPU_IO_PROTOCOL_WIDTH
)(Width
& 0x03);
329 if (Address
- 1 + ((UINTN
)1 << Width
) * Count
> Limit
) {
330 return EFI_UNSUPPORTED
;
333 AlignMask
= ((UINTN
)1 << Width
) - 1;
334 if ((UINTN
) Buffer
& AlignMask
) {
335 return EFI_UNSUPPORTED
;