--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ CpuIo.c\r
+\r
+Abstract:\r
+\r
+ This is the code that publishes the CPU I/O Protocol.\r
+ The intent herein is to have a single I/O service that can load\r
+ as early as possible, extend into runtime, and be layered upon by \r
+ the implementations of architectural protocols and the PCI Root\r
+ Bridge I/O Protocol.\r
+\r
+--*/\r
+\r
+#include <CpuDriver.h>\r
+\r
+#define IA32_MAX_IO_ADDRESS 0xFFFF\r
+#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF\r
+\r
+EFI_CPU_IO_PROTOCOL mCpuIoProtocol;\r
+\r
+EFI_STATUS\r
+CpuIoCheckAddressRange (\r
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN VOID *Buffer,\r
+ IN UINT64 Limit\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuMemoryServiceRead (\r
+ IN EFI_CPU_IO_PROTOCOL *This,\r
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Perform the Memory Access Read service for the CPU I/O Protocol\r
+\r
+Arguments:\r
+\r
+ Pointer to an instance of the CPU I/O Protocol\r
+ Width of the Memory Access\r
+ Address of the Memory access\r
+ Count of the number of accesses to perform\r
+ Pointer to the buffer to read or write from memory\r
+\r
+Returns:\r
+\r
+ Status\r
+\r
+ EFI_SUCCESS - The data was read from or written to the EFI \r
+ System.\r
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
+ EFI_INVALID_PARAMETER - Buffer is NULL.\r
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
+ EFI_UNSUPPORTED - The address range specified by Address, Width, \r
+ and Count is not valid for this EFI System.\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (!Buffer) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Do nothing for Nt32 version\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuMemoryServiceWrite (\r
+ IN EFI_CPU_IO_PROTOCOL *This,\r
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Perform the Memory Access Read service for the CPU I/O Protocol\r
+\r
+Arguments:\r
+\r
+ Pointer to an instance of the CPU I/O Protocol\r
+ Width of the Memory Access\r
+ Address of the Memory access\r
+ Count of the number of accesses to perform\r
+ Pointer to the buffer to read or write from memory\r
+\r
+Returns:\r
+\r
+ Status\r
+\r
+ EFI_SUCCESS - The data was read from or written to the EFI System.\r
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
+ EFI_INVALID_PARAMETER - Buffer is NULL.\r
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
+ EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
+ Count is not valid for this EFI System.\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (!Buffer) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Do nothing for Nt32 version\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuIoServiceRead (\r
+ IN EFI_CPU_IO_PROTOCOL *This,\r
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 UserAddress,\r
+ IN UINTN Count,\r
+ IN OUT VOID *UserBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ This is the service that implements the I/O read\r
+\r
+Arguments:\r
+\r
+ Pointer to an instance of the CPU I/O Protocol\r
+ Width of the Memory Access\r
+ Address of the I/O access\r
+ Count of the number of accesses to perform\r
+ Pointer to the buffer to read or write from I/O space\r
+\r
+Returns:\r
+\r
+ Status\r
+ EFI_SUCCESS - The data was read from or written to the EFI System.\r
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
+ EFI_INVALID_PARAMETER - Buffer is NULL.\r
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
+ EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
+ Count is not valid for this EFI System.\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: UserAddress - add argument and description to function comment\r
+// TODO: UserBuffer - add argument and description to function comment\r
+{\r
+ UINTN Address;\r
+ EFI_STATUS Status;\r
+\r
+ if (!UserBuffer) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Address = (UINTN) UserAddress;\r
+\r
+ if (Width >= EfiCpuIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Do nothing for Nt32 version\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+CpuIoServiceWrite (\r
+ IN EFI_CPU_IO_PROTOCOL *This,\r
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 UserAddress,\r
+ IN UINTN Count,\r
+ IN OUT VOID *UserBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ \r
+ This is the service that implements the I/O Write\r
+\r
+Arguments:\r
+\r
+ Pointer to an instance of the CPU I/O Protocol\r
+ Width of the Memory Access\r
+ Address of the I/O access\r
+ Count of the number of accesses to perform\r
+ Pointer to the buffer to read or write from I/O space\r
+\r
+Returns:\r
+\r
+ Status\r
+\r
+ Status\r
+ EFI_SUCCESS - The data was read from or written to the EFI System.\r
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.\r
+ EFI_INVALID_PARAMETER - Buffer is NULL.\r
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.\r
+ EFI_UNSUPPORTED - The address range specified by Address, Width, and \r
+ Count is not valid for this EFI System.\r
+\r
+--*/\r
+// TODO: This - add argument and description to function comment\r
+// TODO: UserAddress - add argument and description to function comment\r
+// TODO: UserBuffer - add argument and description to function comment\r
+{\r
+ UINTN Address;\r
+ EFI_STATUS Status;\r
+\r
+ if (!UserBuffer) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Address = (UINTN) UserAddress;\r
+\r
+ if (Width >= EfiCpuIoWidthMaximum) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Do nothing for Nt32 version\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+CpuIoCheckAddressRange (\r
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,\r
+ IN UINT64 Address,\r
+ IN UINTN Count,\r
+ IN VOID *Buffer,\r
+ IN UINT64 Limit\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ TODO: Add function description\r
+\r
+Arguments:\r
+\r
+ Width - TODO: add argument description\r
+ Address - TODO: add argument description\r
+ Count - TODO: add argument description\r
+ Buffer - TODO: add argument description\r
+ Limit - TODO: add argument description\r
+\r
+Returns:\r
+\r
+ EFI_UNSUPPORTED - TODO: Add description for return value\r
+ EFI_UNSUPPORTED - TODO: Add description for return value\r
+ EFI_UNSUPPORTED - TODO: Add description for return value\r
+ EFI_SUCCESS - TODO: Add description for return value\r
+\r
+--*/\r
+{\r
+ UINTN AlignMask;\r
+\r
+ if (Address > Limit) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // For FiFo type, the target address won't increase during the access, so treat count as 1\r
+ //\r
+ if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {\r
+ Count = 1;\r
+ }\r
+\r
+ Width = Width & 0x03;\r
+ if (Address - 1 + (1 << Width) * Count > Limit) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ AlignMask = (1 << Width) - 1;\r
+ if ((UINTN) Buffer & AlignMask) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r