/**
  Internal function to add IO write opcode to the table.

  @param  Marker                The variable argument list to get the opcode
                                and associated attributes.

  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
  @retval EFI_SUCCESS           Opcode is added.

**/
EFI_STATUS
BootScriptWriteIoWrite (
  IN VA_LIST                       Marker
  )
{
  S3_BOOT_SCRIPT_LIB_WIDTH Width;
  UINT64                Address;
  UINTN                 Count;
  UINT8                 *Buffer;

  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
  Address     = VA_ARG (Marker, UINT64);
  Count       = VA_ARG (Marker, UINTN);
  Buffer      = VA_ARG (Marker, UINT8 *);

  return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer);
}
Exemple #2
0
EFI_STATUS
SaveRuntimeScriptTable (
  VOID
  )
{
  SMM_PCI_IO_ADDRESS    PciAddress;
  UINT32                Data32;
  UINT16                Data16;
  UINT8                 Data8;
  UINT8                 Mask;
  UINTN                 Index;
  UINTN                 Offset;
  UINT8                 RegTable[] = {

	  //
    //Bus  ,   Dev,  Func,    DMI
	  //
      0x00 ,  0x00,  0x00,

	  //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
	  //
      0x00 ,  0x08,  0x00,  0x00,  0x30,  0x00,  0x00,  0xa0,

	  //
    //Bus  ,   Dev,  Func,    LPC device
	  //
      0x00 ,  0x1F,  0x00,

	  //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x00 ,  0x08,  0x00,  0x07,  0x00,  0x00,  0x90,  0x00,

	  //
    //Bus  ,   Dev,  Func,    PCIE device
	 //
      0x00 ,  0x1C,  0x00,

	  //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0xC0 ,  0x83,  0x30,  0x00,  0x00,  0x00,  0x00,  0x00,

	  //
    //Bus  ,   Dev,  Func,    PCIE device
    //
	  0x00 ,  0x1C,  0x00,

	  //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x03 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,

	  //
    //Bus  ,   Dev,  Func,    SATA device
	  //
      0x00 ,  0x13,  0x00,

	  //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0xf4 ,  0xab,  0x27,  0x10,  0xf1,  0x1d,  0x00,  0x40,

    //
    //Bus  ,   Dev,  Func,    EHCI device
    //
     0x00 ,  0x1D,  0x00,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
     0x10 ,  0x88,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,

    //
    //Bus  ,   Dev,  Func,    SMBUS device
    //
     0x00 ,  0x1f,  0x03,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x10 ,  0x89,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    SMBUS device
    //
      0x00 ,  0x1f,  0x03,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    VGA bus1
    //
      0x01 ,  0x00,  0x00,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x58 ,  0x81,  0x18,  0x01,  0xb0,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    VGA bus1
    //
      0x01 ,  0x00,  0x00,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    VGA bus1 function 1
    //
      0x01 ,  0x00,  0x01,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x51 ,  0x80,  0x80,  0x01,  0x00,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    VGA bus1 function 1
    //
      0x01 ,  0x00,  0x01,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x02 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    IGD bus0 function 0
    //
      0x00 ,  0x02,  0x00,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x42 ,  0x81,  0x00,  0x00,  0x00,  0x00,  0x20,  0x00,

    //
    //Bus  ,   Dev,  Func,    USB bus0 function 0
    //
      0x00 ,  0x16,  0x00,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x32 ,  0x80,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,

    //
    //Bus  ,   Dev,  Func,    HD Audio bus0 function 0
    //
      0x00 ,  0x1B,  0x00,

    //
    //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
    //
      0x00 ,  0x00,  0x00,  0x00,  0x00,  0x00,  0x02,  0x00,

    //
    //0xFF indicates the end of the table
    //
      0xFF
 };

  //
  // These registers have to set in byte order
  //
  UINT8                 ExtReg[] = { 0x9E, 0x9D };  // SMRAM settings



  //
  // 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
  //
  PciAddress.Bus      = 0;
  PciAddress.Device   = 0;
  PciAddress.Function = 0;
  PciAddress.ExtendedRegister = 0;

  for (Index = 0; Index < 2; Index++) {
    //
    // Read SRAM setting from Pci(0, 0, 0)
    //
    PciAddress.Register = ExtReg[Index];
    Data8 = MmioRead8 (
              MmPciAddress (0,
                PciAddress.Bus,
                PciAddress.Device,
                PciAddress.Function,
                PciAddress.Register
              )
            );

    //
    // Save latest settings to runtime script table
    //
    S3BootScriptSavePciCfgWrite(
      S3BootScriptWidthUint8,
      *(UINT64*)&PciAddress,
      1,
      &Data8
      );
  }


  //
  // 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 (RegTable[Index] != 0xFF) {

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

    Data16 = MmioRead16 (
              MmPciAddress (0,
                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 (RegTable[Index + Offset/32] & Mask ) {

        PciAddress.Register = (UINT8)Offset;
        Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));

        //
        // Save latest settings to runtime script table
        //
        S3BootScriptSavePciCfgWrite (
          S3BootScriptWidthUint32,
          *(UINT64*)&PciAddress,
          1,
          &Data32
        );
      }
    }

    Index += 8;

  }


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

  //
  // Selftest KBC
  //
  Data8 = 0xAA;
  S3BootScriptSaveIoWrite (
    S3BootScriptWidthUint8,
    0x64,
    (UINTN)1,
    &Data8
    );

  Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);

  S3BootScriptSaveIoWrite (
      S3BootScriptWidthUint32,
      (mAcpiBaseAddr + R_PCH_SMI_EN),
      1,
      &Data32
      );

  //
  // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
  //
  Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);

  S3BootScriptSaveIoWrite (
      S3BootScriptWidthUint16,
      mAcpiBaseAddr + R_PCH_TCO_CNT,
      1,
      &Data16
      );


  return EFI_SUCCESS;
}
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;
}