/** 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); }
/** 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 (); } }