Beispiel #1
0
/**
 * Restores the context of a 'conditional' PCI device.
 *
 * This traverses the provided register list restoring PCI registers when appropriate.
 *
 * @param[in]     StdHeader      AMD standard header config param.
 * @param[in]     Device         'conditional' PCI device to restore.
 * @param[in]     CallPoint      Indicates whether this is AMD_INIT_RESUME or
 *                               AMD_S3LATE_RESTORE.
 * @param[in,out] OrMask         Current buffer pointer of raw register values.
 *
 */
VOID
RestoreConditionalPciDevice (
  IN       AMD_CONFIG_PARAMS                 *StdHeader,
  IN       CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
  IN       CALL_POINTS                       CallPoint,
  IN OUT   VOID                              **OrMask
  )
{
  UINT8   RegSizeInBytes;
  UINT8   SpecialCaseIndex;
  UINT8   *IntermediatePtr;
  UINT8   BootMode;
  UINT16  i;
  UINT32  Socket;
  UINT32  Module;
  UINT32  RegValueRead;
  UINT32  RegValueWrite;
  UINT32  AndMask;
  ACCESS_WIDTH AccessWidth;
  AGESA_STATUS IgnoredSts;
  PCI_ADDR PciAddress;
  CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;

  GetSocketModuleOfNode ((UINT32) Device->Node,
                               &Socket,
                               &Module,
                               StdHeader);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  if (CallPoint == INIT_RESUME) {
    MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  } else {
    S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  }

  BootMode = S3_RESUME_MODE;
  if (StdHeader->Func == AMD_INIT_POST) {
    BootMode = RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE;
  }

  for (i = 0; i < RegisterHdr->NumRegisters; i++) {
    if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
        ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
      PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
      PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
      RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
      switch (RegSizeInBytes) {
      case 1:
        AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
        RegValueWrite = **(UINT8 **)OrMask;
        AccessWidth = AccessS3SaveWidth8;
        break;
      case 2:
        AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
        RegValueWrite = **(UINT16 **)OrMask;
        AccessWidth = AccessS3SaveWidth16;
        break;
      case 3:
        // In this case, we don't need to restore a register. We just need to call a special
        //  function to do certain things in the save and resume sequence.
        // This should not be used in a non-special case.
        AndMask = 0;
        RegValueWrite = 0;
        RegSizeInBytes = 0;
        AccessWidth = 0;
        break;
      default:
        AndMask = RegisterHdr->RegisterList[i].AndMask;
        RegSizeInBytes = 4;
        RegValueWrite = **(UINT32 **)OrMask;
        AccessWidth = AccessS3SaveWidth32;
        break;
      }
      if ((RegisterHdr->RegisterList[i].BootMode == 0) || ((BootMode & RegisterHdr->RegisterList[i].BootMode) != 0)) {
        // Do not restore the register if not in the right boot mode
        // Pointer to the saved data buffer still needs to be adjusted as data will be saved regardless of boot mode
        if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
          LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader);
          RegValueWrite |= RegValueRead & (~AndMask);
          LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader);
        } else {
          SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
          if (AndMask != 0) {
            RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth,
                                               PciAddress,
                                               &RegValueRead,
                                               StdHeader);
            RegValueWrite |= RegValueRead & (~AndMask);
          }
          RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth,
                                                 PciAddress,
                                                 &RegValueWrite,
                                                 StdHeader);
        }
        IDS_OPTION_HOOK (IDS_AFTER_RESTORING_PCI_REG, RegisterHdr, StdHeader);
      }
      IntermediatePtr = (UINT8 *) *OrMask;
      *OrMask = &IntermediatePtr[RegSizeInBytes];
      if ((RegSizeInBytes == 0) && (RegValueWrite == RESTART_FROM_BEGINNING_LIST)) {
        // Restart from the beginning of the register list
        i = 0xFFFF;
      }
    }
  }
}
Beispiel #2
0
/**
 * Saves the context of a 'conditional' PCI device.
 *
 * This traverses the provided register list saving PCI registers when appropriate.
 *
 * @param[in]     StdHeader      AMD standard header config param.
 * @param[in]     Device         'conditional' PCI device to restore.
 * @param[in]     CallPoint      Indicates whether this is AMD_INIT_RESUME or
 *                               AMD_S3LATE_RESTORE.
 * @param[in,out] OrMask         Current buffer pointer of raw register values.
 *
 */
