Use <dev/ic/mc146818.h>. Change systemclock settings. Usable values for
HZ are now 48/64/96. This reduces the interrupt overhead, because we don't need the extra division by 4 in the interrupt handler.
This commit is contained in:
parent
04246ac4f8
commit
d66ffa3fe1
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clock.c,v 1.2 1995/05/05 16:31:46 leo Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.3 1995/05/28 19:38:49 leo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -105,18 +105,17 @@ struct device *pdp, *dp;
|
|||
void *auxp;
|
||||
{
|
||||
/*
|
||||
* Initialize Timer-A in the ST-MFP. An exact reduce to HZ is not
|
||||
* possible by hardware. We use a divisor of 64 and reduce by software
|
||||
* with a factor of 4. The MFP clock runs at 2457600Hz. Therefore the
|
||||
* timer runs at an effective rate of: 2457600/(64*4) = 9600Hz. The
|
||||
* following expression works for all 'normal' values of hz.
|
||||
* Initialize Timer-A in the ST-MFP. We use a divisor of 200.
|
||||
* The MFP clock runs at 2457600Hz. Therefore the timer runs
|
||||
* at an effective rate of: 2457600/200 = 12288Hz. The
|
||||
* following expression works for 48, 64 or 96 hz.
|
||||
*/
|
||||
divisor = 9600/hz;
|
||||
divisor = 12288/hz;
|
||||
MFP->mf_tacr = 0; /* Stop timer */
|
||||
MFP->mf_iera &= ~IA_TIMA; /* Disable timer interrupts */
|
||||
MFP->mf_tadr = divisor; /* Set divisor */
|
||||
|
||||
printf(": system hz %d timer-A divisor %d\n", hz, divisor);
|
||||
printf(": system hz %d timer-A divisor 200/%d\n", hz, divisor);
|
||||
|
||||
/*
|
||||
* Initialize Timer-B in the ST-MFP. This timer is used by the 'delay'
|
||||
|
@ -132,7 +131,7 @@ void *auxp;
|
|||
|
||||
void cpu_initclocks()
|
||||
{
|
||||
MFP->mf_tacr = T_Q064; /* Start timer */
|
||||
MFP->mf_tacr = T_Q200; /* Start timer */
|
||||
MFP->mf_ipra &= ~IA_TIMA; /* Clear pending interrupts */
|
||||
MFP->mf_iera |= IA_TIMA; /* Enable timer interrupts */
|
||||
MFP->mf_imra |= IA_TIMA; /* ..... */
|
||||
|
@ -149,12 +148,9 @@ setstatclockrate(hz)
|
|||
*/
|
||||
clkread()
|
||||
{
|
||||
extern short clk_div;
|
||||
u_int delta, elapsed;
|
||||
|
||||
elapsed = (divisor - MFP->mf_tadr) + ((4 - clk_div) * divisor);
|
||||
delta = (elapsed * tick) / (divisor << 2);
|
||||
|
||||
u_int delta;
|
||||
|
||||
delta = ((divisor - MFP->mf_tadr) * tick) / divisor;
|
||||
/*
|
||||
* Account for pending clock interrupts
|
||||
*/
|
||||
|
@ -377,68 +373,41 @@ static char ldmsize[12] =
|
|||
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
static __inline__ int rtc_getclkreg(regno)
|
||||
int regno;
|
||||
{
|
||||
RTC->rtc_regno = RTC_REGA;
|
||||
RTC->rtc_regno = regno;
|
||||
return(RTC->rtc_data & 0377);
|
||||
}
|
||||
|
||||
static __inline__ void rtc_setclkreg(regno, value)
|
||||
int regno, value;
|
||||
{
|
||||
RTC->rtc_regno = regno;
|
||||
RTC->rtc_data = value;
|
||||
}
|
||||
|
||||
static u_long
|
||||
gettod()
|
||||
{
|
||||
int i, year, mon, day, hour, min, sec;
|
||||
u_long new_time = 0;
|
||||
char *msize;
|
||||
int i, sps;
|
||||
u_long new_time = 0;
|
||||
char *msize;
|
||||
mc_todregs clkregs;
|
||||
|
||||
/*
|
||||
* Hold clock
|
||||
*/
|
||||
rtc_setclkreg(RTC_REGB, rtc_getclkreg(RTC_REGB) | RTC_B_SET);
|
||||
sps = splhigh();
|
||||
MC146818_GETTOD(RTC, &clkregs);
|
||||
splx(sps);
|
||||
|
||||
/*
|
||||
* Read clock
|
||||
*/
|
||||
sec = rtc_getclkreg(RTC_SEC);
|
||||
min = rtc_getclkreg(RTC_MIN);
|
||||
hour = rtc_getclkreg(RTC_HOUR);
|
||||
day = rtc_getclkreg(RTC_DAY) - 1;
|
||||
mon = rtc_getclkreg(RTC_MONTH) - 1;
|
||||
year = rtc_getclkreg(RTC_YEAR) + STARTOFTIME;
|
||||
|
||||
/*
|
||||
* Let it run again..
|
||||
*/
|
||||
rtc_setclkreg(RTC_REGB, rtc_getclkreg(RTC_REGB) & ~RTC_B_SET);
|
||||
|
||||
if(range_test(hour, 0, 23))
|
||||
if(range_test(clkregs[MC_HOUR], 0, 23))
|
||||
return(0);
|
||||
if(range_test(day, 0, 30))
|
||||
if(range_test(clkregs[MC_DOM], 1, 31))
|
||||
return(0);
|
||||
if (range_test(mon, 0, 11))
|
||||
if (range_test(clkregs[MC_MONTH], 1, 12))
|
||||
return(0);
|
||||
if(range_test(year, STARTOFTIME, 2000))
|
||||
if(range_test(clkregs[MC_YEAR], 0, 2000 - GEMSTARTOFTIME))
|
||||
return(0);
|
||||
clkregs[MC_YEAR] += GEMSTARTOFTIME;
|
||||
|
||||
for(i = STARTOFTIME; i < year; i++) {
|
||||
for(i = BSDSTARTOFTIME; i < clkregs[MC_YEAR]; i++) {
|
||||
if(is_leap(i))
|
||||
new_time += 366;
|
||||
else new_time += 365;
|
||||
}
|
||||
|
||||
msize = is_leap(year) ? ldmsize : dmsize;
|
||||
for(i = 0; i < mon; i++)
|
||||
msize = is_leap(clkregs[MC_YEAR]) ? ldmsize : dmsize;
|
||||
for(i = 0; i < (clkregs[MC_MONTH] - 1); i++)
|
||||
new_time += msize[i];
|
||||
new_time += day;
|
||||
return((new_time * SECS_DAY) + (hour * 3600) + (min * 60) + sec);
|
||||
new_time += clkregs[MC_DOM] - 1;
|
||||
new_time *= SECS_DAY;
|
||||
new_time += (clkregs[MC_HOUR] * 3600) + (clkregs[MC_MIN] * 60);
|
||||
return(new_time + clkregs[MC_SEC]);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -447,9 +416,10 @@ u_long newtime;
|
|||
{
|
||||
register long days, rem, year;
|
||||
register char *ml;
|
||||
int sec, min, hour, month;
|
||||
int sps, sec, min, hour, month;
|
||||
mc_todregs clkregs;
|
||||
|
||||
/* Number of days since Jan. 1 1970 */
|
||||
/* Number of days since Jan. 1 'BSDSTARTOFTIME' */
|
||||
days = newtime / SECS_DAY;
|
||||
rem = newtime % SECS_DAY;
|
||||
|
||||
|
@ -464,14 +434,10 @@ u_long newtime;
|
|||
/*
|
||||
* Figure out the year. Day in year is left in 'days'.
|
||||
*/
|
||||
year = STARTOFTIME;
|
||||
year = BSDSTARTOFTIME;
|
||||
while(days >= (rem = is_leap(year) ? 366 : 365)) {
|
||||
++year;
|
||||
days -= rem;
|
||||
}
|
||||
while(days < 0) {
|
||||
--year;
|
||||
days += is_leap(year) ? 366 : 365;
|
||||
++year;
|
||||
days -= rem;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -484,16 +450,18 @@ u_long newtime;
|
|||
/*
|
||||
* Now that everything is calculated, program the RTC
|
||||
*/
|
||||
rtc_setclkreg(RTC_REGB, RTC_B_SET);
|
||||
rtc_setclkreg(RTC_REGA, RTC_A_DV1|RTC_A_RS2|RTC_A_RS3);
|
||||
rtc_setclkreg(RTC_REGB, RTC_B_SET|RTC_B_SQWE|RTC_B_DM|RTC_B_24_12);
|
||||
rtc_setclkreg(RTC_SEC, sec);
|
||||
rtc_setclkreg(RTC_MIN, min);
|
||||
rtc_setclkreg(RTC_HOUR, hour);
|
||||
rtc_setclkreg(RTC_DAY, days+1);
|
||||
rtc_setclkreg(RTC_MONTH, month+1);
|
||||
rtc_setclkreg(RTC_YEAR, year-1970);
|
||||
rtc_setclkreg(RTC_REGB, RTC_B_SQWE|RTC_B_DM|RTC_B_24_12);
|
||||
mc146818_write(RTC, MC_REGA, MC_BASE_32_KHz);
|
||||
mc146818_write(RTC, MC_REGB, MC_REGB_24HR | MC_REGB_BINARY);
|
||||
sps = splhigh();
|
||||
MC146818_GETTOD(RTC, &clkregs);
|
||||
clkregs[MC_SEC] = sec;
|
||||
clkregs[MC_MIN] = min;
|
||||
clkregs[MC_HOUR] = hour;
|
||||
clkregs[MC_DOM] = days+1;
|
||||
clkregs[MC_MONTH] = month+1;
|
||||
clkregs[MC_YEAR] = year - GEMSTARTOFTIME;
|
||||
MC146818_PUTTOD(RTC, &clkregs);
|
||||
splx(sps);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clockreg.h,v 1.1.1.1 1995/03/26 07:12:15 leo Exp $ */
|
||||
/* $NetBSD: clockreg.h,v 1.2 1995/05/28 19:38:51 leo Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Leo Weppelman.
|
||||
|
@ -47,61 +47,25 @@ struct rtc {
|
|||
#define rtc_data rtc_dat[3] /* data register */
|
||||
|
||||
/*
|
||||
* Register number definitions
|
||||
* Pull in general mc146818 definitions
|
||||
*/
|
||||
#define RTC_SEC 0
|
||||
#define RTC_ASEC 1
|
||||
#define RTC_MIN 2
|
||||
#define RTC_A_MIN 3
|
||||
#define RTC_HOUR 4
|
||||
#define RTC_A_HOUR 5
|
||||
#define RTC_WDAY 6
|
||||
#define RTC_DAY 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_RAMBOT 14 /* Reg. offset of nv-RAM */
|
||||
#define RTC_RAMSIZ 50 /* #bytes of nv-RAM available */
|
||||
#include <dev/ic/mc146818.h>
|
||||
|
||||
/*
|
||||
* Define fields for register A
|
||||
*/
|
||||
#define RTC_A_UIP 0x80 /* Update In Progress */
|
||||
#define RTC_A_DV2 0x40 /* Divider select */
|
||||
#define RTC_A_DV1 0x20 /* Divider select */
|
||||
#define RTC_A_DV0 0x10 /* Divider select */
|
||||
#define RTC_A_RS3 0x08 /* Rate Select */
|
||||
#define RTC_A_RS2 0x04 /* Rate Select */
|
||||
#define RTC_A_RS1 0x02 /* Rate Select */
|
||||
#define RTC_A_RS0 0x01 /* Rate Select */
|
||||
__inline__ u_int mc146818_read(rtc, regno)
|
||||
void *rtc;
|
||||
u_int regno;
|
||||
{
|
||||
((struct rtc *)rtc)->rtc_regno = regno;
|
||||
return(((struct rtc *)rtc)->rtc_data & 0377);
|
||||
}
|
||||
|
||||
/*
|
||||
* Define fields for register B
|
||||
*/
|
||||
#define RTC_B_SET 0x80 /* SET date/time */
|
||||
#define RTC_B_PIE 0x40 /* Periodic Int. Enable */
|
||||
#define RTC_B_AIE 0x20 /* Alarm Int. Enable */
|
||||
#define RTC_B_UIE 0x10 /* Update Ended Int. Enable */
|
||||
#define RTC_B_SQWE 0x08 /* Square Wave Output Enable */
|
||||
#define RTC_B_DM 0x04 /* Binary Data mode */
|
||||
#define RTC_B_24_12 0x02 /* 24 Hour mode */
|
||||
#define RTC_B_DSE 0x01 /* DST Enable */
|
||||
|
||||
/*
|
||||
* Define fields for register C
|
||||
*/
|
||||
#define RTC_C_IRQF 0x80 /* IRQ flag */
|
||||
#define RTC_C_PF 0x40 /* Periodic Int. flag */
|
||||
#define RTC_C_AF 0x20 /* Alarm Int. flag */
|
||||
#define RTC_C_UF 0x10 /* Update Ended Int. flag */
|
||||
|
||||
/*
|
||||
* Define fields for register D
|
||||
*/
|
||||
#define RTC_D_VRT 0x80 /* Valid Ram and Time */
|
||||
__inline__ void mc146818_write(rtc, regno, value)
|
||||
void *rtc;
|
||||
u_int regno, value;
|
||||
{
|
||||
((struct rtc *)rtc)->rtc_regno = regno;
|
||||
((struct rtc *)rtc)->rtc_data = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some useful constants/macros
|
||||
|
@ -110,5 +74,6 @@ struct rtc {
|
|||
#define range_test(n, l, h) ((n) < (l) || (n) > (h))
|
||||
#define SECS_DAY 86400L
|
||||
#define SECS_HOUR 3600L
|
||||
#define STARTOFTIME 1970
|
||||
#define GEMSTARTOFTIME ((machineid & ATARI_CLKBROKEN) ? 1970 : 1968)
|
||||
#define BSDSTARTOFTIME 1970
|
||||
#endif /* _CLOCKREG_H */
|
||||
|
|
Loading…
Reference in New Issue