Quick hack to reintroduce the notion that there might be alpha platforms

without an i8254 timer/counter. This really needs to be cleaned up.
This commit is contained in:
mjacob 2001-05-10 05:23:58 +00:00
parent 84806dd3dd
commit 4626a44bc4

View File

@ -63,6 +63,7 @@
#include <machine/clockvar.h>
#include <isa/isareg.h>
#include <alpha/alpha/timerreg.h>
#include <machine/rpb.h> /* for CPU definitions, etc */
#define SECMIN ((unsigned)60) /* seconds per minute */
#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
@ -151,8 +152,8 @@ static u_int32_t max_cycles_per_tick;
static u_int32_t last_time;
static void handleclock(void* arg);
static void calibrate_clocks(u_int32_t firmware_freq,
u_int32_t *pcc, u_int32_t *timer);
static void
calibrate_clocks(u_int32_t firmware_freq, u_int32_t *pcc, u_int32_t *timer);
static void set_timer_freq(u_int freq, int intr_freq);
void
@ -170,6 +171,14 @@ clockattach(device_t dev)
calibrate_clocks(cycles_per_sec, &pcc, &freq);
cycles_per_sec = pcc;
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type == ST_DEC_21000) {
goto out;
}
/*
* Use the calibrated i8254 frequency if it seems reasonable.
* Otherwise use the default, and don't use the calibrated i586
@ -193,6 +202,7 @@ clockattach(device_t dev)
set_timer_freq(timer_freq, hz);
i8254_timecounter.tc_frequency = timer_freq;
out:
#ifdef EVCNT_COUNTERS
evcnt_attach(dev, "intr", &clock_intr_evcnt);
#endif
@ -250,7 +260,14 @@ cpu_initclocks()
scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / freq;
max_cycles_per_tick = 2*freq / hz;
tc_init(&i8254_timecounter);
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type != ST_DEC_21000) {
tc_init(&i8254_timecounter);
}
if (ncpus == 1) {
alpha_timecounter.tc_frequency = freq;
@ -266,8 +283,10 @@ cpu_initclocks()
CLOCK_INIT(clockdev);
}
static int
getit(void)
static __inline int get_8254_ctr(void);
static __inline int
get_8254_ctr(void)
{
int high, low;
@ -290,6 +309,19 @@ calibrate_clocks(u_int32_t firmware_freq, u_int32_t *pcc, u_int32_t *timer)
u_int count, prev_count, tot_count;
int sec, start_sec;
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type == ST_DEC_21000) {
if (bootverbose)
printf("No i8254- using firmware default of %u Hz\n",
firmware_freq);
*pcc = firmware_freq;
*timer = 0;
return;
}
if (bootverbose)
printf("Calibrating clock(s) ... ");
@ -309,7 +341,7 @@ calibrate_clocks(u_int32_t firmware_freq, u_int32_t *pcc, u_int32_t *timer)
}
/* Start keeping track of the PCC and i8254. */
prev_count = getit();
prev_count = get_8254_ctr();
if (prev_count == 0)
goto fail;
tot_count = 0;
@ -322,7 +354,7 @@ calibrate_clocks(u_int32_t firmware_freq, u_int32_t *pcc, u_int32_t *timer)
* costs a few usec of inaccuracy. The timing of the final reads
* of the counters almost matches the timing of the initial reads,
* so the main cause of inaccuracy is the varying latency from
* inside getit() or rtcin(RTC_STATUSA) to the beginning of the
* inside get_8254_ctr() or rtcin(RTC_STATUSA) to the beginning of the
* rtcin(RTC_SEC) that returns a changed seconds count. The
* maximum inaccuracy from this cause is < 10 usec on 486's.
*/
@ -330,7 +362,7 @@ calibrate_clocks(u_int32_t firmware_freq, u_int32_t *pcc, u_int32_t *timer)
for (;;) {
if (CLOCK_GETSECS(clockdev, &sec))
goto fail;
count = getit();
count = get_8254_ctr();
if (count == 0)
goto fail;
if (count > prev_count)
@ -386,18 +418,24 @@ set_timer_freq(u_int freq, int intr_freq)
static void
handleclock(void* arg)
{
if (timecounter->tc_get_timecount == i8254_get_timecount) {
mtx_lock_spin(&clock_lock);
if (i8254_ticked)
i8254_ticked = 0;
else {
i8254_offset += timer0_max_count;
i8254_lastcount = 0;
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type != ST_DEC_21000) {
if (timecounter->tc_get_timecount == i8254_get_timecount) {
mtx_lock_spin(&clock_lock);
if (i8254_ticked)
i8254_ticked = 0;
else {
i8254_offset += timer0_max_count;
i8254_lastcount = 0;
}
clkintr_pending = 0;
mtx_unlock_spin(&clock_lock);
}
clkintr_pending = 0;
mtx_unlock_spin(&clock_lock);
}
hardclock(arg);
}
@ -591,12 +629,20 @@ i8254_get_timecount(struct timecounter *tc)
static unsigned
alpha_get_timecount(struct timecounter* tc)
{
return alpha_rpcc();
return alpha_rpcc();
}
int
acquire_timer2(int mode)
{
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type == ST_DEC_21000) {
return (0);
}
if (timer2_state != RELEASED)
return (-1);
@ -615,8 +661,16 @@ acquire_timer2(int mode)
}
int
release_timer2()
release_timer2(void)
{
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type == ST_DEC_21000) {
return (0);
}
if (timer2_state != ACQUIRED)
return (-1);
@ -636,6 +690,14 @@ sysbeepstop(void *chan)
int
sysbeep(int pitch, int period)
{
/*
* XXX: TurboLaser doesn't have an i8254 counter.
* XXX: A replacement is needed, and another method
* XXX: of determining this would be nice.
*/
if (hwrpb->rpb_type == ST_DEC_21000) {
return (0);
}
mtx_lock_spin(&clock_lock);