From EDKII, It is simple but useful. If your BIOS vendor not provide the items in setup menu, you may give it a try.
1. Check your RTC_EN at PCH.
2. Refer to http://stanislavs.org/helppc/cmos_ram.html, set your alarm time, don't forget to set update enable/disable and AIE bit.
That's all, EDKII sample code as below
LibSetWakeupTime (
IN BOOLEAN Enabled,
OUT EFI_TIME *Time
)
{
EFI_STATUS Status;
EFI_TIME RtcTime;
RTC_REGISTER_B RegisterB;
UINT8 Century;
EFI_TIME_CAPABILITIES Capabilities;
if (Enabled) {
if (Time == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Make sure that the time fields are valid
//
Status = RtcTimeFieldsValid (Time);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
}
//
// Just support set alarm time within 24 hours
//
LibGetTime (&RtcTime, &Capabilities);
if (Time->Year != RtcTime.Year ||
Time->Month != RtcTime.Month ||
(Time->Day != RtcTime.Day && Time->Day != (RtcTime.Day + 1))
) {
return EFI_UNSUPPORTED;
}
//
// Make a local copy of the time and date
//
CopyMem (&RtcTime, Time, sizeof (EFI_TIME));
}
//
// Acquire RTC Lock to make access to RTC atomic
//
EfiAcquireLock (&mRtc.RtcLock);
//
// Wait for up to 0.1 seconds for the RTC to be updated
//
Status = RtcWaitToUpdate (100000);
if (EFI_ERROR (Status)) {
EfiReleaseLock (&mRtc.RtcLock);
return EFI_DEVICE_ERROR;
}
//
// Read Register B, and inhibit updates of the RTC
//
RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);
RegisterB.Bits.SET = 1;
RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
if (Enabled) {
ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);
//
// Set RTC alarm time
//
RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);
RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);
RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);
RegisterB.Bits.AIE = 1;
} else {
RegisterB.Bits.AIE = 0;
}
//
// Allow updates of the RTC registers
//
RegisterB.Bits.SET = 0;
RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
//
// Release RTC Lock.
//
EfiReleaseLock (&mRtc.RtcLock);
return EFI_SUCCESS;
}