1
0
Files
irix-657m-src/stand/arcs/ide/IP20/time/rt_clock.c
2022-09-29 17:59:04 +03:00

171 lines
4.8 KiB
C

#ident "IP12diags/time/rt_clock.c: $Revision: 1.16 $"
#include "sys/types.h"
#include "sys/cpu.h"
#include "sys/sbd.h"
#include "sys/i8254clock.h"
#include "sys/dp8573clk.h"
#include <libsk.h>
#include "uif.h"
#define CLOCK_COUNTER 10
#define POWER_FAIL_DELAY_ENABLE (0x02)
#define POWER_FAIL_INT_ENABLE (0x80)
#define TIMESAVE_COUNTER 5
#define COUNTER2_VAL 1000 /* counter2 output = 1 kHz */
#define COUNTER1_VAL 2000 /* counter1 output = 2 sec */
#define CAUSE_COUNTER1 CAUSE_IP6
/*
tests the accuracy of the DP8573/DP8572 real time clock by comparing the
elapsed time generated by the clock with the time generated by the
i8254 counter/timer on INT2
*/
int
rt_clock ()
{
int counter;
static char *counter_name[CLOCK_COUNTER] = {
"Ten milliseconds",
"Second",
"Minute",
"Hour",
"Day of month",
"Month",
"Year",
0, /* don't care */
0, /* don't care */
"Day of week"
};
unsigned int current_time[CLOCK_COUNTER];
static unsigned char expected_time[CLOCK_COUNTER] = {
0x50,
0x01,
0x00,
0x00,
0x01,
0x01,
0x00,
0x01, /* don't care */
0x00, /* don't care */
0x01
};
static unsigned char initial_time[CLOCK_COUNTER] = {
0x50,
0x59,
0x59,
0x23,
0x31,
0x12,
0x99,
0x66, /* don't care */
0x03, /* don't care */
0x07
};
int passed = TRUE;
volatile struct dp8573_clk *rt_clock =
(struct dp8573_clk *) PHYS_TO_K1(RT_CLOCK_ADDR);
volatile struct pt_clock *pt = (struct pt_clock *)PT_CLOCK_ADDR;
msg_printf (VRB, "Time of day clock test\n");
rt_clock->ck_status |= RTC_RS;
rt_clock->ck_rtime1 = 0x0; /* stop the clock */
rt_clock->ck_outmode1 = 0x0;
rt_clock->ck_int0ctl1 = 0x0;
rt_clock->ck_int1ctl1 = POWER_FAIL_INT_ENABLE;
/* save current time
*/
for (counter = 0; counter < CLOCK_COUNTER; counter++)
current_time[counter] = rt_clock->ck_counter[counter];
/* enable timesave function
*/
rt_clock->ck_status &= ~RTC_RS;
rt_clock->ck_pflag0 = 0x0;
rt_clock->ck_tsavctl0 = RTC_TIMSAVON | POWER_FAIL_DELAY_ENABLE;
/* set up clock counters and clear timesave ram
*/
for (counter = 0; counter < CLOCK_COUNTER; counter++)
rt_clock->ck_counter[counter] = initial_time[counter];
for (counter = 0; counter < TIMESAVE_COUNTER; counter++)
rt_clock->ck_timsav[counter] = 0x0;
/* start counter/timer ticking
*/
*(volatile char *)TIMER_ACK_ADDR = ACK_TIMER0 | ACK_TIMER1; wbflush();
pt->pt_control = PTCW_SC(2)|PTCW_16B|PTCW_MODE(MODE_RG); wbflush();
pt->pt_counter2 = COUNTER2_VAL & 0xff; wbflush();
pt->pt_counter2 = (COUNTER2_VAL >> 8) & 0xff; wbflush();
pt->pt_control = PTCW_SC(1)|PTCW_16B|PTCW_MODE(MODE_RG); wbflush();
pt->pt_counter1 = COUNTER1_VAL & 0xff; wbflush();
pt->pt_counter1 = (COUNTER1_VAL >> 8) & 0xff; wbflush();
rt_clock->ck_status |= RTC_RS;
rt_clock->ck_rtime1 |= RTC_RUN; /* start the clock */
/* wait for counter/timer to expire
*/
*(volatile char *)TIMER_ACK_ADDR = ACK_TIMER0 | ACK_TIMER1; wbflush();
while (1)
if (get_cause() & CAUSE_COUNTER1)
break;
rt_clock->ck_status &= ~RTC_RS;
rt_clock->ck_tsavctl0 &= ~RTC_TIMSAVON; /* latch time in timesave ram */
rt_clock->ck_status |= RTC_RS;
rt_clock->ck_rtime1 &= ~RTC_RUN; /* stop the clock */
/* clean up counter/timer regs
*/
pt->pt_control = PTCW_SC(0)|PTCW_16B|PTCW_MODE(MODE_STS); wbflush();
pt->pt_control = PTCW_SC(1)|PTCW_16B|PTCW_MODE(MODE_STS); wbflush();
*(volatile char *)TIMER_ACK_ADDR = ACK_TIMER0 | ACK_TIMER1;
/* verify clock counters, all counters must match exactly
*/
for (counter = 0; counter < CLOCK_COUNTER; counter++)
if (counter_name[counter])
if ((rt_clock->ck_counter[counter] & 0xff) !=
expected_time[counter]) {
passed = FALSE;
msg_printf (ERR,
"%s clock counter, Expected: 0x%02x, Actual: 0x%02x\n",
counter_name[counter], expected_time[counter],
rt_clock->ck_counter[counter] & 0xff);
} /* if */
/* verify time save counters, all counters must match exactly
*/
for (counter = 0; counter < TIMESAVE_COUNTER; counter++)
if ((rt_clock->ck_timsav[counter] & 0xff) !=
expected_time[counter + 1]) {
passed = FALSE;
msg_printf (ERR,
"%s time save counter, Expected: 0x%02x, Actual: 0x%02x\n",
counter_name[counter + 1], expected_time[counter + 1],
rt_clock->ck_timsav[counter] & 0xff);
} /* if */
/* restart the clock. the time will be ~3 seconds behind
*/
for (counter = 0; counter < CLOCK_COUNTER; counter++)
rt_clock->ck_counter[counter] = current_time[counter];
rt_clock->ck_status |= RTC_RS;
rt_clock->ck_rtime1 |= RTC_RUN; /* start the clock */
if (!passed)
sum_error ("time of day clock");
else
okydoky ();
return (passed);
} /* rt_clock */