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>
31 #include <Guid/DataHubProducer.h>
33 #include <Library/BaseLib.h>
34 #include <Library/DebugLib.h>
35 #include <Library/HiiLib.h>
36 #include <Library/UefiLib.h>
37 #include <Library/UefiDriverEntryPoint.h>
38 #include <Library/BaseMemoryLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/UefiBootServicesTableLib.h>
41 #include <CpuDriver.h>
43 #define IA32_MAX_IO_ADDRESS 0xFFFF
44 #define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF
46 EFI_CPU_IO_PROTOCOL mCpuIoProtocol
;
49 CpuIoCheckAddressRange (
50 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
59 CpuMemoryServiceRead (
60 IN EFI_CPU_IO_PROTOCOL
*This
,
61 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
70 Perform the Memory Access Read service for the CPU I/O Protocol
74 Pointer to an instance of the CPU I/O Protocol
75 Width of the Memory Access
76 Address of the Memory access
77 Count of the number of accesses to perform
78 Pointer to the buffer to read or write from memory
84 EFI_SUCCESS - The data was read from or written to the EFI
86 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
87 EFI_INVALID_PARAMETER - Buffer is NULL.
88 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
89 EFI_UNSUPPORTED - The address range specified by Address, Width,
90 and Count is not valid for this EFI System.
93 // TODO: This - add argument and description to function comment
98 return EFI_INVALID_PARAMETER
;
101 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
102 if (EFI_ERROR (Status
)) {
107 // Do nothing for Nt32 version
114 CpuMemoryServiceWrite (
115 IN EFI_CPU_IO_PROTOCOL
*This
,
116 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
125 Perform the Memory Access Read service for the CPU I/O Protocol
129 Pointer to an instance of the CPU I/O Protocol
130 Width of the Memory Access
131 Address of the Memory access
132 Count of the number of accesses to perform
133 Pointer to the buffer to read or write from memory
139 EFI_SUCCESS - The data was read from or written to the EFI System.
140 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
141 EFI_INVALID_PARAMETER - Buffer is NULL.
142 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
143 EFI_UNSUPPORTED - The address range specified by Address, Width, and
144 Count is not valid for this EFI System.
147 // TODO: This - add argument and description to function comment
152 return EFI_INVALID_PARAMETER
;
155 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, Buffer
, IA32_MAX_MEM_ADDRESS
);
156 if (EFI_ERROR (Status
)) {
161 // Do nothing for Nt32 version
169 IN EFI_CPU_IO_PROTOCOL
*This
,
170 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
171 IN UINT64 UserAddress
,
173 IN OUT VOID
*UserBuffer
179 This is the service that implements the I/O read
183 Pointer to an instance of the CPU I/O Protocol
184 Width of the Memory Access
185 Address of the I/O access
186 Count of the number of accesses to perform
187 Pointer to the buffer to read or write from I/O space
192 EFI_SUCCESS - The data was read from or written to the EFI System.
193 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
194 EFI_INVALID_PARAMETER - Buffer is NULL.
195 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
196 EFI_UNSUPPORTED - The address range specified by Address, Width, and
197 Count is not valid for this EFI System.
199 // TODO: This - add argument and description to function comment
200 // TODO: UserAddress - add argument and description to function comment
201 // TODO: UserBuffer - add argument and description to function comment
207 return EFI_INVALID_PARAMETER
;
210 Address
= (UINTN
) UserAddress
;
212 if (Width
>= EfiCpuIoWidthMaximum
) {
213 return EFI_INVALID_PARAMETER
;
216 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
217 if (EFI_ERROR (Status
)) {
222 // Do nothing for Nt32 version
230 IN EFI_CPU_IO_PROTOCOL
*This
,
231 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
232 IN UINT64 UserAddress
,
234 IN OUT VOID
*UserBuffer
241 This is the service that implements the I/O Write
245 Pointer to an instance of the CPU I/O Protocol
246 Width of the Memory Access
247 Address of the I/O access
248 Count of the number of accesses to perform
249 Pointer to the buffer to read or write from I/O space
256 EFI_SUCCESS - The data was read from or written to the EFI System.
257 EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
258 EFI_INVALID_PARAMETER - Buffer is NULL.
259 EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
260 EFI_UNSUPPORTED - The address range specified by Address, Width, and
261 Count is not valid for this EFI System.
264 // TODO: This - add argument and description to function comment
265 // TODO: UserAddress - add argument and description to function comment
266 // TODO: UserBuffer - add argument and description to function comment
272 return EFI_INVALID_PARAMETER
;
275 Address
= (UINTN
) UserAddress
;
277 if (Width
>= EfiCpuIoWidthMaximum
) {
278 return EFI_INVALID_PARAMETER
;
281 Status
= CpuIoCheckAddressRange (Width
, Address
, Count
, UserBuffer
, IA32_MAX_IO_ADDRESS
);
282 if (EFI_ERROR (Status
)) {
287 // Do nothing for Nt32 version
294 CpuIoCheckAddressRange (
295 IN EFI_CPU_IO_PROTOCOL_WIDTH Width
,
305 TODO: Add function description
309 Width - TODO: add argument description
310 Address - TODO: add argument description
311 Count - TODO: add argument description
312 Buffer - TODO: add argument description
313 Limit - TODO: add argument description
317 EFI_UNSUPPORTED - TODO: Add description for return value
318 EFI_UNSUPPORTED - TODO: Add description for return value
319 EFI_UNSUPPORTED - TODO: Add description for return value
320 EFI_SUCCESS - TODO: Add description for return value
326 if (Address
> Limit
) {
327 return EFI_UNSUPPORTED
;
331 // For FiFo type, the target address won't increase during the access, so treat count as 1
333 if (Width
>= EfiCpuIoWidthFifoUint8
&& Width
<= EfiCpuIoWidthFifoUint64
) {
337 Width
= Width
& 0x03;
338 if (Address
- 1 + (1 << Width
) * Count
> Limit
) {
339 return EFI_UNSUPPORTED
;
342 AlignMask
= (1 << Width
) - 1;
343 if ((UINTN
) Buffer
& AlignMask
) {
344 return EFI_UNSUPPORTED
;