Home | History | Annotate | Download | only in AcpiPlatformDxe
      1 /** @file
      2   Sample ACPI Platform Driver
      3 
      4   Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <PiDxe.h>
     16 
     17 #include <Protocol/AcpiTable.h>
     18 #include <Protocol/FirmwareVolume2.h>
     19 
     20 #include <Library/BaseLib.h>
     21 #include <Library/UefiBootServicesTableLib.h>
     22 #include <Library/DebugLib.h>
     23 #include <Library/PcdLib.h>
     24 
     25 #include <IndustryStandard/Acpi.h>
     26 
     27 /**
     28   Locate the first instance of a protocol.  If the protocol requested is an
     29   FV protocol, then it will return the first FV that contains the ACPI table
     30   storage file.
     31 
     32   @param  Instance      Return pointer to the first instance of the protocol
     33 
     34   @return EFI_SUCCESS           The function completed successfully.
     35   @return EFI_NOT_FOUND         The protocol could not be located.
     36   @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
     37 
     38 **/
     39 EFI_STATUS
     40 LocateFvInstanceWithTables (
     41   OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
     42   )
     43 {
     44   EFI_STATUS                    Status;
     45   EFI_HANDLE                    *HandleBuffer;
     46   UINTN                         NumberOfHandles;
     47   EFI_FV_FILETYPE               FileType;
     48   UINT32                        FvStatus;
     49   EFI_FV_FILE_ATTRIBUTES        Attributes;
     50   UINTN                         Size;
     51   UINTN                         Index;
     52   EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
     53 
     54   FvStatus = 0;
     55 
     56   //
     57   // Locate protocol.
     58   //
     59   Status = gBS->LocateHandleBuffer (
     60                    ByProtocol,
     61                    &gEfiFirmwareVolume2ProtocolGuid,
     62                    NULL,
     63                    &NumberOfHandles,
     64                    &HandleBuffer
     65                    );
     66   if (EFI_ERROR (Status)) {
     67     //
     68     // Defined errors at this time are not found and out of resources.
     69     //
     70     return Status;
     71   }
     72 
     73 
     74 
     75   //
     76   // Looking for FV with ACPI storage file
     77   //
     78 
     79   for (Index = 0; Index < NumberOfHandles; Index++) {
     80     //
     81     // Get the protocol on this handle
     82     // This should not fail because of LocateHandleBuffer
     83     //
     84     Status = gBS->HandleProtocol (
     85                      HandleBuffer[Index],
     86                      &gEfiFirmwareVolume2ProtocolGuid,
     87                      (VOID**) &FvInstance
     88                      );
     89     ASSERT_EFI_ERROR (Status);
     90 
     91     //
     92     // See if it has the ACPI storage file
     93     //
     94     Status = FvInstance->ReadFile (
     95                            FvInstance,
     96                            (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
     97                            NULL,
     98                            &Size,
     99                            &FileType,
    100                            &Attributes,
    101                            &FvStatus
    102                            );
    103 
    104     //
    105     // If we found it, then we are done
    106     //
    107     if (Status == EFI_SUCCESS) {
    108       *Instance = FvInstance;
    109       break;
    110     }
    111   }
    112 
    113   //
    114   // Our exit status is determined by the success of the previous operations
    115   // If the protocol was found, Instance already points to it.
    116   //
    117 
    118   //
    119   // Free any allocated buffers
    120   //
    121   gBS->FreePool (HandleBuffer);
    122 
    123   return Status;
    124 }
    125 
    126 
    127 /**
    128   This function calculates and updates an UINT8 checksum.
    129 
    130   @param  Buffer          Pointer to buffer to checksum
    131   @param  Size            Number of bytes to checksum
    132 
    133 **/
    134 VOID
    135 AcpiPlatformChecksum (
    136   IN UINT8      *Buffer,
    137   IN UINTN      Size
    138   )
    139 {
    140   UINTN ChecksumOffset;
    141 
    142   ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
    143 
    144   //
    145   // Set checksum to 0 first
    146   //
    147   Buffer[ChecksumOffset] = 0;
    148 
    149   //
    150   // Update checksum value
    151   //
    152   Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
    153 }
    154 
    155 
    156 /**
    157   Entrypoint of Acpi Platform driver.
    158 
    159   @param  ImageHandle
    160   @param  SystemTable
    161 
    162   @return EFI_SUCCESS
    163   @return EFI_LOAD_ERROR
    164   @return EFI_OUT_OF_RESOURCES
    165 
    166 **/
    167 EFI_STATUS
    168 EFIAPI
    169 AcpiPlatformEntryPoint (
    170   IN EFI_HANDLE         ImageHandle,
    171   IN EFI_SYSTEM_TABLE   *SystemTable
    172   )
    173 {
    174   EFI_STATUS                     Status;
    175   EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
    176   EFI_FIRMWARE_VOLUME2_PROTOCOL  *FwVol;
    177   INTN                           Instance;
    178   EFI_ACPI_COMMON_HEADER         *CurrentTable;
    179   UINTN                          TableHandle;
    180   UINT32                         FvStatus;
    181   UINTN                          TableSize;
    182   UINTN                          Size;
    183 
    184   Instance     = 0;
    185   CurrentTable = NULL;
    186   TableHandle  = 0;
    187 
    188   //
    189   // Find the AcpiTable protocol
    190   //
    191   Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
    192   if (EFI_ERROR (Status)) {
    193     return EFI_ABORTED;
    194   }
    195 
    196   //
    197   // Locate the firmware volume protocol
    198   //
    199   Status = LocateFvInstanceWithTables (&FwVol);
    200   if (EFI_ERROR (Status)) {
    201     return EFI_ABORTED;
    202   }
    203   //
    204   // Read tables from the storage file.
    205   //
    206   while (Status == EFI_SUCCESS) {
    207 
    208     Status = FwVol->ReadSection (
    209                       FwVol,
    210                       (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
    211                       EFI_SECTION_RAW,
    212                       Instance,
    213                       (VOID**) &CurrentTable,
    214                       &Size,
    215                       &FvStatus
    216                       );
    217     if (!EFI_ERROR(Status)) {
    218       //
    219       // Add the table
    220       //
    221       TableHandle = 0;
    222 
    223       TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
    224       ASSERT (Size >= TableSize);
    225 
    226       //
    227       // Checksum ACPI table
    228       //
    229       AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
    230 
    231       //
    232       // Install ACPI table
    233       //
    234       Status = AcpiTable->InstallAcpiTable (
    235                             AcpiTable,
    236                             CurrentTable,
    237                             TableSize,
    238                             &TableHandle
    239                             );
    240 
    241       //
    242       // Free memory allocated by ReadSection
    243       //
    244       gBS->FreePool (CurrentTable);
    245 
    246       if (EFI_ERROR(Status)) {
    247         return EFI_ABORTED;
    248       }
    249 
    250       //
    251       // Increment the instance
    252       //
    253       Instance++;
    254       CurrentTable = NULL;
    255     }
    256   }
    257 
    258   return EFI_SUCCESS;
    259 }
    260 
    261