EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

UnixPkg/CpuRuntimeDxe/CpuIo.c

Go to the documentation of this file.
00001 /*++
00002 
00003 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
00004 This program and the accompanying materials                          
00005 are licensed and made available under the terms and conditions of the BSD License         
00006 which accompanies this distribution.  The full text of the license may be found at        
00007 http://opensource.org/licenses/bsd-license.php                                            
00008                                                                                           
00009 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
00010 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
00011 
00012 Module Name:
00013 
00014   CpuIo.c
00015 
00016 Abstract:
00017 
00018   This is the code that publishes the CPU I/O Protocol.
00019   The intent herein is to have a single I/O service that can load
00020   as early as possible, extend into runtime, and be layered upon by 
00021   the implementations of architectural protocols and the PCI Root
00022   Bridge I/O Protocol.
00023 
00024 --*/
00025 #include <FrameworkDxe.h>
00026 #include <Protocol/Cpu.h>
00027 #include <Protocol/DataHub.h>
00028 #include <Guid/DataHubRecords.h>
00029 #include <Protocol/CpuIo2.h>
00030 #include <Protocol/FrameworkHii.h>
00031 
00032 #include <Library/BaseLib.h>
00033 #include <Library/DebugLib.h>
00034 #include <Library/HiiLib.h>
00035 #include <Library/UefiLib.h>
00036 #include <Library/UefiDriverEntryPoint.h>
00037 #include <Library/BaseMemoryLib.h>
00038 #include <Library/MemoryAllocationLib.h>
00039 #include <Library/UefiBootServicesTableLib.h>
00040 #include <CpuDriver.h>
00041 
00042 #define IA32_MAX_IO_ADDRESS   0xFFFF
00043 #define IA32_MAX_MEM_ADDRESS  0xFFFFFFFF
00044 
00045 EFI_STATUS
00046 CpuIoCheckAddressRange (
00047   IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
00048   IN  UINT64                            Address,
00049   IN  UINTN                             Count,
00050   IN  VOID                              *Buffer,
00051   IN  UINT64                            Limit
00052   );
00053 
00054 EFI_STATUS
00055 EFIAPI
00056 CpuMemoryServiceRead (
00057   IN  EFI_CPU_IO2_PROTOCOL              *This,
00058   IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
00059   IN  UINT64                            Address,
00060   IN  UINTN                             Count,
00061   IN  OUT VOID                          *Buffer
00062   )
00063 /*++
00064 
00065 Routine Description:
00066 
00067   Perform the Memory Access Read service for the CPU I/O Protocol
00068 
00069 Arguments:
00070 
00071   Pointer to an instance of the CPU I/O Protocol
00072   Width of the Memory Access
00073   Address of the Memory access
00074   Count of the number of accesses to perform
00075   Pointer to the buffer to read or write from memory
00076 
00077 Returns:
00078 
00079   Status
00080 
00081   EFI_SUCCESS             - The data was read from or written to the EFI 
00082                             System.
00083   EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
00084   EFI_INVALID_PARAMETER   - Buffer is NULL.
00085   EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
00086   EFI_UNSUPPORTED         - The address range specified by Address, Width, 
00087                             and Count is not valid for this EFI System.
00088 
00089 --*/
00090 // TODO:    This - add argument and description to function comment
00091 {
00092   EFI_STATUS  Status;
00093 
00094   if (!Buffer) {
00095     return EFI_INVALID_PARAMETER;
00096   }
00097 
00098   Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);
00099   if (EFI_ERROR (Status)) {
00100     return Status;
00101   }
00102 
00103   //
00104   // Do nothing for Nt32 version
00105   //
00106   return EFI_SUCCESS;
00107 }
00108 
00109 EFI_STATUS
00110 EFIAPI
00111 CpuMemoryServiceWrite (
00112   IN EFI_CPU_IO2_PROTOCOL               *This,
00113   IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
00114   IN  UINT64                            Address,
00115   IN  UINTN                             Count,
00116   IN  OUT VOID                          *Buffer
00117   )
00118 /*++
00119 
00120 Routine Description:
00121 
00122   Perform the Memory Access Read service for the CPU I/O Protocol
00123 
00124 Arguments:
00125 
00126   Pointer to an instance of the CPU I/O Protocol
00127   Width of the Memory Access
00128   Address of the Memory access
00129   Count of the number of accesses to perform
00130   Pointer to the buffer to read or write from memory
00131 
00132 Returns:
00133 
00134   Status
00135 
00136   EFI_SUCCESS             - The data was read from or written to the EFI System.
00137   EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
00138   EFI_INVALID_PARAMETER   - Buffer is NULL.
00139   EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
00140   EFI_UNSUPPORTED         - The address range specified by Address, Width, and 
00141                             Count is not valid for this EFI System.
00142 
00143 --*/
00144 // TODO:    This - add argument and description to function comment
00145 {
00146   EFI_STATUS  Status;
00147 
00148   if (!Buffer) {
00149     return EFI_INVALID_PARAMETER;
00150   }
00151 
00152   Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);
00153   if (EFI_ERROR (Status)) {
00154     return Status;
00155   }
00156 
00157   //
00158   // Do nothing for Nt32 version
00159   //
00160   return EFI_SUCCESS;
00161 }
00162 
00163 EFI_STATUS
00164 EFIAPI
00165 CpuIoServiceRead (
00166   IN EFI_CPU_IO2_PROTOCOL               *This,
00167   IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
00168   IN  UINT64                            UserAddress,
00169   IN  UINTN                             Count,
00170   IN  OUT VOID                          *UserBuffer
00171   )
00172 /*++
00173 
00174 Routine Description:
00175   
00176   This is the service that implements the I/O read
00177 
00178 Arguments:
00179 
00180   Pointer to an instance of the CPU I/O Protocol
00181   Width of the Memory Access
00182   Address of the I/O access
00183   Count of the number of accesses to perform
00184   Pointer to the buffer to read or write from I/O space
00185 
00186 Returns:
00187 
00188   Status
00189   EFI_SUCCESS             - The data was read from or written to the EFI System.
00190   EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
00191   EFI_INVALID_PARAMETER   - Buffer is NULL.
00192   EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
00193   EFI_UNSUPPORTED         - The address range specified by Address, Width, and 
00194                             Count is not valid for this EFI System.
00195 --*/
00196 // TODO:    This - add argument and description to function comment
00197 // TODO:    UserAddress - add argument and description to function comment
00198 // TODO:    UserBuffer - add argument and description to function comment
00199 {
00200   UINTN       Address;
00201   EFI_STATUS  Status;
00202 
00203   if (!UserBuffer) {
00204     return EFI_INVALID_PARAMETER;
00205   }
00206 
00207   Address = (UINTN) UserAddress;
00208 
00209   if (Width >= EfiCpuIoWidthMaximum) {
00210     return EFI_INVALID_PARAMETER;
00211   }
00212 
00213   Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
00214   if (EFI_ERROR (Status)) {
00215     return Status;
00216   }
00217 
00218   //
00219   // Do nothing for Nt32 version
00220   //
00221   return EFI_SUCCESS;
00222 }
00223 
00224 EFI_STATUS
00225 EFIAPI
00226 CpuIoServiceWrite (
00227   IN EFI_CPU_IO2_PROTOCOL               *This,
00228   IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
00229   IN  UINT64                            UserAddress,
00230   IN  UINTN                             Count,
00231   IN  OUT VOID                          *UserBuffer
00232   )
00233 /*++
00234 
00235 Routine Description:
00236 
00237   
00238   This is the service that implements the I/O Write
00239 
00240 Arguments:
00241 
00242   Pointer to an instance of the CPU I/O Protocol
00243   Width of the Memory Access
00244   Address of the I/O access
00245   Count of the number of accesses to perform
00246   Pointer to the buffer to read or write from I/O space
00247 
00248 Returns:
00249 
00250   Status
00251 
00252   Status
00253   EFI_SUCCESS             - The data was read from or written to the EFI System.
00254   EFI_INVALID_PARAMETER   - Width is invalid for this EFI System.
00255   EFI_INVALID_PARAMETER   - Buffer is NULL.
00256   EFI_UNSUPPORTED         - The Buffer is not aligned for the given Width.
00257   EFI_UNSUPPORTED         - The address range specified by Address, Width, and 
00258                             Count is not valid for this EFI System.
00259 
00260 --*/
00261 // TODO:    This - add argument and description to function comment
00262 // TODO:    UserAddress - add argument and description to function comment
00263 // TODO:    UserBuffer - add argument and description to function comment
00264 {
00265   UINTN       Address;
00266   EFI_STATUS  Status;
00267 
00268   if (!UserBuffer) {
00269     return EFI_INVALID_PARAMETER;
00270   }
00271 
00272   Address = (UINTN) UserAddress;
00273 
00274   if (Width >= EfiCpuIoWidthMaximum) {
00275     return EFI_INVALID_PARAMETER;
00276   }
00277 
00278   Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
00279   if (EFI_ERROR (Status)) {
00280     return Status;
00281   }
00282 
00283   //
00284   // Do nothing for Nt32 version
00285   //
00286   return EFI_SUCCESS;
00287 }
00288 
00289 
00290 EFI_STATUS
00291 CpuIoCheckAddressRange (
00292   IN  EFI_CPU_IO_PROTOCOL_WIDTH         Width,
00293   IN  UINT64                            Address,
00294   IN  UINTN                             Count,
00295   IN  VOID                              *Buffer,
00296   IN  UINT64                            Limit
00297   )
00298 /*++
00299 
00300 Routine Description:
00301 
00302   TODO: Add function description
00303 
00304 Arguments:
00305 
00306   Width   - TODO: add argument description
00307   Address - TODO: add argument description
00308   Count   - TODO: add argument description
00309   Buffer  - TODO: add argument description
00310   Limit   - TODO: add argument description
00311 
00312 Returns:
00313 
00314   EFI_UNSUPPORTED - TODO: Add description for return value
00315   EFI_UNSUPPORTED - TODO: Add description for return value
00316   EFI_UNSUPPORTED - TODO: Add description for return value
00317   EFI_SUCCESS - TODO: Add description for return value
00318 
00319 --*/
00320 {
00321   UINTN AlignMask;
00322 
00323   if (Address > Limit) {
00324     return EFI_UNSUPPORTED;
00325   }
00326 
00327   //
00328   // For FiFo type, the target address won't increase during the access, so treat count as 1
00329   //
00330   if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
00331     Count = 1;
00332   }
00333 
00334   Width = Width & 0x03;
00335   if (Address - 1 + (1 << Width) * Count > Limit) {
00336     return EFI_UNSUPPORTED;
00337   }
00338 
00339   AlignMask = (1 << Width) - 1;
00340   if ((UINTN) Buffer & AlignMask) {
00341     return EFI_UNSUPPORTED;
00342   }
00343 
00344   return EFI_SUCCESS;
00345 }
00346 
00347 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines