3 Copyright (c) 2006 - 2009, 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
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 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
85 if (EFI_ERROR (Status
)) {
90 // Do nothing for Nt32 version
92 return EFI_UNSUPPORTED
;
97 CpuMemoryServiceWrite (
98 IN EFI_CPU_IO2_PROTOCOL
*This
,
99 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
108 Perform the Memory Access Read service for the CPU I/O Protocol
112 Pointer to an instance of the CPU I/O Protocol
113 Width of the Memory Access
114 Address of the Memory access
115 Count of the number of accesses to perform
116 Pointer to the buffer to read or write from memory
122 EFI_SUCCESS - The data was read from or written to the EFI System.
123 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
124 EFI_INVALID_PARAMETER - Buffer is NULL.
125 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
126 EFI_UNSUPPORTED - The address range specified by Address, Width, and
127 Count is not valid for this EFI System.
130 // TODO: This - add argument and description to function comment
135 return EFI_INVALID_PARAMETER
;
138 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
139 if (EFI_ERROR (Status
)) {
144 // Do nothing for Nt32 version
146 return EFI_UNSUPPORTED
;
152 IN EFI_CPU_IO2_PROTOCOL
*This
,
153 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
154 IN UINT64 UserAddress
,
156 IN OUT VOID
*UserBuffer
162 This is the service that implements the I/O read
166 Pointer to an instance of the CPU I/O Protocol
167 Width of the Memory Access
168 Address of the I/O access
169 Count of the number of accesses to perform
170 Pointer to the buffer to read or write from I/O space
175 EFI_SUCCESS - The data was read from or written to the EFI System.
176 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
177 EFI_INVALID_PARAMETER - Buffer is NULL.
178 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
179 EFI_UNSUPPORTED - The address range specified by Address, Width, and
180 Count is not valid for this EFI System.
182 // TODO: This - add argument and description to function comment
183 // TODO: UserAddress - add argument and description to function comment
184 // TODO: UserBuffer - add argument and description to function comment
190 return EFI_INVALID_PARAMETER
;
193 Address
= (UINTN
) UserAddress
;
195 if (Width
>= EfiCpuIoWidthMaximum
) {
196 return EFI_INVALID_PARAMETER
;
199 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
200 if (EFI_ERROR (Status
)) {
205 // Do nothing for Nt32 version
207 return EFI_UNSUPPORTED
;
213 IN EFI_CPU_IO2_PROTOCOL
*This
,
214 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
215 IN UINT64 UserAddress
,
217 IN OUT VOID
*UserBuffer
224 This is the service that implements the I/O Write
228 Pointer to an instance of the CPU I/O Protocol
229 Width of the Memory Access
230 Address of the I/O access
231 Count of the number of accesses to perform
232 Pointer to the buffer to read or write from I/O space
239 EFI_SUCCESS - The data was read from or written to the EFI System.
240 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
241 EFI_INVALID_PARAMETER - Buffer is NULL.
242 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
243 EFI_UNSUPPORTED - The address range specified by Address, Width, and
244 Count is not valid for this EFI System.
247 // TODO: This - add argument and description to function comment
248 // TODO: UserAddress - add argument and description to function comment
249 // TODO: UserBuffer - add argument and description to function comment
255 return EFI_INVALID_PARAMETER
;
258 Address
= (UINTN
) UserAddress
;
260 if (Width
>= EfiCpuIoWidthMaximum
) {
261 return EFI_INVALID_PARAMETER
;
264 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
265 if (EFI_ERROR (Status
)) {
270 // Do nothing for Nt32 version
272 return EFI_UNSUPPORTED
;
277 CpuIoCheckAddressRange (
278 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
288 TODO: Add function description
292 Width - TODO: add argument description
293 Address - TODO: add argument description
294 Count - TODO: add argument description
295 Buffer - TODO: add argument description
296 Limit - TODO: add argument description
300 EFI_UNSUPPORTED - TODO: Add description for return value
301 EFI_UNSUPPORTED - TODO: Add description for return value
302 EFI_UNSUPPORTED - TODO: Add description for return value
303 EFI_SUCCESS - TODO: Add description for return value
309 if (Address
> Limit
) {
310 return EFI_UNSUPPORTED
;
314 // For FiFo type, the target address won't increase during the access, so treat count as 1
316 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
320 Width
= (EFI_CPU_IO_PROTOCOL_WIDTH
)(Width
& 0x03);
321 if (Address
- 1 + (1 << Width
) * Count
> Limit
) {
322 return EFI_UNSUPPORTED
;
325 AlignMask
= (1 << Width
) - 1;
326 if ((UINTN
) Buffer
& AlignMask
) {
327 return EFI_UNSUPPORTED
;