Exemplo n.º 1
0
/**
  Retrieves the current CPU interrupt state.

  Retrieves the current CPU interrupt state. Returns TRUE is interrupts are
  currently enabled. Otherwise returns FALSE.

  @retval TRUE  CPU interrupts are enabled.
  @retval FALSE CPU interrupts are disabled.

**/
BOOLEAN
EFIAPI
GlueGetInterruptState (
  VOID
  )
{
  IA32_EFLAGS32                     EFlags;

  EFlags.UintN = AsmReadEflags ();
  return (BOOLEAN)(EFlags.Bits.IF == 1);
}
Exemplo n.º 2
0
/**
  Calling this function causes the system to enter a power state for capsule
  update.

  Reset update should not return, if it returns, it means the system does
  not support capsule update.

**/
VOID
EFIAPI
EnterS3WithImmediateWake (
VOID
)
{
  UINT8     Data8;
  UINT16    Data16;
  UINT32    Data32;
  UINTN     Eflags;
  UINTN     RegCr0;
  EFI_TIME  EfiTime;
  UINT32    SmiEnSave;

  Eflags  = AsmReadEflags ();
  if ( (Eflags & 0x200) ) {
     DisableInterrupts ();
  }

  //
  //  Write all cache data to memory because processor will lost power
  //
  AsmWbinvd();
  RegCr0 = AsmReadCr0();
  AsmWriteCr0 (RegCr0 | 0x060000000);

  SmiEnSave = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, (SmiEnSave & ~SMI_EN));

  //
  // Pogram RTC alarm for immediate WAKE
  //

  //
  // Disable SMI sources
  //
  IoWrite16 (PcdGet16 (PcdGpe0blkIoBaseAddress) + R_QNC_GPE0BLK_SMIE, 0);

  //
  // Disable RTC alarm interrupt
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, (Data8 & ~BIT5));

  //
  // Clear RTC alarm if already set
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);              // Read clears alarm status

  //
  // Disable all WAKE events
  //
  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, B_QNC_PM1BLK_PM1E_PWAKED);

  //
  // Clear all WAKE status bits
  //
  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S, B_QNC_PM1BLK_PM1S_ALL);

  //
  // Avoid RTC rollover
  //
  do {
    WaitForRTCUpdate();
    IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS);
    EfiTime.Second = IoRead8 (PCAT_RTC_DATA_REGISTER);
  } while (EfiTime.Second > PLATFORM_RTC_ROLLOVER_LIMIT);

  //
  // Read RTC time
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOURS);
  EfiTime.Hour = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTES);
  EfiTime.Minute = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS);
  EfiTime.Second = IoRead8 (PCAT_RTC_DATA_REGISTER);

  //
  // Set RTC alarm
  //

  //
  // Add PLATFORM_WAKE_SECONDS_BUFFER to current EfiTime.Second
  // The maths is to allow for the fact we are adding to a BCD number and require the answer to be BCD (EfiTime.Second)
  //
  if ((BCD_BASE - (EfiTime.Second & 0x0F)) <= PLATFORM_WAKE_SECONDS_BUFFER) {
    Data8 = (((EfiTime.Second & 0xF0) + 0x10) + (PLATFORM_WAKE_SECONDS_BUFFER - (BCD_BASE - (EfiTime.Second & 0x0F))));
  } else {
    Data8 = EfiTime.Second + PLATFORM_WAKE_SECONDS_BUFFER;
  }

  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOURS_ALARM);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, EfiTime.Hour);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTES_ALARM);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, EfiTime.Minute);
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECONDS_ALARM);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, Data8);

  //
  // Enable RTC alarm interrupt
  //
  IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
  Data8 = IoRead8 (PCAT_RTC_DATA_REGISTER);
  IoWrite8 (PCAT_RTC_DATA_REGISTER, (Data8 | BIT5));

  //
  // Enable RTC alarm as WAKE event
  //
  Data16 = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E);
  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, (Data16 | B_QNC_PM1BLK_PM1E_RTC));

  //
  // Enter S3
  //
  Data32 = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
  Data32  = (UINT32) ((Data32 & 0xffffc3fe) | V_S3 | B_QNC_PM1BLK_PM1C_SCIEN);
  IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Data32);
  Data32 = Data32 | B_QNC_PM1BLK_PM1C_SLPEN;
  IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Data32);

  //
  // Enable Interrupt if it's enabled before
  //
  if ( (Eflags & 0x200) ) {
     EnableInterrupts ();
  }
}