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
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
31 EFI_CPU_IO_PROTOCOL mCpuIoProtocol
;
34 CpuIoCheckAddressRange (
35 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
44 CpuMemoryServiceRead (
45 IN EFI_CPU_IO_PROTOCOL
*This
,
46 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
55 Perform the Memory Access Read service for the CPU I/O Protocol
59 Pointer to an instance of the CPU I/O Protocol
60 Width of the Memory Access
61 Address of the Memory access
62 Count of the number of accesses to perform
63 Pointer to the buffer to read or write from memory
69 EFI_SUCCESS - The data was read from or written to the EFI
71 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
72 EFI_INVALID_PARAMETER - Buffer is NULL.
73 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
74 EFI_UNSUPPORTED - The address range specified by Address, Width,
75 and Count is not valid for this EFI System.
78 // TODO: This - add argument and description to function comment
83 return EFI_INVALID_PARAMETER
;
86 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
87 if (EFI_ERROR (Status
)) {
92 // Do nothing for Nt32 version
99 CpuMemoryServiceWrite (
100 IN EFI_CPU_IO_PROTOCOL
*This
,
101 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
110 Perform the Memory Access Read service for the CPU I/O Protocol
114 Pointer to an instance of the CPU I/O Protocol
115 Width of the Memory Access
116 Address of the Memory access
117 Count of the number of accesses to perform
118 Pointer to the buffer to read or write from memory
124 EFI_SUCCESS - The data was read from or written to the EFI System.
125 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
126 EFI_INVALID_PARAMETER - Buffer is NULL.
127 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
128 EFI_UNSUPPORTED - The address range specified by Address, Width, and
129 Count is not valid for this EFI System.
132 // TODO: This - add argument and description to function comment
137 return EFI_INVALID_PARAMETER
;
140 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
141 if (EFI_ERROR (Status
)) {
146 // Do nothing for Nt32 version
154 IN EFI_CPU_IO_PROTOCOL
*This
,
155 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
156 IN UINT64 UserAddress
,
158 IN OUT VOID
*UserBuffer
164 This is the service that implements the I/O read
168 Pointer to an instance of the CPU I/O Protocol
169 Width of the Memory Access
170 Address of the I/O access
171 Count of the number of accesses to perform
172 Pointer to the buffer to read or write from I/O space
177 EFI_SUCCESS - The data was read from or written to the EFI System.
178 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
179 EFI_INVALID_PARAMETER - Buffer is NULL.
180 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
181 EFI_UNSUPPORTED - The address range specified by Address, Width, and
182 Count is not valid for this EFI System.
184 // TODO: This - add argument and description to function comment
185 // TODO: UserAddress - add argument and description to function comment
186 // TODO: UserBuffer - add argument and description to function comment
192 return EFI_INVALID_PARAMETER
;
195 Address
= (UINTN
) UserAddress
;
197 if (Width
>= EfiCpuIoWidthMaximum
) {
198 return EFI_INVALID_PARAMETER
;
201 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
202 if (EFI_ERROR (Status
)) {
207 // Do nothing for Nt32 version
215 IN EFI_CPU_IO_PROTOCOL
*This
,
216 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
217 IN UINT64 UserAddress
,
219 IN OUT VOID
*UserBuffer
226 This is the service that implements the I/O Write
230 Pointer to an instance of the CPU I/O Protocol
231 Width of the Memory Access
232 Address of the I/O access
233 Count of the number of accesses to perform
234 Pointer to the buffer to read or write from I/O space
241 EFI_SUCCESS - The data was read from or written to the EFI System.
242 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
243 EFI_INVALID_PARAMETER - Buffer is NULL.
244 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
245 EFI_UNSUPPORTED - The address range specified by Address, Width, and
246 Count is not valid for this EFI System.
249 // TODO: This - add argument and description to function comment
250 // TODO: UserAddress - add argument and description to function comment
251 // TODO: UserBuffer - add argument and description to function comment
257 return EFI_INVALID_PARAMETER
;
260 Address
= (UINTN
) UserAddress
;
262 if (Width
>= EfiCpuIoWidthMaximum
) {
263 return EFI_INVALID_PARAMETER
;
266 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
267 if (EFI_ERROR (Status
)) {
272 // Do nothing for Nt32 version
279 CpuIoCheckAddressRange (
280 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
290 TODO: Add function description
294 Width - TODO: add argument description
295 Address - TODO: add argument description
296 Count - TODO: add argument description
297 Buffer - TODO: add argument description
298 Limit - TODO: add argument description
302 EFI_UNSUPPORTED - TODO: Add description for return value
303 EFI_UNSUPPORTED - TODO: Add description for return value
304 EFI_UNSUPPORTED - TODO: Add description for return value
305 EFI_SUCCESS - TODO: Add description for return value
311 if (Address
> Limit
) {
312 return EFI_UNSUPPORTED
;
316 // For FiFo type, the target address won't increase during the access, so treat count as 1
318 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
322 Width
= (EFI_CPU_IO_PROTOCOL_WIDTH
)(Width
& 0x03);
323 if (Address
- 1 + (1 << Width
) * Count
> Limit
) {
324 return EFI_UNSUPPORTED
;
327 AlignMask
= (1 << Width
) - 1;
328 if ((UINTN
) Buffer
& AlignMask
) {
329 return EFI_UNSUPPORTED
;