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 <Protocol/Cpu.h>
27 #include <Protocol/DataHub.h>
28 #include <Guid/DataHubRecords.h>
29 #include <Protocol/CpuIo.h>
30 #include <Protocol/FrameworkHii.h>
32 #include <Library/BaseLib.h>
33 #include <Library/DebugLib.h>
34 #include <Library/HiiLib.h>
35 #include <Library/UefiLib.h>
36 #include <Library/UefiDriverEntryPoint.h>
37 #include <Library/BaseMemoryLib.h>
38 #include <Library/MemoryAllocationLib.h>
39 #include <Library/UefiBootServicesTableLib.h>
40 #include <CpuDriver.h>
42 #define IA32_MAX_IO_ADDRESS 0xFFFF
43 #define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF
45 EFI_CPU_IO_PROTOCOL mCpuIoProtocol
;
48 CpuIoCheckAddressRange (
49 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
58 CpuMemoryServiceRead (
59 IN EFI_CPU_IO_PROTOCOL
*This
,
60 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
69 Perform the Memory Access Read service for the CPU I/O Protocol
73 Pointer to an instance of the CPU I/O Protocol
74 Width of the Memory Access
75 Address of the Memory access
76 Count of the number of accesses to perform
77 Pointer to the buffer to read or write from memory
83 EFI_SUCCESS - The data was read from or written to the EFI
85 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
86 EFI_INVALID_PARAMETER - Buffer is NULL.
87 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
88 EFI_UNSUPPORTED - The address range specified by Address, Width,
89 and Count is not valid for this EFI System.
92 // TODO: This - add argument and description to function comment
97 return EFI_INVALID_PARAMETER
;
100 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
101 if (EFI_ERROR (Status
)) {
106 // Do nothing for Nt32 version
113 CpuMemoryServiceWrite (
114 IN EFI_CPU_IO_PROTOCOL
*This
,
115 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
124 Perform the Memory Access Read service for the CPU I/O Protocol
128 Pointer to an instance of the CPU I/O Protocol
129 Width of the Memory Access
130 Address of the Memory access
131 Count of the number of accesses to perform
132 Pointer to the buffer to read or write from memory
138 EFI_SUCCESS - The data was read from or written to the EFI System.
139 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
140 EFI_INVALID_PARAMETER - Buffer is NULL.
141 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
142 EFI_UNSUPPORTED - The address range specified by Address, Width, and
143 Count is not valid for this EFI System.
146 // TODO: This - add argument and description to function comment
151 return EFI_INVALID_PARAMETER
;
154 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
155 if (EFI_ERROR (Status
)) {
160 // Do nothing for Nt32 version
168 IN EFI_CPU_IO_PROTOCOL
*This
,
169 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
170 IN UINT64 UserAddress
,
172 IN OUT VOID
*UserBuffer
178 This is the service that implements the I/O read
182 Pointer to an instance of the CPU I/O Protocol
183 Width of the Memory Access
184 Address of the I/O access
185 Count of the number of accesses to perform
186 Pointer to the buffer to read or write from I/O space
191 EFI_SUCCESS - The data was read from or written to the EFI System.
192 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
193 EFI_INVALID_PARAMETER - Buffer is NULL.
194 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
195 EFI_UNSUPPORTED - The address range specified by Address, Width, and
196 Count is not valid for this EFI System.
198 // TODO: This - add argument and description to function comment
199 // TODO: UserAddress - add argument and description to function comment
200 // TODO: UserBuffer - add argument and description to function comment
206 return EFI_INVALID_PARAMETER
;
209 Address
= (UINTN
) UserAddress
;
211 if (Width
>= EfiCpuIoWidthMaximum
) {
212 return EFI_INVALID_PARAMETER
;
215 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
216 if (EFI_ERROR (Status
)) {
221 // Do nothing for Nt32 version
229 IN EFI_CPU_IO_PROTOCOL
*This
,
230 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
231 IN UINT64 UserAddress
,
233 IN OUT VOID
*UserBuffer
240 This is the service that implements the I/O Write
244 Pointer to an instance of the CPU I/O Protocol
245 Width of the Memory Access
246 Address of the I/O access
247 Count of the number of accesses to perform
248 Pointer to the buffer to read or write from I/O space
255 EFI_SUCCESS - The data was read from or written to the EFI System.
256 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
257 EFI_INVALID_PARAMETER - Buffer is NULL.
258 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
259 EFI_UNSUPPORTED - The address range specified by Address, Width, and
260 Count is not valid for this EFI System.
263 // TODO: This - add argument and description to function comment
264 // TODO: UserAddress - add argument and description to function comment
265 // TODO: UserBuffer - add argument and description to function comment
271 return EFI_INVALID_PARAMETER
;
274 Address
= (UINTN
) UserAddress
;
276 if (Width
>= EfiCpuIoWidthMaximum
) {
277 return EFI_INVALID_PARAMETER
;
280 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
281 if (EFI_ERROR (Status
)) {
286 // Do nothing for Nt32 version
293 CpuIoCheckAddressRange (
294 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
304 TODO: Add function description
308 Width - TODO: add argument description
309 Address - TODO: add argument description
310 Count - TODO: add argument description
311 Buffer - TODO: add argument description
312 Limit - TODO: add argument description
316 EFI_UNSUPPORTED - TODO: Add description for return value
317 EFI_UNSUPPORTED - TODO: Add description for return value
318 EFI_UNSUPPORTED - TODO: Add description for return value
319 EFI_SUCCESS - TODO: Add description for return value
325 if (Address
> Limit
) {
326 return EFI_UNSUPPORTED
;
330 // For FiFo type, the target address won't increase during the access, so treat count as 1
332 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
336 Width
= Width
& 0x03;
337 if (Address
- 1 + (1 << Width
) * Count
> Limit
) {
338 return EFI_UNSUPPORTED
;
341 AlignMask
= (1 << Width
) - 1;
342 if ((UINTN
) Buffer
& AlignMask
) {
343 return EFI_UNSUPPORTED
;