VOID
SaveConditionalPciDevice (
  IN       AMD_CONFIG_PARAMS                 *StdHeader,
  IN       CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
  IN       CALL_POINTS                       CallPoint,
  IN OUT   VOID                              **OrMask
  )
{
  UINT8   RegSizeInBytes;
  UINT8   SpecialCaseIndex;
  UINT8   *IntermediatePtr;
  UINT16  i;
  UINT32  Socket;
  UINT32  Module;
  UINT32  AndMask;
  ACCESS_WIDTH AccessWidth;
  AGESA_STATUS IgnoredSts;
  PCI_ADDR PciAddress;
  CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;

  GetSocketModuleOfNode ((UINT32) Device->Node,
                               &Socket,
                               &Module,
                               StdHeader);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  if (CallPoint == INIT_RESUME) {
    MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  } else {
    S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  }

  for (i = 0; i < RegisterHdr->NumRegisters; i++) {
    if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
        ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
      PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
      PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
      RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
      switch (RegSizeInBytes) {
      case 1:
        AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
        AccessWidth = AccessS3SaveWidth8;
        break;
      case 2:
        AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
        AccessWidth = AccessS3SaveWidth16;
        break;
      case 3:
        // In this case, we don't need to save a register. We just need to call a special
        // function to do certain things in the save and resume sequence.
        // This should not be used in a non-special case.
        AndMask = 0;
        RegSizeInBytes = 0;
        AccessWidth = 0;
        break;
      default:
        AndMask = RegisterHdr->RegisterList[i].AndMask;
        RegSizeInBytes = 4;
        AccessWidth = AccessS3SaveWidth32;
        break;
      }
      if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
        ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0));
        LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader);
      } else {
        SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
        RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader);
      }
      if (AndMask != 0) {
        // If AndMask is 0, then it is a not-care. Don't need to apply it to the OrMask
        **((UINT32 **) OrMask) &= AndMask;
      }
      if ((RegSizeInBytes == 0) && (**((UINT32 **) OrMask) == RESTART_FROM_BEGINNING_LIST)) {
        // Restart from the beginning of the register list
        i = 0xFFFF;
      }
      IntermediatePtr = (UINT8 *) *OrMask;
      *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes;
    }
  }
}
Beispiel #3
0
/**
 * Determines the maximum amount of space required to store all raw register
 * values for the given device list.
 *
 * This traverses the entire device list, and calculates the worst case size
 * of each device in the device list.
 *
 * @param[in]     DeviceList     Beginning of the device list.
 * @param[in]     CallPoint      Indicates whether this is AMD_INIT_RESUME or
 *                               AMD_S3LATE_RESTORE.
 * @param[in]     StdHeader      AMD standard header config param.
 *
 * @retval        Size in bytes required for storing all registers.
 */
