3 Copyright (c) 2006, 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
25 #include <FrameworkDxe.h>
26 #include <Protocol/Cpu.h>
27 #include <Protocol/DataHub.h>
28 #include <Guid/DataHubRecords.h>
29 #include <Protocol/CpuIo2.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
46 CpuIoCheckAddressRange (
47 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
56 CpuMemoryServiceRead (
57 IN EFI_CPU_IO2_PROTOCOL
*This
,
58 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
67 Perform the Memory Access Read service for the CPU I/O Protocol
71 Pointer to an instance of the CPU I/O Protocol
72 Width of the Memory Access
73 Address of the Memory access
74 Count of the number of accesses to perform
75 Pointer to the buffer to read or write from memory
81 EFI_SUCCESS - The data was read from or written to the EFI
83 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
84 EFI_INVALID_PARAMETER - Buffer is NULL.
85 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
86 EFI_UNSUPPORTED - The address range specified by Address, Width,
87 and Count is not valid for this EFI System.
90 // TODO: This - add argument and description to function comment
95 return EFI_INVALID_PARAMETER
;
98 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
99 if (EFI_ERROR (Status
)) {
104 // Do nothing for Nt32 version
111 CpuMemoryServiceWrite (
112 IN EFI_CPU_IO2_PROTOCOL
*This
,
113 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
122 Perform the Memory Access Read service for the CPU I/O Protocol
126 Pointer to an instance of the CPU I/O Protocol
127 Width of the Memory Access
128 Address of the Memory access
129 Count of the number of accesses to perform
130 Pointer to the buffer to read or write from memory
136 EFI_SUCCESS - The data was read from or written to the EFI System.
137 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
138 EFI_INVALID_PARAMETER - Buffer is NULL.
139 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
140 EFI_UNSUPPORTED - The address range specified by Address, Width, and
141 Count is not valid for this EFI System.
144 // TODO: This - add argument and description to function comment
149 return EFI_INVALID_PARAMETER
;
152 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
153 if (EFI_ERROR (Status
)) {
158 // Do nothing for Nt32 version
166 IN EFI_CPU_IO2_PROTOCOL
*This
,
167 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
168 IN UINT64 UserAddress
,
170 IN OUT VOID
*UserBuffer
176 This is the service that implements the I/O read
180 Pointer to an instance of the CPU I/O Protocol
181 Width of the Memory Access
182 Address of the I/O access
183 Count of the number of accesses to perform
184 Pointer to the buffer to read or write from I/O space
189 EFI_SUCCESS - The data was read from or written to the EFI System.
190 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
191 EFI_INVALID_PARAMETER - Buffer is NULL.
192 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
193 EFI_UNSUPPORTED - The address range specified by Address, Width, and
194 Count is not valid for this EFI System.
196 // TODO: This - add argument and description to function comment
197 // TODO: UserAddress - add argument and description to function comment
198 // TODO: UserBuffer - add argument and description to function comment
204 return EFI_INVALID_PARAMETER
;
207 Address
= (UINTN
) UserAddress
;
209 if (Width
>= EfiCpuIoWidthMaximum
) {
210 return EFI_INVALID_PARAMETER
;
213 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
214 if (EFI_ERROR (Status
)) {
219 // Do nothing for Nt32 version
227 IN EFI_CPU_IO2_PROTOCOL
*This
,
228 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
229 IN UINT64 UserAddress
,
231 IN OUT VOID
*UserBuffer
238 This is the service that implements the I/O Write
242 Pointer to an instance of the CPU I/O Protocol
243 Width of the Memory Access
244 Address of the I/O access
245 Count of the number of accesses to perform
246 Pointer to the buffer to read or write from I/O space
253 EFI_SUCCESS - The data was read from or written to the EFI System.
254 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
255 EFI_INVALID_PARAMETER - Buffer is NULL.
256 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
257 EFI_UNSUPPORTED - The address range specified by Address, Width, and
258 Count is not valid for this EFI System.
261 // TODO: This - add argument and description to function comment
262 // TODO: UserAddress - add argument and description to function comment
263 // TODO: UserBuffer - add argument and description to function comment
269 return EFI_INVALID_PARAMETER
;
272 Address
= (UINTN
) UserAddress
;
274 if (Width
>= EfiCpuIoWidthMaximum
) {
275 return EFI_INVALID_PARAMETER
;
278 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
279 if (EFI_ERROR (Status
)) {
284 // Do nothing for Nt32 version
291 CpuIoCheckAddressRange (
292 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
302 TODO: Add function description
306 Width - TODO: add argument description
307 Address - TODO: add argument description
308 Count - TODO: add argument description
309 Buffer - TODO: add argument description
310 Limit - TODO: add argument description
314 EFI_UNSUPPORTED - TODO: Add description for return value
315 EFI_UNSUPPORTED - TODO: Add description for return value
316 EFI_UNSUPPORTED - TODO: Add description for return value
317 EFI_SUCCESS - TODO: Add description for return value
323 if (Address
> Limit
) {
324 return EFI_UNSUPPORTED
;
328 // For FiFo type, the target address won't increase during the access, so treat count as 1
330 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
334 Width
= Width
& 0x03;
335 if (Address
- 1 + (1 << Width
) * Count
> Limit
) {
336 return EFI_UNSUPPORTED
;
339 AlignMask
= (1 << Width
) - 1;
340 if ((UINTN
) Buffer
& AlignMask
) {
341 return EFI_UNSUPPORTED
;