You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
3.9 KiB
216 lines
3.9 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pmrtc.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the code for ACPI-related RTC functions.
|
|
|
|
Author:
|
|
|
|
Jake Oshins (jakeo) March 28, 1997
|
|
|
|
Environment:
|
|
|
|
Kernel mode only.
|
|
|
|
Revision History:
|
|
|
|
Split from pmclock.asm due to PIIX4 bugs.
|
|
|
|
Forrest Foltz (forrestf) 24-Oct-2000
|
|
Ported from pmrtc.asm to pmrtc.c
|
|
|
|
--*/
|
|
|
|
#include <halp.h>
|
|
#include <acpitabl.h>
|
|
#include <xxacpi.h>
|
|
#include "io_cmos.h"
|
|
|
|
VOID
|
|
HalpInitializeCmos (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
This routine reads CMOS and initializes globals required for CMOS access,
|
|
such as the location of the century byte.
|
|
|
|
Arguments
|
|
|
|
None
|
|
|
|
Return Value
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR centuryAlarmIndex;
|
|
|
|
//
|
|
// If the century byte is filled in, use it... otherwise assume
|
|
// a default value.
|
|
//
|
|
|
|
centuryAlarmIndex = HalpFixedAcpiDescTable.century_alarm_index;
|
|
if (centuryAlarmIndex == 0) {
|
|
centuryAlarmIndex = RTC_OFFSET_CENTURY;
|
|
}
|
|
|
|
HalpCmosCenturyOffset = centuryAlarmIndex;
|
|
}
|
|
|
|
NTSTATUS
|
|
HalpSetWakeAlarm (
|
|
IN ULONG64 WakeSystemTime,
|
|
IN PTIME_FIELDS WakeTimeFields
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the real-time clock's alarm to go
|
|
off at a specified time in the future and programs
|
|
the ACPI chipset so that this wakes the computer.
|
|
|
|
Arguments:
|
|
|
|
WakeSystemTime - amount of time that passes before we wake
|
|
WakeTimeFields - time to wake broken down into TIME_FIELDS
|
|
|
|
Return Value:
|
|
|
|
status
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR alarmPort;
|
|
UCHAR value;
|
|
|
|
HalpAcquireCmosSpinLockAndWait();
|
|
|
|
CMOS_WRITE_BCD(RTC_OFFSET_SECOND_ALARM,(UCHAR)WakeTimeFields->Second);
|
|
CMOS_WRITE_BCD(RTC_OFFSET_MINUTE_ALARM,(UCHAR)WakeTimeFields->Minute);
|
|
CMOS_WRITE_BCD(RTC_OFFSET_HOUR_ALARM,(UCHAR)WakeTimeFields->Hour);
|
|
|
|
alarmPort = HalpFixedAcpiDescTable.day_alarm_index;
|
|
if (alarmPort != 0) {
|
|
|
|
CMOS_WRITE_BCD(alarmPort,(UCHAR)WakeTimeFields->Day);
|
|
alarmPort = HalpFixedAcpiDescTable.month_alarm_index;
|
|
if (alarmPort != 0) {
|
|
CMOS_WRITE_BCD(alarmPort,(UCHAR)WakeTimeFields->Month);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enable the alarm. Be sure to preserve the daylight savings time
|
|
// bit.
|
|
//
|
|
|
|
value = CMOS_READ(CMOS_STATUS_B);
|
|
value &= REGISTER_B_DAYLIGHT_SAVINGS_TIME;
|
|
value |= REGISTER_B_ENABLE_ALARM_INTERRUPT | REGISTER_B_24HOUR_MODE;
|
|
|
|
CMOS_WRITE(CMOS_STATUS_B,value);
|
|
CMOS_READ(CMOS_STATUS_C);
|
|
CMOS_READ(CMOS_STATUS_D);
|
|
|
|
HalpReleaseCmosSpinLock();
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
HalpSetClockBeforeSleep (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the RTC such that it will not generate
|
|
periodic interrupts while the machine is sleeping, as this
|
|
could be interpretted as an RTC wakeup event.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR value;
|
|
|
|
HalpAcquireCmosSpinLock();
|
|
|
|
HalpRtcRegA = CMOS_READ(CMOS_STATUS_A);
|
|
HalpRtcRegB = CMOS_READ(CMOS_STATUS_B);
|
|
|
|
value = HalpRtcRegB & ~REGISTER_B_ENABLE_PERIODIC_INTERRUPT;
|
|
value |= REGISTER_B_24HOUR_MODE;
|
|
CMOS_WRITE(CMOS_STATUS_B,value);
|
|
|
|
CMOS_READ(CMOS_STATUS_C);
|
|
CMOS_READ(CMOS_STATUS_D);
|
|
|
|
HalpReleaseCmosSpinLock();
|
|
}
|
|
|
|
VOID
|
|
HalpSetClockAfterSleep (
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the RTC back to the way it was
|
|
before a call to HalpSetClockBeforeSleep.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR value;
|
|
|
|
HalpAcquireCmosSpinLock();
|
|
|
|
CMOS_WRITE(CMOS_STATUS_A,HalpRtcRegA);
|
|
|
|
value = HalpRtcRegB;
|
|
value &= ~REGISTER_B_ENABLE_ALARM_INTERRUPT;
|
|
value |= REGISTER_B_24HOUR_MODE;
|
|
CMOS_WRITE(CMOS_STATUS_B,value);
|
|
|
|
CMOS_READ(CMOS_STATUS_C);
|
|
CMOS_READ(CMOS_STATUS_D);
|
|
|
|
HalpReleaseCmosSpinLock();
|
|
}
|
|
|
|
|
|
|
|
|
|
|