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
27 // Include common header file for this module.
29 #include "CommonHeader.h"
31 #include <CpuDriver.h>
33 #define IA32_MAX_IO_ADDRESS 0xFFFF
34 #define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF
36 EFI_CPU_IO_PROTOCOL mCpuIoProtocol
;
39 CpuIoCheckAddressRange (
40 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
49 CpuMemoryServiceRead (
50 IN EFI_CPU_IO_PROTOCOL
*This
,
51 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
60 Perform the Memory Access Read service for the CPU I/O Protocol
64 Pointer to an instance of the CPU I/O Protocol
65 Width of the Memory Access
66 Address of the Memory access
67 Count of the number of accesses to perform
68 Pointer to the buffer to read or write from memory
74 EFI_SUCCESS - The data was read from or written to the EFI
76 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
77 EFI_INVALID_PARAMETER - Buffer is NULL.
78 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
79 EFI_UNSUPPORTED - The address range specified by Address, Width,
80 and Count is not valid for this EFI System.
83 // TODO: This - add argument and description to function comment
88 return EFI_INVALID_PARAMETER
;
91 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
92 if (EFI_ERROR (Status
)) {
97 // Do nothing for Nt32 version
104 CpuMemoryServiceWrite (
105 IN EFI_CPU_IO_PROTOCOL
*This
,
106 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
115 Perform the Memory Access Read service for the CPU I/O Protocol
119 Pointer to an instance of the CPU I/O Protocol
120 Width of the Memory Access
121 Address of the Memory access
122 Count of the number of accesses to perform
123 Pointer to the buffer to read or write from memory
129 EFI_SUCCESS - The data was read from or written to the EFI System.
130 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
131 EFI_INVALID_PARAMETER - Buffer is NULL.
132 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
133 EFI_UNSUPPORTED - The address range specified by Address, Width, and
134 Count is not valid for this EFI System.
137 // TODO: This - add argument and description to function comment
142 return EFI_INVALID_PARAMETER
;
145 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
146 if (EFI_ERROR (Status
)) {
151 // Do nothing for Nt32 version
159 IN EFI_CPU_IO_PROTOCOL
*This
,
160 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
161 IN UINT64 UserAddress
,
163 IN OUT VOID
*UserBuffer
169 This is the service that implements the I/O read
173 Pointer to an instance of the CPU I/O Protocol
174 Width of the Memory Access
175 Address of the I/O access
176 Count of the number of accesses to perform
177 Pointer to the buffer to read or write from I/O space
182 EFI_SUCCESS - The data was read from or written to the EFI System.
183 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
184 EFI_INVALID_PARAMETER - Buffer is NULL.
185 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
186 EFI_UNSUPPORTED - The address range specified by Address, Width, and
187 Count is not valid for this EFI System.
189 // TODO: This - add argument and description to function comment
190 // TODO: UserAddress - add argument and description to function comment
191 // TODO: UserBuffer - add argument and description to function comment
197 return EFI_INVALID_PARAMETER
;
200 Address
= (UINTN
) UserAddress
;
202 if (Width
>= EfiCpuIoWidthMaximum
) {
203 return EFI_INVALID_PARAMETER
;
206 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
207 if (EFI_ERROR (Status
)) {
212 // Do nothing for Nt32 version
220 IN EFI_CPU_IO_PROTOCOL
*This
,
221 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
222 IN UINT64 UserAddress
,
224 IN OUT VOID
*UserBuffer
231 This is the service that implements the I/O Write
235 Pointer to an instance of the CPU I/O Protocol
236 Width of the Memory Access
237 Address of the I/O access
238 Count of the number of accesses to perform
239 Pointer to the buffer to read or write from I/O space
246 EFI_SUCCESS - The data was read from or written to the EFI System.
247 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
248 EFI_INVALID_PARAMETER - Buffer is NULL.
249 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
250 EFI_UNSUPPORTED - The address range specified by Address, Width, and
251 Count is not valid for this EFI System.
254 // TODO: This - add argument and description to function comment
255 // TODO: UserAddress - add argument and description to function comment
256 // TODO: UserBuffer - add argument and description to function comment
262 return EFI_INVALID_PARAMETER
;
265 Address
= (UINTN
) UserAddress
;
267 if (Width
>= EfiCpuIoWidthMaximum
) {
268 return EFI_INVALID_PARAMETER
;
271 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
272 if (EFI_ERROR (Status
)) {
277 // Do nothing for Nt32 version
284 CpuIoCheckAddressRange (
285 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
295 TODO: Add function description
299 Width - TODO: add argument description
300 Address - TODO: add argument description
301 Count - TODO: add argument description
302 Buffer - TODO: add argument description
303 Limit - TODO: add argument description
307 EFI_UNSUPPORTED - TODO: Add description for return value
308 EFI_UNSUPPORTED - TODO: Add description for return value
309 EFI_UNSUPPORTED - TODO: Add description for return value
310 EFI_SUCCESS - TODO: Add description for return value
316 if (Address
> Limit
) {
317 return EFI_UNSUPPORTED
;
321 // For FiFo type, the target address won't increase during the access, so treat count as 1
323 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
327 Width
= Width
& 0x03;
328 if (Address
- 1 + (1 << Width
) * Count
> Limit
) {
329 return EFI_UNSUPPORTED
;
332 AlignMask
= (1 << Width
) - 1;
333 if ((UINTN
) Buffer
& AlignMask
) {
334 return EFI_UNSUPPORTED
;