UINT32
GetWorstCaseContextSize (
  IN       DEVICE_BLOCK_HEADER *DeviceList,
  IN       CALL_POINTS         CallPoint,
  IN       AMD_CONFIG_PARAMS   *StdHeader
  )
{
  UINT32 WorstCaseSize;
  DEVICE_DESCRIPTORS Device;
  UINT16 i;
  REGISTER_BLOCK_HEADERS RegisterHdr;

  WorstCaseSize = DeviceList->RelativeOrMaskOffset;
  Device.CommonDeviceHeader = (DEVICE_DESCRIPTOR *) &DeviceList[1];

  // Process Device List
  for (i = 0; i < DeviceList->NumDevices; i++) {
    switch (Device.CommonDeviceHeader->Type) {
    case DEV_TYPE_PCI_PRE_ESR:
      // PRE_ESR and post ESR take the same amount of space
    case DEV_TYPE_PCI:
      if (CallPoint == INIT_RESUME) {
        MemFS3GetPciDeviceRegisterList (Device.PciDevice, &RegisterHdr.PciRegisters, StdHeader);
      } else {
        S3GetPciDeviceRegisterList (Device.PciDevice, &RegisterHdr.PciRegisters, StdHeader);
      }
      WorstCaseSize += (RegisterHdr.PciRegisters->NumRegisters * 4);
      Device.PciDevice++;
      break;
    case DEV_TYPE_CPCI_PRE_ESR:
      // PRE_ESR and post ESR take the same amount of space
    case DEV_TYPE_CPCI:
      if (CallPoint == INIT_RESUME) {
        MemFS3GetCPciDeviceRegisterList (Device.CPciDevice, &RegisterHdr.CPciRegisters, StdHeader);
      } else {
        S3GetCPciDeviceRegisterList (Device.CPciDevice, &RegisterHdr.CPciRegisters, StdHeader);
      }
      WorstCaseSize += (RegisterHdr.CPciRegisters->NumRegisters * 4);
      Device.CPciDevice++;
      break;
    case DEV_TYPE_MSR_PRE_ESR:
      // PRE_ESR and post ESR take the same amount of space
    case DEV_TYPE_MSR:
      if (CallPoint == INIT_RESUME) {
        MemFS3GetMsrDeviceRegisterList (Device.MsrDevice, &RegisterHdr.MsrRegisters, StdHeader);
      } else {
        S3GetMsrDeviceRegisterList (Device.MsrDevice, &RegisterHdr.MsrRegisters, StdHeader);
      }
      WorstCaseSize += (RegisterHdr.MsrRegisters->NumRegisters * 8);
      Device.MsrDevice++;
      break;
    case DEV_TYPE_CMSR_PRE_ESR:
      // PRE_ESR and post ESR take the same amount of space
    case DEV_TYPE_CMSR:
      if (CallPoint == INIT_RESUME) {
        MemFS3GetCMsrDeviceRegisterList (Device.CMsrDevice, &RegisterHdr.CMsrRegisters, StdHeader);
      } else {
        S3GetCMsrDeviceRegisterList (Device.CMsrDevice, &RegisterHdr.CMsrRegisters, StdHeader);
      }
      WorstCaseSize += (RegisterHdr.CMsrRegisters->NumRegisters * 8);
      Device.CMsrDevice++;
      break;
    default:
      ASSERT (FALSE);
    }
  }
  return (WorstCaseSize);
}
Beispiel #4
0
/**
 * Restores the context of a 'conditional' PCI device.
 *
 * This traverses the provided register list restoring PCI registers when appropriate.
 *
 * @param[in]     StdHeader      AMD standard header config param.
 * @param[in]     Device         'conditional' PCI device to restore.
 * @param[in]     CallPoint      Indicates whether this is AMD_INIT_RESUME or
 *                               AMD_S3LATE_RESTORE.
 * @param[in,out] OrMask         Current buffer pointer of raw register values.
 *
 */
VOID
RestoreConditionalPciDevice (
  IN       AMD_CONFIG_PARAMS                 *StdHeader,
  IN       CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
  IN       CALL_POINTS                       CallPoint,
  IN OUT   VOID                              **OrMask
  )
{
  UINT8   RegSizeInBytes;
  UINT8   SpecialCaseIndex;
  UINT8   *IntermediatePtr;
  UINT16  i;
  UINT32  Socket;
  UINT32  Module;
  UINT32  RegValueRead;
  UINT32  RegValueWrite;
  UINT32  AndMask;
  ACCESS_WIDTH AccessWidth;
  AGESA_STATUS IgnoredSts;
  PCI_ADDR PciAddress;
  CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;

  GetSocketModuleOfNode ((UINT32) Device->Node,
                               &Socket,
                               &Module,
                               StdHeader);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  if (CallPoint == INIT_RESUME) {
    MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  } else {
    S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  }

  for (i = 0; i < RegisterHdr->NumRegisters; i++) {
    if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
        ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
      PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
      PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
      RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
      switch (RegSizeInBytes) {
      case 1:
        AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
        RegValueWrite = **(UINT8 **)OrMask;
        AccessWidth = AccessS3SaveWidth8;
        break;
      case 2:
        AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
        RegValueWrite = **(UINT16 **)OrMask;
        AccessWidth = AccessS3SaveWidth16;
        break;
      default:
        AndMask = RegisterHdr->RegisterList[i].AndMask;
        RegSizeInBytes = 4;
        RegValueWrite = **(UINT32 **)OrMask;
        AccessWidth = AccessS3SaveWidth32;
        break;
      }
      if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
        LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader);
        RegValueWrite |= RegValueRead & (~AndMask);
        LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader);
      } else {
        SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
        RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth,
                                             PciAddress,
                                             &RegValueRead,
                                             StdHeader);
        RegValueWrite |= RegValueRead & (~AndMask);
        RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth,
                                               PciAddress,
                                               &RegValueWrite,
                                               StdHeader);
      }
      IntermediatePtr = (UINT8 *) *OrMask;
      *OrMask = &IntermediatePtr[RegSizeInBytes];
    }
  }
}