mirror of https://github.com/lianthony/NT4.0
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.
359 lines
9.0 KiB
359 lines
9.0 KiB
//#pragma comment(exestr, "$Header: /usr4/winnt/SOURCES/halpcims/src/hal/halsnipm/mips/RCS/jxtime.c,v 1.2 1995/11/02 11:04:33 flo Exp $")
|
|
|
|
/*++
|
|
|
|
Copyright (c) 1993 SNI
|
|
|
|
Module Name:
|
|
|
|
SNItime.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the HAL set/query realtime clock routines for
|
|
a MIPS R4000 SNI system.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
|
|
|
|
#define NVINDEX_STATE 0x6
|
|
#define NVSTATE_TODVALID 0x1
|
|
|
|
|
|
|
|
#define bcd_to_dec(x) ( ((((x) >> 4 ) & 0xf ) * 10 ) + ((x) & 0xf) )
|
|
#define dec_to_bcd(x) ( (((x) / 10) << 4) | ((x) % 10) )
|
|
|
|
|
|
#define RTC_NVRAM_SIZE 0x7ff // NVRAM size on this chip
|
|
|
|
// definitions for rtc 146818
|
|
|
|
#define RTC_SECS 0
|
|
#define RTC_SECA 1
|
|
#define RTC_MINS 2
|
|
#define RTC_MINA 3
|
|
#define RTC_HOURS 4
|
|
#define RTC_HOURA 5
|
|
#define RTC_DAYW 6
|
|
#define RTC_DAYM 7
|
|
#define RTC_MONTH 8
|
|
#define RTC_YEAR 9
|
|
#define RTC_REGA 10
|
|
#define RTC_REGB 11
|
|
#define RTC_REGC 12
|
|
#define RTC_REGD 13
|
|
#define RTC_MEM1 14
|
|
#define RTC_MEM2 128
|
|
|
|
/*
|
|
* Register B bit definitions
|
|
*/
|
|
#define RTCB_SET 0x80 /* inhibit date update */
|
|
#define RTCB_PIE 0x40 /* enable periodic interrupt */
|
|
#define RTCB_AIE 0x20 /* enable alarm interrupt */
|
|
#define RTCB_UIE 0x10 /* enable update-ended interrupt */
|
|
#define RTCB_SQWE 0x08 /* square wave enable */
|
|
#define RTCB_DMBINARY 0x04 /* binary data (0 => bcd data) */
|
|
#define RTCB_24HR 0x02 /* 24 hour mode (0 => 12 hour) */
|
|
#define RTCB_DSE 0x01 /* daylight savings mode enable */
|
|
|
|
/* Time of Day Clock */
|
|
|
|
struct todc {
|
|
short htenths;
|
|
short hsecs;
|
|
short hmins;
|
|
short hhours;
|
|
short hdays;
|
|
short hweekday;
|
|
short hmonth;
|
|
short hyear;
|
|
};
|
|
|
|
/* masks to get valid information */
|
|
|
|
#define MASK_CENT_SECS 0xFF
|
|
#define MASK_SECS 0x7F
|
|
#define MASK_MINS 0x7F
|
|
#define MASK_HOURS 0x3F
|
|
#define MASK_DAY_W 0x07
|
|
#define MASK_DAY_M 0x3F
|
|
#define MASK_MONTH 0x1F
|
|
#define MASK_YEAR 0xFF
|
|
|
|
//
|
|
// the reference year (we have only two digits for the year on the chip)
|
|
//
|
|
|
|
#define YRREF 1900
|
|
|
|
|
|
|
|
//
|
|
// Define forward referenced procedure prototypes.
|
|
//
|
|
|
|
BOOLEAN
|
|
HalQueryRealTimeClock (
|
|
OUT PTIME_FIELDS TimeFields
|
|
);
|
|
|
|
BOOLEAN
|
|
HalSetRealTimeClock (
|
|
IN PTIME_FIELDS TimeFields
|
|
);
|
|
|
|
VOID
|
|
HalpWrite146818(struct todc *todp, PUCHAR index, PUCHAR data);
|
|
|
|
VOID
|
|
HalpRead146818(struct todc *todp, PUCHAR index, PUCHAR data);
|
|
|
|
VOID
|
|
HalpPciReadTodc(struct todc *todp);
|
|
|
|
VOID
|
|
HalpPciWriteTodc(struct todc *todp);
|
|
|
|
UCHAR
|
|
HalpReadRegister146818(PUCHAR index, PUCHAR data, int reg);
|
|
|
|
VOID HalpWriteRegister146818(PUCHAR index, PUCHAR data, int reg, UCHAR val);
|
|
|
|
|
|
|
|
/* Calendar clock : For PCI Minitower and Desktop systems, the RTC is part of
|
|
* --------------- the SUPER_IO pc87323.
|
|
* It is software compatible with rtc146818.
|
|
*/
|
|
|
|
BOOLEAN
|
|
HalQueryRealTimeClock (
|
|
OUT PTIME_FIELDS TimeFields
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine queries the realtime clock.
|
|
|
|
N.B. this comment stand in jxtime.c:
|
|
This routine is required to provide any synchronization necessary
|
|
to query the realtime clock information.
|
|
|
|
Arguments:
|
|
|
|
TimeFields - Supplies a pointer to a time structure that receives
|
|
the realtime clock information.
|
|
|
|
Return Value:
|
|
|
|
If the power to the realtime clock has not failed, then the time
|
|
values are read from the realtime clock and a value of TRUE is
|
|
returned. Otherwise, a value of FALSE is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
register CSHORT month, dayweek, daymonth, year, hours, mins, secs, msecs;
|
|
struct todc ltodc;
|
|
KIRQL oldIrql;
|
|
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
|
|
|
|
HalpPciReadTodc(<odc);
|
|
|
|
KeLowerIrql(oldIrql);
|
|
|
|
msecs = 0;
|
|
secs = ltodc.hsecs;
|
|
mins = ltodc.hmins;
|
|
hours = ltodc.hhours;
|
|
daymonth = ltodc.hdays;
|
|
dayweek = ltodc.hweekday;
|
|
month = ltodc.hmonth;
|
|
year = ltodc.hyear;
|
|
|
|
|
|
if (TimeFields)
|
|
{
|
|
TimeFields->Year = year+YRREF;
|
|
TimeFields->Month = month;
|
|
TimeFields->Day = daymonth;
|
|
TimeFields->Weekday = dayweek;
|
|
TimeFields->Hour = hours;
|
|
TimeFields->Minute = mins;
|
|
TimeFields->Second = secs;
|
|
TimeFields->Milliseconds = msecs;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
BOOLEAN
|
|
HalSetRealTimeClock (
|
|
IN PTIME_FIELDS TimeFields
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine sets the realtime clock.
|
|
|
|
N.B. this comment stand in jxtime.c:
|
|
This routine is required to provide anq synchronization necessary
|
|
to set the realtime clock information.
|
|
|
|
Arguments:
|
|
|
|
TimeFields - Supplies a pointer to a time structure that specifies the
|
|
realtime clock information.
|
|
|
|
Return Value:
|
|
|
|
If the power to the realtime clock has not failed, then the time
|
|
values are written to the realtime clock and a value of TRUE is
|
|
returned. Otherwise, a value of FALSE is returned.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
struct todc ltodc;
|
|
|
|
KIRQL oldIrql;
|
|
UCHAR year, month, daymonth, dayweek, hours, mins, secs, msecs;
|
|
|
|
//
|
|
// If the realtime clock battery is still functioning, then write
|
|
// the realtime clock values, and return a function value of TRUE.
|
|
// Otherwise, return a function value of FALSE.
|
|
//
|
|
|
|
// this part has to be written
|
|
// if (...) return FALSE;
|
|
year = (UCHAR) ( (TimeFields->Year - YRREF) % 100 );
|
|
month = (UCHAR) TimeFields->Month;
|
|
daymonth = (UCHAR) TimeFields->Day;
|
|
dayweek = (UCHAR) TimeFields->Weekday;
|
|
hours = (UCHAR) TimeFields->Hour;
|
|
mins = (UCHAR) TimeFields->Minute;
|
|
secs = (UCHAR) TimeFields->Second;
|
|
msecs = (UCHAR) TimeFields->Milliseconds;
|
|
|
|
|
|
ltodc.htenths = 0;
|
|
ltodc.hsecs = secs;
|
|
ltodc.hmins = mins;
|
|
ltodc.hhours = hours;
|
|
ltodc.hdays = daymonth;
|
|
ltodc.hweekday = dayweek;
|
|
ltodc.hmonth = month;
|
|
ltodc.hyear = year;
|
|
|
|
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
|
|
|
|
HalpPciWriteTodc(<odc);
|
|
|
|
KeLowerIrql(oldIrql);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
/* HAL_RTODC() */
|
|
VOID
|
|
HalpPciReadTodc(struct todc *todp)
|
|
{
|
|
PUCHAR rtc_index = (PUCHAR) RTC_ADDR_PCIMT;
|
|
PUCHAR rtc_data = (PUCHAR) RTC_DATA_PCIMT;
|
|
HalpRead146818(todp,rtc_index,rtc_data);
|
|
}
|
|
|
|
/* HAL_WTODC() */
|
|
VOID
|
|
HalpPciWriteTodc(struct todc *todp)
|
|
{
|
|
|
|
PUCHAR rtc_index = (PUCHAR) RTC_ADDR_PCIMT;
|
|
PUCHAR rtc_data = (PUCHAR)RTC_DATA_PCIMT;
|
|
HalpWrite146818(todp, rtc_index, rtc_data);
|
|
}
|
|
|
|
|
|
VOID
|
|
HalpWrite146818(struct todc *todp, PUCHAR index, PUCHAR data)
|
|
{
|
|
UCHAR temp;
|
|
/*
|
|
* Write information to rtc146818 chip
|
|
*/
|
|
HalpWriteRegister146818(index,data,RTC_REGB,temp=(HalpReadRegister146818(index,data,RTC_REGB)|RTCB_SET));
|
|
HalpWriteRegister146818(index,data,RTC_SECS,dec_to_bcd(todp->hsecs)&MASK_SECS);
|
|
HalpWriteRegister146818(index,data,RTC_MINS,dec_to_bcd(todp->hmins)&MASK_MINS);
|
|
HalpWriteRegister146818(index,data,RTC_HOURS,dec_to_bcd(todp->hhours)&MASK_HOURS);
|
|
HalpWriteRegister146818(index,data,RTC_DAYM,dec_to_bcd(todp->hdays)&MASK_DAY_M);
|
|
HalpWriteRegister146818(index,data,RTC_DAYW,dec_to_bcd(todp->hweekday)&MASK_DAY_W);
|
|
HalpWriteRegister146818(index,data,RTC_MONTH,dec_to_bcd(todp->hmonth)&MASK_MONTH);
|
|
|
|
HalpWriteRegister146818(index,data,RTC_YEAR,dec_to_bcd(todp->hyear)&MASK_YEAR);
|
|
|
|
|
|
|
|
HalpWriteRegister146818(index,data,RTC_REGB, temp &= ~RTCB_SET);
|
|
}
|
|
|
|
VOID
|
|
HalpRead146818(struct todc *todp, PUCHAR index, PUCHAR data)
|
|
{
|
|
UCHAR temp;
|
|
|
|
HalpWriteRegister146818(index,data,RTC_REGB,temp=(HalpReadRegister146818(index,data,RTC_REGB)|RTCB_SET));
|
|
|
|
todp->htenths = 0;
|
|
todp->hsecs=bcd_to_dec(HalpReadRegister146818(index,data,RTC_SECS)&MASK_SECS);
|
|
todp->hmins=bcd_to_dec(HalpReadRegister146818(index,data,RTC_MINS)&MASK_MINS);
|
|
todp->hhours=bcd_to_dec(HalpReadRegister146818(index,data,RTC_HOURS)&MASK_HOURS);
|
|
todp->hdays=bcd_to_dec(HalpReadRegister146818(index,data,RTC_DAYM)&MASK_DAY_M);
|
|
todp->hweekday=bcd_to_dec(HalpReadRegister146818(index,data,RTC_DAYW)&MASK_DAY_W);
|
|
todp->hmonth=bcd_to_dec(HalpReadRegister146818(index,data,RTC_MONTH)&MASK_MONTH);
|
|
todp->hyear=bcd_to_dec(HalpReadRegister146818(index,data,RTC_YEAR)&MASK_YEAR);
|
|
|
|
HalpWriteRegister146818(index,data,RTC_REGB, temp &= ~RTCB_SET);
|
|
}
|
|
|
|
|
|
|
|
UCHAR
|
|
HalpReadRegister146818(PUCHAR index, PUCHAR data, int reg)
|
|
{
|
|
WRITE_REGISTER_UCHAR(index,reg);
|
|
// *index = reg;
|
|
// wbflush();
|
|
// return(*data)
|
|
return(READ_REGISTER_UCHAR(data));
|
|
}
|
|
|
|
VOID HalpWriteRegister146818(PUCHAR index, PUCHAR data, int reg, UCHAR val)
|
|
{
|
|
WRITE_REGISTER_UCHAR(index,reg);
|
|
// *index = reg;
|
|
// wbflush();
|
|
WRITE_REGISTER_UCHAR(data, val);
|
|
// *data = val;
|
|
// wbflush();
|
|
}
|
|
|