Home | History | Annotate | Download | only in PlatformSmm
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
      4 
      5   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      9   The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     13 
     15   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     21 
     23 
     24 Module Name:
     25 
     26     IchS3Save.c
     27 
     28 Abstract:
     29 
     30     SMM S3 handler Driver implementation file
     31 
     32 Revision History
     33 
     34 **/
     35 #include "SmmPlatform.h"
     36 
     37 extern  UINT16                          mAcpiBaseAddr;
     38 EFI_PHYSICAL_ADDRESS                    mRuntimeScriptTableBase;
     39 
     40 EFI_STATUS
     41 InitRuntimeScriptTable (
     42   IN EFI_SYSTEM_TABLE  *SystemTable
     43   )
     44 {
     45   EFI_STATUS        Status;
     46   UINT32            VarAttrib;
     47   UINTN             VarSize;
     48   ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase;
     49 
     50   //
     51   // Allocate runtime ACPI script table space. We need it to save some
     52   // settings done by CSM, which runs after normal script table closed
     53   //
     54   Status = gBS->AllocatePages (
     55                   AllocateAnyPages,
     56                   EfiACPIReclaimMemory,
     57                   1,
     58                   &mRuntimeScriptTableBase
     59                   );
     60   if (EFI_ERROR(Status)) {
     61     return EFI_OUT_OF_RESOURCES ;
     62   }
     63 
     64   //
     65   // Save runtime script table base into global ACPI variable
     66   //
     67   VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
     68               | EFI_VARIABLE_NON_VOLATILE;
     69   VarSize   = sizeof (UINTN);
     70   Status = SystemTable->RuntimeServices->GetVariable (
     71                           ACPI_GLOBAL_VARIABLE,
     72                           &gEfiAcpiVariableCompatiblityGuid,
     73                           &VarAttrib,
     74                           &VarSize,
     75                           &AcpiVariableBase
     76                           );
     77   if (EFI_ERROR(Status)) {
     78     return Status;
     79   }
     80 
     81   AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase;
     82 
     83   return EFI_SUCCESS;
     84 }
     85 
     86 EFI_STATUS
     87 SaveRuntimeScriptTable (
     88   VOID
     89   )
     90 {
     91   SMM_PCI_IO_ADDRESS    PciAddress;
     92   UINT32                Data32;
     93   UINT16                Data16;
     94   UINT8                 Data8;
     95   UINT8                 Mask;
     96   UINTN                 Index;
     97   UINTN                 Offset;
     98   UINT8                 RegTable[] = {
     99 
    100 	  //
    101     //Bus  ,   Dev,  Func,    DMI
    102 	  //
    103       0x00 ,  0x00,  0x00,
    104 
    105 	  //
    106     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    107 	  //
    108       0x00 ,  0x08,  0x00,  0x00,  0x30,  0x00,  0x00,  0xa0,
    109 
    110 	  //
    111     //Bus  ,   Dev,  Func,    LPC device
    112 	  //
    113       0x00 ,  0x1F,  0x00,
    114 
    115 	  //
    116     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    117     //
    118       0x00 ,  0x08,  0x00,  0x07,  0x00,  0x00,  0x90,  0x00,
    119 
    120 	  //
    121     //Bus  ,   Dev,  Func,    PCIE device
    122 	 //
    123       0x00 ,  0x1C,  0x00,
    124 
    125 	  //
    126     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    127     //
    128       0xC0 ,  0x83,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,
    129 
    130 	  //
    131     //Bus  ,   Dev,  Func,    PCIE device
    132     //
    133 	  0x00 ,  0x1C,  0x00,
    134 
    135 	  //
    136     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    137     //
    138       0x03 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
    139 
    140 	  //
    141     //Bus  ,   Dev,  Func,    SATA device
    142 	  //
    143       0x00 ,  0x13,  0x00,
    144 
    145 	  //
    146     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    147     //
    148       0xf4 ,  0xab,  0x27,  0x10,  0xf1,  0x1d,  0x00,  0x40,
    149 
    150     //
    151     //Bus  ,   Dev,  Func,    EHCI device
    152     //
    153      0x00 ,  0x1D,  0x00,
    154 
    155     //
    156     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    157     //
    158      0x10 ,  0x88,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,
    159 
    160     //
    161     //Bus  ,   Dev,  Func,    SMBUS device
    162     //
    163      0x00 ,  0x1f,  0x03,
    164 
    165     //
    166     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    167     //
    168       0x10 ,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
    169 
    170     //
    171     //Bus  ,   Dev,  Func,    SMBUS device
    172     //
    173       0x00 ,  0x1f,  0x03,
    174 
    175     //
    176     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    177     //
    178       0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
    179 
    180     //
    181     //Bus  ,   Dev,  Func,    VGA bus1
    182     //
    183       0x01 ,  0x00,  0x00,
    184 
    185     //
    186     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    187     //
    188       0x58 ,  0x81,  0x18,  0x01,  0xb0,  0x00,  0x00,  0x00,
    189 
    190     //
    191     //Bus  ,   Dev,  Func,    VGA bus1
    192     //
    193       0x01 ,  0x00,  0x00,
    194 
    195     //
    196     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    197     //
    198       0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
    199 
    200     //
    201     //Bus  ,   Dev,  Func,    VGA bus1 function 1
    202     //
    203       0x01 ,  0x00,  0x01,
    204 
    205     //
    206     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    207     //
    208       0x51 ,  0x80,  0x80,  0x01,  0x00,  0x00,  0x00,  0x00,
    209 
    210     //
    211     //Bus  ,   Dev,  Func,    VGA bus1 function 1
    212     //
    213       0x01 ,  0x00,  0x01,
    214 
    215     //
    216     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    217     //
    218       0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
    219 
    220     //
    221     //Bus  ,   Dev,  Func,    IGD bus0 function 0
    222     //
    223       0x00 ,  0x02,  0x00,
    224 
    225     //
    226     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    227     //
    228       0x42 ,  0x81,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,
    229 
    230     //
    231     //Bus  ,   Dev,  Func,    USB bus0 function 0
    232     //
    233       0x00 ,  0x16,  0x00,
    234 
    235     //
    236     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    237     //
    238       0x32 ,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
    239 
    240     //
    241     //Bus  ,   Dev,  Func,    HD Audio bus0 function 0
    242     //
    243       0x00 ,  0x1B,  0x00,
    244 
    245     //
    246     //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    247     //
    248       0x00 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,
    249 
    250     //
    251     //0xFF indicates the end of the table
    252     //
    253       0xFF
    254  };
    255 
    256   //
    257   // These registers have to set in byte order
    258   //
    259   UINT8                 ExtReg[] = { 0x9E, 0x9D };  // SMRAM settings
    260 
    261 
    262 
    263   //
    264   // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
    265   // and vital to S3 resume. That's why we put save code here
    266   //
    267   PciAddress.Bus      = 0;
    268   PciAddress.Device   = 0;
    269   PciAddress.Function = 0;
    270   PciAddress.ExtendedRegister = 0;
    271 
    272   for (Index = 0; Index < 2; Index++) {
    273     //
    274     // Read SRAM setting from Pci(0, 0, 0)
    275     //
    276     PciAddress.Register = ExtReg[Index];
    277     Data8 = MmioRead8 (
    278               MmPciAddress (0,
    279                 PciAddress.Bus,
    280                 PciAddress.Device,
    281                 PciAddress.Function,
    282                 PciAddress.Register
    283               )
    284             );
    285 
    286     //
    287     // Save latest settings to runtime script table
    288     //
    289     S3BootScriptSavePciCfgWrite(
    290       S3BootScriptWidthUint8,
    291       *(UINT64*)&PciAddress,
    292       1,
    293       &Data8
    294       );
    295   }
    296 
    297 
    298   //
    299   // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
    300   // and vital to S3 resume. That's why we put save code here
    301   //
    302   Index = 0;
    303   while (RegTable[Index] != 0xFF) {
    304 
    305     PciAddress.Bus      = RegTable[Index++];
    306     PciAddress.Device   = RegTable[Index++];
    307     PciAddress.Function = RegTable[Index++];
    308     PciAddress.Register = 0;
    309     PciAddress.ExtendedRegister = 0;
    310 
    311     Data16 = MmioRead16 (
    312               MmPciAddress (0,
    313                 PciAddress.Bus,
    314                 PciAddress.Device,
    315                 PciAddress.Function,
    316                 PciAddress.Register
    317               )
    318             );
    319 
    320     if (Data16 == 0xFFFF) {
    321       Index+=8;
    322       continue;
    323     }
    324 
    325     for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
    326 
    327       if (Mask == 0x00) {
    328         Mask = 0x01;
    329       }
    330 
    331       if (RegTable[Index + Offset/32] & Mask ) {
    332 
    333         PciAddress.Register = (UINT8)Offset;
    334         Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
    335 
    336         //
    337         // Save latest settings to runtime script table
    338         //
    339         S3BootScriptSavePciCfgWrite (
    340           S3BootScriptWidthUint32,
    341           *(UINT64*)&PciAddress,
    342           1,
    343           &Data32
    344         );
    345       }
    346     }
    347 
    348     Index += 8;
    349 
    350   }
    351 
    352 
    353   //
    354   // Save I/O ports to S3 script table
    355   //
    356 
    357   //
    358   // Selftest KBC
    359   //
    360   Data8 = 0xAA;
    361   S3BootScriptSaveIoWrite (
    362     S3BootScriptWidthUint8,
    363     0x64,
    364     (UINTN)1,
    365     &Data8
    366     );
    367 
    368   Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
    369 
    370   S3BootScriptSaveIoWrite (
    371       S3BootScriptWidthUint32,
    372       (mAcpiBaseAddr + R_PCH_SMI_EN),
    373       1,
    374       &Data32
    375       );
    376 
    377   //
    378   // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
    379   //
    380   Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);
    381 
    382   S3BootScriptSaveIoWrite (
    383       S3BootScriptWidthUint16,
    384       mAcpiBaseAddr + R_PCH_TCO_CNT,
    385       1,
    386       &Data16
    387       );
    388 
    389 
    390   return EFI_SUCCESS;
    391 }
    392