Exemple #1
0
/**
  Saves a PCI configuration value to the boot script.

  This internal worker function saves a PCI configuration value in
  the S3 script to be replayed on S3 resume. 

  If the saving process fails, then ASSERT().

  @param  Width   The width of PCI configuration.
  @param  Address Address that encodes the PCI Bus, Device, Function and
                  Register.
  @param  Buffer  The buffer containing value.

**/
VOID
InternalSavePciWriteValueToBootScript (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINTN                  Address,
  IN VOID                   *Buffer
  )
{
  RETURN_STATUS                Status;

  Status = S3BootScriptSavePciCfgWrite (
             Width,
             PCILIB_TO_COMMON_ADDRESS(Address),
             1,
             Buffer
             );
  ASSERT (Status == RETURN_SUCCESS);
}
Exemple #2
0
/**
  Copies the data in a caller supplied buffer to a specified range of PCI
  configuration space and saves the value in the S3 script to be replayed on S3
  resume.

  Writes the range of PCI configuration registers specified by StartAddress and
  Size from the buffer specified by Buffer. This function only allows the PCI
  configuration registers from a single PCI function to be written. Size is
  returned. When possible 32-bit PCI configuration write cycles are used to
  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
  and the end of the range.

  If StartAddress > 0x0FFFFFFF, then ASSERT().
  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
  If Size > 0 and Buffer is NULL, then ASSERT().

  @param  StartAddress  Starting address that encodes the PCI Bus, Device,
                        Function and Register.
  @param  Size          Size in bytes of the transfer.
  @param  Buffer        Pointer to a buffer containing the data to write.

  @return Size

**/
UINTN
EFIAPI
S3PciWriteBuffer (
  IN UINTN                     StartAddress,
  IN UINTN                     Size,
  IN VOID                      *Buffer
  )
{
  RETURN_STATUS    Status;

  Status = S3BootScriptSavePciCfgWrite (
             S3BootScriptWidthUint8,
             PCILIB_TO_COMMON_ADDRESS (StartAddress),
             PciWriteBuffer (StartAddress, Size, Buffer),
             Buffer
             );
  ASSERT (Status == RETURN_SUCCESS);
  
  return Size;
}
Exemple #3
0
EFI_STATUS
SaveRuntimeScriptTable (
  IN EFI_SMM_SYSTEM_TABLE2       *Smst
  )
{
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS  PciAddress;
  UINT32                Data32;
  UINT16                Data16;
  UINT8                 Mask;
  UINTN                 Index;
  UINTN                 Offset;
  UINT16                DeviceId;

  //
  // Check what Soc we are running on (read Host bridge DeviceId)
  //
  DeviceId = QncGetSocDeviceId();

  //
  // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
  // and vital to S3 resume. That's why we put save code here
  //
  Index = 0;
  while (mPciCfgRegTable[Index] != PCI_DEVICE_END) {

    PciAddress.Bus              = mPciCfgRegTable[Index++];
    PciAddress.Device           = mPciCfgRegTable[Index++];
    PciAddress.Function         = mPciCfgRegTable[Index++];
    PciAddress.Register         = 0;
    PciAddress.ExtendedRegister = 0;

    Data16 = PciRead16 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
    if (Data16 == 0xFFFF) {
      Index += 8;
      continue;
    }

    for (Offset = 0, Mask = 0x01; Offset < 256; Offset += 4, Mask <<= 1) {

      if (Mask == 0x00) {
        Mask = 0x01;
      }

      if (mPciCfgRegTable[Index + Offset / 32] & Mask) {

        PciAddress.Register = (UINT8) Offset;
        Data32 = PciRead32 (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));


        //
        // Save latest settings to runtime script table
        //
        S3BootScriptSavePciCfgWrite (
             S3BootScriptWidthUint32,
             PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)),
             1,
             &Data32
             );
      }
    }

    Index += 8;

  }

  //
  // Save message bus registers
  //
  Index = 0;
  while (QNCS3SaveExtReg[Index] != 0xFF) {
    Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

    //
    // Save IMR settings with IMR protection disabled initially
    // HMBOUND and IMRs will be locked just before jumping to the OS waking vector
    //
    if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) {
      if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) {
        Data32 &= ~IMR_LOCK;
        if (DeviceId == QUARK2_MC_DEVICE_ID) {
          Data32 &= ~IMR_EN;
        }
      }
      if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) {
        Data32 = (UINT32)IMRX_ALL_ACCESS;
      }
    }

    //
    // Save latest settings to runtime script table
    //
    S3BootScriptSavePciCfgWrite (
      S3BootScriptWidthUint32,
      PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
      1,
      &Data32
     );

    Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

    S3BootScriptSavePciCfgWrite (
      S3BootScriptWidthUint32,
      PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
      1,
      &Data32
     );
    Index += 2;
  }

  Index = 0;
  while (QNCS3SaveExtReg[Index] != 0xFF) {
    //
    // Save IMR settings with IMR protection enabled (above script was to handle restoring all settings first - now we want to enable)
    //
    if (QNCS3SaveExtReg[Index] == QUARK_NC_MEMORY_MANAGER_SB_PORT_ID) {
      if (DeviceId == QUARK2_MC_DEVICE_ID) {
        if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXL)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) == QUARK_NC_MEMORY_MANAGER_IMRXL)) {
          Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);
          Data32 &= ~IMR_LOCK;

          //
          // Save latest settings to runtime script table
          //
          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
            1,
            &Data32
          );

          Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
            1,
            &Data32
          );
        }
      } else {
        if ((QNCS3SaveExtReg[Index + 1] >= (QUARK_NC_MEMORY_MANAGER_IMR0+QUARK_NC_MEMORY_MANAGER_IMRXRM)) && (QNCS3SaveExtReg[Index + 1] <= (QUARK_NC_MEMORY_MANAGER_IMR7+QUARK_NC_MEMORY_MANAGER_IMRXWM)) && ((QNCS3SaveExtReg[Index + 1] & 0x03) >= QUARK_NC_MEMORY_MANAGER_IMRXRM)) {
          Data32 = QNCPortRead (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

          //
          // Save latest settings to runtime script table
          //
          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MDR)),
            1,
            &Data32
          );

          Data32 = MESSAGE_WRITE_DW (QNCS3SaveExtReg[Index], QNCS3SaveExtReg[Index + 1]);

          S3BootScriptSavePciCfgWrite (
            S3BootScriptWidthUint32,
            PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
            1,
            &Data32
          );
        }
      }
    }
    Index += 2;
  }

  // Check if ECC scrub enabled and need re-enabling on resume
  // All scrub related configuration registers are saved on suspend
  // as part of QNCS3SaveExtReg configuration table script.
  // The code below extends the S3 resume script with scrub reactivation
  // message (if needed only)
  Data32 = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG);
  if( 0 != (Data32 & SCRUB_CFG_ACTIVE)) {

      Data32 = SCRUB_RESUME_MSG();

      S3BootScriptSavePciCfgWrite (
        S3BootScriptWidthUint32,
        PCILIB_TO_COMMON_ADDRESS (PCI_LIB_ADDRESS(0, 0, 0, QNC_ACCESS_PORT_MCR)),
        1,
        &Data32
       );
  }

  //
  // Save I/O ports to S3 script table
  //

  //
  // Important to trap Sx for SMM
  //
  Data32 = IoRead32 (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE);
  S3BootScriptSaveIoWrite(S3BootScriptWidthUint32, (mAcpiSmm.QncGpe0Base + R_QNC_GPE0BLK_SMIE), 1, &Data32);

  return EFI_SUCCESS;
}