New NetBSD/sh3 clock framework.

+ hardclock source is moved from TMU1 to TMU0.
 + SH3/SH4 common kernel support.
 + PCLOCK estimation.
 + remove duplicated code.
This commit is contained in:
uch 2002-02-22 19:43:58 +00:00
parent 67678b7c54
commit f694c9fdd7
34 changed files with 1077 additions and 1743 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.dreamcast,v 1.14 2001/11/20 14:34:20 lukem Exp $
# $NetBSD: files.dreamcast,v 1.15 2002/02/22 19:44:02 uch Exp $
#
# new style config file for sh3 architecture
#
@ -19,7 +19,7 @@ file arch/dreamcast/dreamcast/conf.c
file arch/dreamcast/dreamcast/machdep.c
file arch/dreamcast/dreamcast/autoconf.c
file arch/dreamcast/dreamcast/procfs_machdep.c procfs
file arch/dreamcast/dreamcast/clock.c
file arch/dreamcast/dreamcast/clock_machdep.c
file arch/sh3/sh3/disksubr.c disk
defparam opt_memsize.h IOM_ROM_BEGIN IOM_ROM_SIZE IOM_RAM_BEGIN IOM_RAM_SIZE

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.1 2001/02/06 16:45:20 uch Exp $ */
/* $NetBSD: autoconf.c,v 1.2 2002/02/22 19:43:59 uch Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -76,8 +76,6 @@ void
cpu_configure()
{
startrtclock();
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");

View File

@ -1,422 +0,0 @@
/* $NetBSD: clock.c,v 1.3 2002/02/19 17:21:19 uch Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum.
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz and Don Ahn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)clock.c 7.2 (Berkeley) 5/12/91
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Primitive clock interrupt routines.
*/
#include "wdog.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <dev/clock_subr.h>
#include <sh3/pclock.h>
#include <sh3/rtcreg.h>
#include <sh3/tmureg.h>
#include <sh3/wdogvar.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/cpufunc.h>
#include <machine/shbvar.h>
void findcpuspeed __P((void));
int clockintr __P((void *));
int gettick __P((void));
void rtcinit __P((void));
int timer0speed;
/*
* microtime() makes use of the following globals. Note that isa_timer_tick
* may be redundant to the `tick' variable, but is kept here for stability.
* isa_timer_count is the countdown count for the timer. timer_msb_table[]
* and timer_lsb_table[] are used to compute the microsecond increment
* for time.tv_usec in the follow fashion:
*
* time.tv_usec += isa_timer_msb_table[cnt_msb] - isa_timer_lsb_table[cnt_lsb];
*/
void
startrtclock()
{
findcpuspeed(); /* use the clock (while it's free)
to find the cpu speed */
}
/*
* Fill in *tvp with current time with microsecond resolution.
*/
void
microtime(tvp)
struct timeval *tvp;
{
int s = splclock();
static struct timeval lasttime;
*tvp = time;
if (tvp->tv_sec == lasttime.tv_sec &&
tvp->tv_usec <= lasttime.tv_usec &&
(tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
tvp->tv_sec++;
tvp->tv_usec -= 1000000;
}
lasttime = *tvp;
splx(s);
}
#include <sh3/wdtreg.h>
unsigned int maxwdog;
int
clockintr(arg)
void *arg;
{
struct clockframe *frame = arg; /* not strictly necessary */
#if (NWDOG > 0)
unsigned int i;
i = (unsigned int)SHREG_WTCNT_R;
if (i > maxwdog)
maxwdog = i;
wdog_wr_cnt(0); /* reset to zero */
#endif
/* clear timer counter under flow interrupt flag */
#ifdef USE_RTCCLK
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_RTC;
#else
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_P16;
#endif
hardclock(frame);
return -1;
}
int
gettick()
{
int counter;
/* Don't want someone screwing with the counter while we're here. */
_cpu_exception_suspend();
counter = SHREG_TCNT0;
_cpu_exception_resume(0);
return counter;
}
/*
* Wait "n" microseconds.
* Relies on timer 1 counting down from (TIMER_FREQ / hz) at TIMER_FREQ Hz.
* Note: timer had better have been programmed before this is first used!
* (Note that we use `rate generator' mode, which counts at 1:1; `square
* wave' mode counts at 2:1).
*/
void
delay(n)
int n;
{
unsigned int limit, tick, otick;
/*
* Read the counter first, so that the rest of the setup overhead is
* counted.
*/
n *= timer0speed;
otick = gettick();
limit = 0xffffffff;
while (n > 0) {
tick = gettick();
if (tick > otick)
n -= limit - (tick - otick);
else
n -= otick - tick;
otick = tick;
}
}
unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
#define FIRST_GUESS 0x2000
void
findcpuspeed()
{
int i;
unsigned int remainder;
/* using clock = Internal RTC */
SHREG_TOCR = TOCR_TCOE;
/* disable Under Flow int,up rising edge, 1/4 Cys */
SHREG_TCR0 = 0;
timer0speed = PCLOCK / 1000000 / 4 + 1;
/* set counter */
SHREG_TCNT0 = 0xffffffff;
/* start counter 0 */
SHREG_TSTR |= TSTR_STR0;
/* Timer counter is decremented at every 0.5 uSec */
for (i = FIRST_GUESS; i; i--)
;
/* Read the value left in the counter */
remainder = gettick();
/* 1 timer tick neary eqyal 0.5 uSec */
delaycount = (FIRST_GUESS * 2000) / (0xffffffff - remainder);
}
void
cpu_initclocks()
{
#ifdef USE_RTCCLK
/* enable under flow interrupt, up rising edge, RTCCLK */
/* RTCCLK == 16kHz */
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_RTC;
SHREG_TCOR1 = 16384 / hz - 1; /* about 1/HZ Sec */
SHREG_TCNT1 = 16384 / hz - 1; /* about 1/HZ Sec */
#else
/* enable under flow interrupt, up rising edge, 1/16 Pcyc */
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_P16;
SHREG_TCOR1 = PCLOCK / 16 / hz - 1; /* about 1/HZ Sec */
SHREG_TCNT1 = PCLOCK / 16 / hz - 1; /* about 1/HZ Sec */
#endif
/* start timer counter 1 */
SHREG_TSTR |= TSTR_STR1;
(void)shb_intr_establish(TMU1_IRQ, IST_EDGE, IPL_CLOCK, clockintr, 0);
}
void
rtcinit()
{
static int first_rtcopen_ever = 1;
if (!first_rtcopen_ever)
return;
first_rtcopen_ever = 0;
}
static int timeset;
/*
* Initialize the time of day register, based on the time base which is, e.g.
* from a filesystem.
*/
void
inittodr(base)
time_t base;
{
volatile unsigned int *rtc = (volatile unsigned int *)0xa0710000;
unsigned int old = 0, new;
/*
* We mostly ignore the suggested time and go for the RTC clock time
* stored in the CMOS RAM. If the time can't be obtained from the
* CMOS, or if the time obtained from the CMOS is 5 or more years
* less than the suggested time, we used the suggested time. (In
* the latter case, it's likely that the CMOS battery has died.)
*/
if (base < 15*SECYR) { /* if before 1985, something's odd... */
printf("WARNING: preposterous time in file system\n");
/* read the system clock anyway */
base = 17*SECYR + 186*SECDAY + SECDAY/2;
}
for (;;) {
int i;
for (i = 0; i < 3; i++) {
new = ((rtc[0] & 0xffff) << 16) | (rtc[1] & 0xffff);
if (new != old)
break;
}
if (i < 3)
old = new;
else
break;
}
/* offset 20 years */
time.tv_sec = new + rtc_offset * 60 - 631152000;
#ifndef INITTODR_ALWAYS_USE_RTC
if (base < time.tv_sec - 5*SECYR)
printf("WARNING: file system time much less than clock time\n");
else if (base > time.tv_sec + 5*SECYR) {
printf("WARNING: clock time much less than file system time\n");
printf("WARNING: using file system time\n");
goto fstime;
}
#endif
timeset = 1;
time.tv_usec = 0;
return;
#ifndef INITTODR_ALWAYS_USE_RTC
fstime:
timeset = 1;
time.tv_sec = base;
time.tv_usec = 0;
printf("WARNING: CHECK AND RESET THE DATE!\n");
#endif
}
/*
* Reset the clock.
*/
void
resettodr()
{
struct clock_ymdhms dt;
int s;
/*
* We might have been called by boot() due to a crash early
* on. Don't reset the clock chip in this case.
*/
if (!timeset)
return;
s = splclock();
clock_secs_to_ymdhms(time.tv_sec - rtc_offset * 60, &dt);
/* stop RTC */
SHREG_RCR2 = SHREG_RCR2_RESET|SHREG_RCR2_ENABLE;
SHREG_RSECCNT = TOBCD(dt.dt_sec);
SHREG_RMINCNT = TOBCD(dt.dt_min);
SHREG_RHRCNT = TOBCD(dt.dt_hour);
SHREG_RWKCNT = TOBCD(dt.dt_wday);
SHREG_RDAYCNT = TOBCD(dt.dt_day);
SHREG_RMONCNT = TOBCD(dt.dt_mon);
#define TOBCD2(x) ((((x) % 10000) / 1000 * 4096) + \
(((x) % 1000) / 100 * 256) + \
((((x) % 100) / 10) * 16) + ((x) % 10))
SHREG_RYRCNT = TOBCD2(dt.dt_year);
/* start RTC */
SHREG_RCR2 = SHREG_RCR2_RESET|SHREG_RCR2_ENABLE|SHREG_RCR2_START;
splx(s);
#ifdef DEBUG
printf("setclock: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year % 100,
dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
dt.dt_wday);
#endif
}
void
setstatclockrate(arg)
int arg;
{
}

View File

@ -0,0 +1,110 @@
/* $NetBSD: clock_machdep.c,v 1.1 2002/02/22 19:43:58 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <dev/clock_subr.h>
#include <sh3/clock.h>
#ifdef DEBUG
#define STATIC
#else
#define STATIC static
#endif
#define DREAMCAST_RTC 0xa0710000
STATIC void dreamcast_rtc_init(void *);
STATIC void dreamcast_rtc_get(void *, time_t, struct clock_ymdhms *);
STATIC void dreamcast_rtc_set(void *, struct clock_ymdhms *);
STATIC u_int32_t dreamcast_read_rtc(void);
STATIC struct rtc_ops dreamcast_rtc_ops = {
.init = dreamcast_rtc_init,
.get = dreamcast_rtc_get,
.set = dreamcast_rtc_set
};
void
machine_clock_init()
{
sh_clock_init(SH_CLOCK_NORTC, &dreamcast_rtc_ops);
}
void
dreamcast_rtc_init(void *cookie)
{
/* Nothing to do */
}
void
dreamcast_rtc_get(void *cookie, time_t base, struct clock_ymdhms *dt)
{
clock_secs_to_ymdhms(dreamcast_read_rtc(), dt);
}
void
dreamcast_rtc_set(void *cookie, struct clock_ymdhms *dt)
{
/* Not suppoted */
}
u_int32_t
dreamcast_read_rtc()
{
__volatile__ u_int32_t *rtc = (__volatile__ u_int32_t *)DREAMCAST_RTC;
u_int32_t new, old;
int i;
for (old = 0;;) {
for (i = 0; i < 3; i++) {
new = ((rtc[0] & 0xffff) << 16) | (rtc[1] & 0xffff);
if (new != old)
break;
}
if (i < 3)
old = new;
else
break;
}
/* offset 20 years */
return (new - 631152000);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.7 2002/02/19 17:21:19 uch Exp $ */
/* $NetBSD: machdep.c,v 1.8 2002/02/22 19:43:59 uch Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@ -209,6 +209,7 @@ cpu_startup()
{
sh3_startup();
printf("%s\n", cpu_model);
/* Safe for i/o port allocation to use malloc now. */
ioport_malloc_safe = 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: shb.c,v 1.6 2002/02/19 17:21:19 uch Exp $ */
/* $NetBSD: shb.c,v 1.7 2002/02/22 19:43:59 uch Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
@ -399,8 +399,8 @@ intrhandler(p1, p2, p3, p4, frame)
if (irl >= INTEVT_SOFT) {
/* This is software interrupt */
irq_num = (irl - INTEVT_SOFT);
} else if (irl == INTEVT_TMU1) {
irq_num = TMU1_IRQ;
} else if (irl == INTEVT_TMU0) {
irq_num = TMU0_IRQ;
} else if (IS_INTEVT_SCI0(irl)) { /* XXX TOO DIRTY */
irq_num = SCI_IRQ;
#ifdef SH4
@ -522,12 +522,12 @@ mask_irq(irq)
int irq;
{
switch (irq) {
case TMU1_IRQ:
case TMU0_IRQ:
#ifdef SH7709A_BROKEN_IPR
ipr[IPRA] &= ~((15)<<8);
ipr[IPRA] &= ~((15)<<12);
SHREG_IPRA = ipr[IPRA];
#else
SHREG_IPRA &= ~((15)<<8);
SHREG_IPRA &= ~((15)<<12);
#endif
break;
case SCI_IRQ:
@ -575,12 +575,12 @@ unmask_irq(irq)
{
switch (irq) {
case TMU1_IRQ:
case TMU0_IRQ:
#ifdef SH7709A_BROKEN_IPR
ipr[ IPRA ] |= ((15 - irq)<<8);
ipr[ IPRA ] |= ((15 - irq)<<12);
SHREG_IPRA = ipr[ IPRA ];
#else
SHREG_IPRA |= ((15 - irq)<<8);
SHREG_IPRA |= ((15 - irq)<<12);
#endif
break;
case SCI_IRQ:
@ -627,8 +627,8 @@ mask_irq(irq)
int irq;
{
switch (irq) {
case TMU1_IRQ:
SHREG_IPRA &= ~((15)<<8);
case TMU0_IRQ:
SHREG_IPRA &= ~((15)<<12);
break;
case SCI_IRQ:
SHREG_IPRB &= ~((15)<<4);
@ -675,8 +675,8 @@ unmask_irq(irq)
{
switch (irq) {
case TMU1_IRQ:
SHREG_IPRA |= ((15 - irq)<<8);
case TMU0_IRQ:
SHREG_IPRA |= ((15 - irq)<<12);
break;
case SCI_IRQ:
SHREG_IPRB |= ((15 - irq)<<4);

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.1 2000/12/11 18:19:15 marcus Exp $ */
/* $NetBSD: intr.h,v 1.2 2002/02/22 19:44:02 uch Exp $ */
#ifndef _DREAMCAST_INTR_H_
#define _DREAMCAST_INTR_H_
@ -28,7 +28,7 @@
#define SIR_HIGH 31
/* IRQ */
#define TMU1_IRQ 2
#define TMU0_IRQ 2
#define SCI_IRQ 6
#define SCIF_IRQ 7
#define WDOG_IRQ 1

View File

@ -1,4 +1,4 @@
# $NetBSD: files.evbsh3,v 1.10 2001/11/20 14:34:20 lukem Exp $
# $NetBSD: files.evbsh3,v 1.11 2002/02/22 19:44:03 uch Exp $
#
# new style config file for sh3 architecture
#
@ -12,7 +12,7 @@ file arch/evbsh3/evbsh3/conf.c
file arch/evbsh3/evbsh3/machdep.c
file arch/evbsh3/evbsh3/procfs_machdep.c procfs
file arch/evbsh3/evbsh3/autoconf.c
file arch/sh3/sh3/clock.c
file arch/evbsh3/evbsh3/clock_machdep.c
file arch/sh3/sh3/disksubr.c disk
defparam opt_memsize.h IOM_ROM_BEGIN IOM_ROM_SIZE IOM_RAM_BEGIN IOM_RAM_SIZE

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.1 2001/02/06 16:45:20 uch Exp $ */
/* $NetBSD: autoconf.c,v 1.2 2002/02/22 19:44:00 uch Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -76,8 +76,6 @@ void
cpu_configure()
{
startrtclock();
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");

View File

@ -0,0 +1,50 @@
/* $NetBSD: clock_machdep.c,v 1.1 2002/02/22 19:44:00 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sh3/clock.h>
void
machine_clock_init()
{
#ifdef INITTODR_ALWAYS_USE_RTC
sh_clock_init(SH_CLOCK_NOINITTODR, 0);
#else
sh_clock_init(0, 0);
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: shb.c,v 1.14 2002/02/19 17:21:20 uch Exp $ */
/* $NetBSD: shb.c,v 1.15 2002/02/22 19:44:00 uch Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
@ -396,8 +396,8 @@ intrhandler(p1, p2, p3, p4, frame)
if (irl >= INTEVT_SOFT) {
/* This is software interrupt */
irq_num = (irl - INTEVT_SOFT);
} else if (irl == INTEVT_TMU1) {
irq_num = TMU1_IRQ;
} else if (irl == INTEVT_TMU0) {
irq_num = TMU0_IRQ;
} else if (IS_INTEVT_SCI0(irl)) { /* XXX TOO DIRTY */
irq_num = SCI_IRQ;
#ifdef SH4
@ -519,9 +519,9 @@ mask_irq(irq)
int irq;
{
switch (irq) {
case TMU1_IRQ:
case TMU0_IRQ:
#ifdef SH7709A_BROKEN_IPR
ipr[IPRA] &= ~((15)<<8);
ipr[IPRA] &= ~((15)<<12);
SHREG_IPRA = ipr[IPRA];
#else
SHREG_IPRA &= ~((15)<<8);
@ -571,9 +571,9 @@ unmask_irq(irq)
{
switch (irq) {
case TMU1_IRQ:
case TMU0_IRQ:
#ifdef SH7709A_BROKEN_IPR
ipr[ IPRA ] |= ((15 - irq)<<8);
ipr[ IPRA ] |= ((15 - irq)<<12);
SHREG_IPRA = ipr[ IPRA ];
#else
SHREG_IPRA |= ((15 - irq)<<8);
@ -622,8 +622,8 @@ mask_irq(irq)
int irq;
{
switch (irq) {
case TMU1_IRQ:
SHREG_IPRA &= ~((15)<<8);
case TMU0_IRQ:
SHREG_IPRA &= ~((15)<<12);
break;
case SCI_IRQ:
SHREG_IPRB &= ~((15)<<4);
@ -657,8 +657,8 @@ unmask_irq(irq)
{
switch (irq) {
case TMU1_IRQ:
SHREG_IPRA |= ((15 - irq)<<8);
case TMU0_IRQ:
SHREG_IPRA |= ((15 - irq)<<12);
break;
case SCI_IRQ:
SHREG_IPRB |= ((15 - irq)<<4);

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.4 2000/10/31 02:04:13 msaitoh Exp $ */
/* $NetBSD: intr.h,v 1.5 2002/02/22 19:44:03 uch Exp $ */
#ifndef _EVBSH3_INTR_H_
#define _EVBSH3_INTR_H_
@ -28,7 +28,7 @@
#define SIR_HIGH 31
/* IRQ */
#define TMU1_IRQ 2
#define TMU0_IRQ 2
#define SCI_IRQ 6
#define SCIF_IRQ 7
#define WDOG_IRQ 1

View File

@ -1,4 +1,4 @@
# $NetBSD: files.hpcsh,v 1.19 2002/02/17 21:01:15 uch Exp $
# $NetBSD: files.hpcsh,v 1.20 2002/02/22 19:44:03 uch Exp $
#
maxpartitions 8
@ -11,11 +11,10 @@ defflag debug_hpcsh.h BUS_SPACE_DEBUG
file arch/hpcsh/hpcsh/conf.c
file arch/hpcsh/hpcsh/machdep.c
file arch/hpcsh/hpcsh/clock.c
file arch/hpcsh/hpcsh/console.c
file arch/hpcsh/hpcsh/autoconf.c
file arch/hpcsh/hpcsh/bus_space.c
#file arch/hpcsh/hpcsh/bus_dma.c
file arch/hpcsh/hpcsh/clock_machdep.c
file arch/hpcsh/hpcsh/procfs_machdep.c procfs
file arch/hpc/hpc/kloader.c

View File

@ -1,649 +0,0 @@
/* $NetBSD: clock.c,v 1.6 2002/02/17 21:01:18 uch Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <dev/clock_subr.h>
#include <sh3/cpufunc.h>
#include <machine/shbvar.h>
#include <machine/debug.h>
#include <hpcsh/hpcsh/clockvar.h>
/* RTC */
#define SH3_R64CNT 0xfffffec0
#define SH3_RSECCNT 0xfffffec2
#define SH3_RMINCNT 0xfffffec4
#define SH3_RHRCNT 0xfffffec6
#define SH3_RWKCNT 0xfffffec8
#define SH3_RDAYCNT 0xfffffeca
#define SH3_RMONCNT 0xfffffecc
#define SH3_RYRCNT 0xfffffece
#define SH3_RSECAR 0xfffffed0
#define SH3_RMINAR 0xfffffed2
#define SH3_RHRAR 0xfffffed4
#define SH3_RWKAR 0xfffffed6
#define SH3_RDAYAR 0xfffffed8
#define SH3_RMONAR 0xfffffeda
#define SH3_RCR1 0xfffffedc
#define SH3_RCR2 0xfffffede
#define SH4_R64CNT 0xffc80000
#define SH4_RSECCNT 0xffc80004
#define SH4_RMINCNT 0xffc80008
#define SH4_RHRCNT 0xffc8000c
#define SH4_RWKCNT 0xffc80010
#define SH4_RDAYCNT 0xffc80014
#define SH4_RMONCNT 0xffc80018
#define SH4_RYRCNT 0xffc8001c /* 16 bit */
#define SH4_RSECAR 0xffc80020
#define SH4_RMINAR 0xffc80024
#define SH4_RHRAR 0xffc80028
#define SH4_RWKAR 0xffc8002c
#define SH4_RDAYAR 0xffc80030
#define SH4_RMONAR 0xffc80034
#define SH4_RCR1 0xffc80038
#define SH4_RCR2 0xffc8003c
#if defined(SH3) && defined(SH4)
int __sh_R64CNT;
int __sh_RSECCNT;
int __sh_RMINCNT;
int __sh_RHRCNT;
int __sh_RWKCNT;
int __sh_RDAYCNT;
int __sh_RMONCNT;
int __sh_RYRCNT;
int __sh_RSECAR;
int __sh_RMINAR;
int __sh_RHRAR;
int __sh_RWKAR;
int __sh_RDAYAR;
int __sh_RMONAR;
int __sh_RCR1;
int __sh_RCR2;
#endif /* SH3 && SH4 */
#define SH_RCR1_CF 0x80
#define SH_RCR1_CIE 0x10
#define SH_RCR1_AIE 0x08
#define SH_RCR1_AF 0x01
#define SH_RCR2_PEF 0x80
#define SH_RCR2_PES2 0x40
#define SH_RCR2_PES1 0x20
#define SH_RCR2_PES0 0x10
#define SH_RCR2_ENABLE 0x08
#define SH_RCR2_ADJ 0x04
#define SH_RCR2_RESET 0x02
#define SH_RCR2_START 0x01
/* TMU */
#define SH3_TOCR 0xfffffe90
#define SH3_TSTR 0xfffffe92
#define SH3_TCOR0 0xfffffe94
#define SH3_TCNT0 0xfffffe98
#define SH3_TCR0 0xfffffe9c
#define SH3_TCOR1 0xfffffea0
#define SH3_TCNT1 0xfffffea4
#define SH3_TCR1 0xfffffea8
#define SH3_TCOR2 0xfffffeac
#define SH3_TCNT2 0xfffffeb0
#define SH3_TCR2 0xfffffeb4
#define SH3_TCPR2 0xfffffeb8
#define SH4_TOCR 0xffd80000
#define SH4_TSTR 0xffd80004
#define SH4_TCOR0 0xffd80008
#define SH4_TCNT0 0xffd8000c
#define SH4_TCR0 0xffd80010
#define SH4_TCOR1 0xffd80014
#define SH4_TCNT1 0xffd80018
#define SH4_TCR1 0xffd8001c
#define SH4_TCOR2 0xffd80020
#define SH4_TCNT2 0xffd80024
#define SH4_TCR2 0xffd80028
#define SH4_TCPR2 0xffd8002c
#if defined(SH3) && defined(SH4)
int __sh_TOCR;
int __sh_TSTR;
int __sh_TCOR0;
int __sh_TCNT0;
int __sh_TCR0;
int __sh_TCOR1;
int __sh_TCNT1;
int __sh_TCR1;
int __sh_TCOR2;
int __sh_TCNT2;
int __sh_TCR2;
int __sh_TCPR2;
#endif /* SH3 && SH4 */
#define TOCR_TCOE 0x01
#define TSTR_STR2 0x04
#define TSTR_STR1 0x02
#define TSTR_STR0 0x01
#define TCR_ICPF 0x0200
#define TCR_UNF 0x0100
#define TCR_ICPE1 0x0080
#define TCR_ICPE0 0x0040
#define TCR_UNIE 0x0020
#define TCR_CKEG1 0x0010
#define TCR_CKEG0 0x0008
#define TCR_TPSC2 0x0004
#define TCR_TPSC1 0x0002
#define TCR_TPSC0 0x0001
#define TCR_TPSC_P4 0x0000
#define TCR_TPSC_P16 0x0001
#define TCR_TPSC_P64 0x0002
#define TCR_TPSC_P256 0x0003
#define SH3_TCR_TPSC_RTC 0x0004
#define SH3_TCR_TPSC_TCLK 0x0005
#define SH4_TCR_TPSC_P512 0x0004
#define SH4_TCR_TPSC_RTC 0x0006
#define SH4_TCR_TPSC_TCLK 0x0007
#if defined(SH3) && defined(SH4)
#define SH_(x) __sh_ ## x
#elif defined(SH3)
#define SH_(x) SH3_ ## x
#elif defined(SH4)
#define SH_(x) SH4_ ## x
#endif
#ifndef HZ
#define HZ 64
#endif
#define MINYEAR 2001 /* "today" */
#define RTC_CLOCK 16384 /* Hz */
/*
* hpcsh clock module
* + default 64Hz
* + use TMU channel 0 as clock interrupt source.
* + TMU channel 0 input source is SH internal RTC output. (1.6384kHz)
*/
static void clock_register_init(void);
/* TMU */
/* interrupt handler is timing critical. prepared for each. */
int sh3_clock_intr(void *);
int sh4_clock_intr(void *);
/* RTC */
static void rtc_init(void);
static int rtc_gettime(struct clock_ymdhms *);
static int rtc_settime(struct clock_ymdhms *);
static int __todr_inited;
static int __cnt_delay; /* calibrated loop variable (1 us) */
static u_int32_t __cnt_clock; /* clock interrupt interval count */
static int __cpuclock;
static int __pclock;
/*
* [...]
* add IF ID EX MA WB
* nop IF ID EX MA WB
* cmp/pl IF ID EX MA WB - -
* nop IF ID EX MA - - WB
* bt IF ID EX . . MA WB
* nop IF ID - - EX MA WB
* nop IF - - ID EX MA WB
* nop - - - IF ID EX MA WB
* add IF ID EX MA WB
* nop IF ID EX MA WB
* cmp/pl IF ID EX MA WB - -
* nop IF ID EX MA - - WB
* bt IF ID EX . . MA
* [...]
*/
#define DELAY_LOOP(x) \
__asm__ __volatile__(" \
mov.l r0, @-r15; \
mov %0, r0; \
nop;nop;nop;nop; \
1: nop; /* 1 */ \
nop; /* 2 */ \
nop; /* 3 */ \
add #-1, r0; /* 4 */ \
nop; /* 5 */ \
cmp/pl r0; /* 6 */ \
nop; /* 7 */ \
bt 1b; /* 8, 9, 10 */ \
mov.l @r15+, r0; \
" :: "r"(x))
/*
* Estimate CPU and Peripheral clock.
*/
#define TMU_START(x) \
do { \
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) & ~TSTR_STR ## x);\
_reg_write_4(SH_(TCNT ## x), 0xffffffff); \
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) | TSTR_STR ## x);\
} while (/*CONSTCOND*/0)
#define TMU_ELAPSED(x) \
(0xffffffff - _reg_read_4(SH_(TCNT ## x)))
void
clock_init()
{
u_int32_t t0, t1;
clock_register_init();
/* initialize TMU */
_reg_write_2(SH_(TCR0), 0);
_reg_write_2(SH_(TCR1), 0);
_reg_write_2(SH_(TCR2), 0);
/* stop all counter */
_reg_write_1(SH_(TSTR), 0);
/* set TMU channel 0 source to RTC counter clock (16.384kHz) */
_reg_write_2(SH_(TCR0), CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC);
/*
* estimate CPU clock.
*/
TMU_START(0);
DELAY_LOOP(10000000);
t0 = TMU_ELAPSED(0);
__cpuclock = (100000000 / t0) * RTC_CLOCK;
if (CPU_IS_SH4)
__cpuclock >>= 1; /* two-issue */
__cnt_delay = (RTC_CLOCK * 10) / t0;
/*
* estimate PCLOCK
*/
/* set TMU channel 1 source to PCLOCK / 4 */
_reg_write_2(SH_(TCR1), TCR_TPSC_P4);
TMU_START(0);
TMU_START(1);
delay(1000000);
t0 = TMU_ELAPSED(0);
t1 = TMU_ELAPSED(1);
__pclock = (t1 / t0) * RTC_CLOCK * 4;
/* stop all counter */
_reg_write_1(SH_(TSTR), 0);
/* Initialize RTC */
rtc_init();
#undef TMU_START
#undef TMU_ELAPSED
}
int
clock_get_cpuclock()
{
return __cpuclock;
}
int
clock_get_pclock()
{
return __pclock;
}
/*
* Return the best possible estimate of the time in the timeval to
* which tv points.
*/
void
microtime(struct timeval *tv)
{
static struct timeval lasttime;
int s = splclock();
*tv = time;
splx(s);
tv->tv_usec += ((__cnt_clock - _reg_read_4(SH_(TCNT0))) * 1000000) /
RTC_CLOCK;
while (tv->tv_usec >= 1000000) {
tv->tv_usec -= 1000000;
tv->tv_sec++;
}
if (tv->tv_sec == lasttime.tv_sec &&
tv->tv_usec <= lasttime.tv_usec &&
(tv->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
tv->tv_usec -= 1000000;
tv->tv_sec++;
}
lasttime = *tv;
}
/*
* Wait at least `n' usec.
*/
void
delay(int n)
{
DELAY_LOOP(__cnt_delay * n);
}
/*
* Start the clock interrupt.
*/
void
cpu_initclocks()
{
/* set global variables. */
hz = HZ;
tick = 1000000 / hz;
/* use TMU channel 0 as clock source. */
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) & ~TSTR_STR1);
_reg_write_2(SH_(TCR1), TCR_UNIE |
(CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC));
__cnt_clock = RTC_CLOCK / hz - 1;
_reg_write_4(SH_(TCOR1), __cnt_clock);
_reg_write_4(SH_(TCNT1), __cnt_clock);
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) | TSTR_STR1);
shb_intr_establish(TMU1_IRQ, IST_EDGE, IPL_CLOCK,
CPU_IS_SH3 ? sh3_clock_intr : sh4_clock_intr, 0);
}
#ifdef SH3
int
sh3_clock_intr(void *arg) /* trap frame */
{
/* clear underflow status */
_reg_write_2(SH3_TCR1, _reg_read_2(SH3_TCR1) & ~TCR_UNF);
__dbg_heart_beat(HEART_BEAT_WHITE);
hardclock(arg);
return (1);
}
#endif /* SH3 */
#ifdef SH4
int
sh4_clock_intr(void *arg) /* trap frame */
{
/* clear underflow status */
_reg_write_2(SH4_TCR1, _reg_read_2(SH4_TCR1) & ~TCR_UNF);
__dbg_heart_beat(HEART_BEAT_WHITE);
hardclock(arg);
return (1);
}
#endif /* SH4 */
/*
* Initialize time of day.
*/
void
inittodr(time_t base)
{
struct clock_ymdhms dt;
time_t rtc;
int s;
__todr_inited = 1;
rtc_gettime(&dt);
rtc = clock_ymdhms_to_secs(&dt);
#ifdef DEBUG
printf("readclock: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year,
dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
dt.dt_wday);
#endif
if (rtc < base ||
dt.dt_year < MINYEAR || dt.dt_year > 2037 ||
dt.dt_mon < 1 || dt.dt_mon > 12 ||
dt.dt_wday > 6 ||
dt.dt_day < 1 || dt.dt_day > 31 ||
dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59) {
/*
* Believe the time in the file system for lack of
* anything better, resetting the RTC.
*/
s = splclock();
time.tv_sec = base;
time.tv_usec = 0;
splx(s);
printf("WARNING: preposterous clock chip time\n");
resettodr();
printf(" -- CHECK AND RESET THE DATE!\n");
return;
}
s = splclock();
time.tv_sec = rtc + rtc_offset * 60;
time.tv_usec = 0;
splx(s);
return;
}
/*
* Reset the RTC.
*/
void
resettodr()
{
struct clock_ymdhms dt;
int s;
if (!__todr_inited)
return;
s = splclock();
clock_secs_to_ymdhms(time.tv_sec - rtc_offset * 60, &dt);
splx(s);
rtc_settime(&dt);
#ifdef DEBUG
printf("setclock: %d/%d/%d/%d/%d/%d(%d) rtc_offset %d\n", dt.dt_year,
dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec, dt.dt_wday,
rtc_offset);
#endif
}
void
setstatclockrate(int newhz)
{
/* XXX not yet */
}
/*
* SH3 RTC module ops.
*/
void
rtc_init()
{
/* reset RTC alarm and interrupt */
_reg_write_1(SH_(RCR1), 0);
/* make sure to start RTC */
_reg_write_1(SH_(RCR2), SH_RCR2_ENABLE | SH_RCR2_START);
}
int
rtc_gettime(struct clock_ymdhms *dt)
{
int retry = 8;
/* disable carry interrupt */
_reg_write_1(SH_(RCR1), _reg_read_1(SH_(RCR1)) & ~SH_RCR1_CIE);
do {
u_int8_t r = _reg_read_1(SH_(RCR1));
r &= ~SH_RCR1_CF;
r |= SH_RCR1_AF; /* don't clear alarm flag */
_reg_write_1(SH_(RCR1), r);
/* read counter */
#define RTCGET(x, y) dt->dt_ ## x = FROMBCD(_reg_read_1(SH_(R ## y ## CNT)))
RTCGET(year, YR);
RTCGET(mon, MON);
RTCGET(wday, WK);
RTCGET(day, DAY);
RTCGET(hour, HR);
RTCGET(min, MIN);
RTCGET(sec, SEC);
#undef RTCGET
} while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0);
if (retry == 0) {
printf("rtc_gettime: couldn't read RTC register.\n");
memset(dt, sizeof(*dt), 0);
return (1);
}
dt->dt_year = (dt->dt_year % 100) + 1900;
if (dt->dt_year < 1970)
dt->dt_year += 100;
return (0);
}
int
rtc_settime(struct clock_ymdhms *dt)
{
u_int8_t r;
/* stop clock */
r = _reg_read_1(SH_(RCR2));
r |= SH_RCR2_RESET;
r &= ~SH_RCR2_START;
_reg_write_1(SH_(RCR2), r);
/* set time */
if (CPU_IS_SH3)
_reg_write_1(SH3_RYRCNT, TOBCD(dt->dt_year % 100));
else
_reg_write_2(SH4_RYRCNT, TOBCD(dt->dt_year % 100));
#define RTCSET(x, y) _reg_write_1(SH_(R ## x ## CNT), TOBCD(dt->dt_ ## y))
RTCSET(MON, mon);
RTCSET(WK, wday);
RTCSET(DAY, day);
RTCSET(HR, hour);
RTCSET(MIN, min);
RTCSET(SEC, sec);
#undef RTCSET
/* start clock */
_reg_write_1(SH_(RCR2), r | SH_RCR2_START);
return (0);
}
#define SH3REG(x) __sh_ ## x = SH3_ ## x
#define SH4REG(x) __sh_ ## x = SH4_ ## x
static void
clock_register_init()
{
#if defined(SH3) && defined(SH4)
if (CPU_IS_SH3) {
SH3REG(R64CNT);
SH3REG(RSECCNT);
SH3REG(RMINCNT);
SH3REG(RHRCNT);
SH3REG(RWKCNT);
SH3REG(RDAYCNT);
SH3REG(RMONCNT);
SH3REG(RYRCNT);
SH3REG(RSECAR);
SH3REG(RMINAR);
SH3REG(RHRAR);
SH3REG(RWKAR);
SH3REG(RDAYAR);
SH3REG(RMONAR);
SH3REG(RCR1);
SH3REG(RCR2);
SH3REG(TOCR);
SH3REG(TSTR);
SH3REG(TCOR0);
SH3REG(TCNT0);
SH3REG(TCR0);
SH3REG(TCOR1);
SH3REG(TCNT1);
SH3REG(TCR1);
SH3REG(TCOR2);
SH3REG(TCNT2);
SH3REG(TCR2);
SH3REG(TCPR2);
}
if (CPU_IS_SH4) {
SH4REG(R64CNT);
SH4REG(RSECCNT);
SH4REG(RMINCNT);
SH4REG(RHRCNT);
SH4REG(RWKCNT);
SH4REG(RDAYCNT);
SH4REG(RMONCNT);
SH4REG(RYRCNT);
SH4REG(RSECAR);
SH4REG(RMINAR);
SH4REG(RHRAR);
SH4REG(RWKAR);
SH4REG(RDAYAR);
SH4REG(RMONAR);
SH4REG(RCR1);
SH4REG(RCR2);
SH4REG(TOCR);
SH4REG(TSTR);
SH4REG(TCOR0);
SH4REG(TCNT0);
SH4REG(TCR0);
SH4REG(TCOR1);
SH4REG(TCNT1);
SH4REG(TCR1);
SH4REG(TCOR2);
SH4REG(TCNT2);
SH4REG(TCR2);
SH4REG(TCPR2);
}
#endif /* SH3 && SH4 */
}
#undef SH3REG
#undef SH4REG

View File

@ -1,7 +1,7 @@
/* $NetBSD: clockvar.h,v 1.1 2001/04/23 16:47:16 uch Exp $ */
/* $NetBSD: clock_machdep.c,v 1.1 2002/02/22 19:44:00 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,6 +33,14 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
void clock_init(void);
int clock_get_cpuclock(void);
int clock_get_pclock(void);
#include <sys/param.h>
#include <sys/systm.h>
#include <sh3/clock.h>
void
machine_clock_init()
{
sh_clock_init(0, 0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.24 2002/02/19 17:21:20 uch Exp $ */
/* $NetBSD: machdep.c,v 1.25 2002/02/22 19:44:01 uch Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@ -60,6 +60,7 @@
#include <sh3/cpu.h>
#include <sh3/mmu.h>
#include <sh3/clock.h>
#ifdef KGDB
#include <sys/kgdb.h>
@ -84,10 +85,8 @@
#include <machine/autoconf.h> /* makebootdev() */
#include <machine/kloader.h>
#include <hpcsh/hpcsh/clockvar.h>
#include <hpcsh/dev/hd64465/hd64465var.h>
#include <sh3/pclock.h>
#include <sh3/intcreg.h>
#ifdef DEBUG
@ -285,8 +284,6 @@ machine_startup(int argc, char *argv[], struct bootinfo *bi)
/*
* Console
*/
clock_init(); /* serial console requires PCLOCK. estimate here */
sh3_pclock = clock_get_pclock();
consinit();
#ifdef HPC_DEBUG_LCD
dbg_lcd_test();
@ -407,9 +404,10 @@ void
cpu_startup()
{
platid_t cpu;
int cpuclock;
int cpuclock, pclock;
cpuclock = clock_get_cpuclock();
cpuclock = sh_clock_get_cpuclock();
pclock = sh_clock_get_pclock();
sh3_startup();
@ -419,8 +417,7 @@ cpu_startup()
#define MHZ(x) ((x) / 1000000), (((x) % 1000000) / 1000)
printf("%s %d.%02d MHz PCLOCK %d.%02d MHz\n", cpu_model,
MHZ(cpuclock), MHZ(PCLOCK));
MHZ(cpuclock), MHZ(pclock));
#ifdef SYSCALL_DEBUG
scdebug |= SCDEBUG_ALL;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: shb.c,v 1.9 2002/02/17 21:01:19 uch Exp $ */
/* $NetBSD: shb.c,v 1.10 2002/02/22 19:44:01 uch Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
@ -333,8 +333,8 @@ intrhandler(int p1, int p2, int p3, int p4, /* dummy param */
if (irl >= INTEVT_SOFT) {
/* This is software interrupt */
irq_num = (irl - INTEVT_SOFT);
} else if (irl == INTEVT_TMU1) {
irq_num = TMU1_IRQ;
} else if (irl == INTEVT_TMU0) {
irq_num = TMU0_IRQ;
} else if (IS_INTEVT_SCI0(irl)) { /* XXX TOO DIRTY */
irq_num = SCI_IRQ;
#ifdef SH4 //XXX
@ -428,8 +428,8 @@ void
mask_irq_sh4(int irq)
{
switch (irq) {
case TMU1_IRQ:
_reg_write_2(SH4_IPRA, _reg_read_2(SH4_IPRA) & ~((15) << 8));
case TMU0_IRQ:
_reg_write_2(SH4_IPRA, _reg_read_2(SH4_IPRA) & ~((15) << 12));
break;
case SCI_IRQ:
_reg_write_2(SH4_IPRB, _reg_read_2(SH4_IPRB) & ~((15) << 4));
@ -454,9 +454,9 @@ unmask_irq_sh4(int irq)
{
switch (irq) {
case TMU1_IRQ:
case TMU0_IRQ:
_reg_write_2(SH4_IPRA,
_reg_read_2(SH4_IPRA) | ((15 - irq) << 8));
_reg_read_2(SH4_IPRA) | ((15 - irq) << 12));
break;
case SCI_IRQ:
_reg_write_2(SH4_IPRB,
@ -493,8 +493,8 @@ void
mask_irq_sh3(int irq)
{
switch (irq) {
case TMU1_IRQ:
ipr[IPRA] &= ~((15)<<8);
case TMU0_IRQ:
ipr[IPRA] &= ~((15)<<12);
_reg_write_2(SH3_IPRA, ipr[IPRA]);
break;
case SCI_IRQ:
@ -520,8 +520,8 @@ unmask_irq_sh3(int irq)
{
switch (irq) {
case TMU1_IRQ:
ipr[ IPRA ] |= ((15 - irq)<<8);
case TMU0_IRQ:
ipr[ IPRA ] |= ((15 - irq)<<12);
_reg_write_2(SH3_IPRA, ipr[IPRA]);
break;
case SCI_IRQ:

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.3 2001/02/21 16:28:04 uch Exp $ */
/* $NetBSD: intr.h,v 1.4 2002/02/22 19:44:03 uch Exp $ */
#ifndef _HPCSH_INTR_H_
#define _HPCSH_INTR_H_
@ -28,7 +28,7 @@
#define SIR_HIGH 31
/* IRQ */
#define TMU1_IRQ 2
#define TMU0_IRQ 2
#define SCI_IRQ 6
#define SCIF_IRQ 7
#define IRQ4_IRQ 4

View File

@ -1,4 +1,4 @@
# $NetBSD: files.mmeye,v 1.8 2001/11/20 14:34:22 lukem Exp $
# $NetBSD: files.mmeye,v 1.9 2002/02/22 19:44:03 uch Exp $
#
# config file for mmeye
@ -11,7 +11,7 @@ file arch/mmeye/mmeye/conf.c
file arch/mmeye/mmeye/machdep.c
file arch/mmeye/mmeye/procfs_machdep.c procfs
file arch/mmeye/mmeye/autoconf.c
file arch/sh3/sh3/clock.c
file arch/mmeye/mmeye/clock_machdep.c
file arch/sh3/sh3/disksubr.c disk
defparam opt_memsize.h IOM_ROM_BEGIN IOM_ROM_SIZE IOM_RAM_BEGIN IOM_RAM_SIZE

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.3 2000/04/13 15:36:10 msaitoh Exp $ */
/* $NetBSD: intr.h,v 1.4 2002/02/22 19:44:04 uch Exp $ */
#ifndef _MMEYE_INTR_H_
#define _MMEYE_INTR_H_
@ -30,7 +30,7 @@
/* IRQ */
#define TMU1_IRQ 2
#define TMU0_IRQ 2
#define IRQ_LOW 2
#define IRQ_HIGH 15

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.1 2001/02/06 16:45:21 uch Exp $ */
/* $NetBSD: autoconf.c,v 1.2 2002/02/22 19:44:01 uch Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -76,8 +76,6 @@ void
cpu_configure()
{
startrtclock();
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");

View File

@ -0,0 +1,50 @@
/* $NetBSD: clock_machdep.c,v 1.1 2002/02/22 19:44:01 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sh3/clock.h>
void
machine_clock_init()
{
#ifdef INITTODR_ALWAYS_USE_RTC
sh_clock_init(SH_CLOCK_NOINITTODR, 0);
#else
sh_clock_init(0, 0);
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: shb.c,v 1.9 2002/02/19 17:21:20 uch Exp $ */
/* $NetBSD: shb.c,v 1.10 2002/02/22 19:44:01 uch Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum. All rights reserved.
@ -402,8 +402,8 @@ intrhandler(p1, p2, p3, p4, frame)
if (irl >= INTEVT_SOFT) {
/* This is software interrupt */
irq_num = (irl - INTEVT_SOFT);
} else if (irl == INTEVT_TMU1)
irq_num = TMU1_IRQ;
} else if (irl == INTEVT_TMU0)
irq_num = TMU0_IRQ;
else
irq_num = (irl - 0x200) >> 5;
@ -511,8 +511,8 @@ mask_irq(irq)
{
unsigned short mask;
if (irq == TMU1_IRQ) {
SHREG_IPRA &= 0xf0ff;
if (irq == TMU0_IRQ) {
SHREG_IPRA &= 0x0fff;
} else{
mask = IRQ_BIT(15 - irq);
MMTA_IMASK &= ~mask;
@ -525,8 +525,8 @@ unmask_irq(irq)
{
unsigned short mask;
if (irq == TMU1_IRQ) {
SHREG_IPRA |= ((15 - irq)<<8);
if (irq == TMU0_IRQ) {
SHREG_IPRA |= ((15 - irq)<<12);
} else{
mask = IRQ_BIT(15 - irq);
MMTA_IMASK |= mask;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sci.c,v 1.18 2002/02/12 15:26:46 uch Exp $ */
/* $NetBSD: sci.c,v 1.19 2002/02/22 19:44:04 uch Exp $ */
/*-
* Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu. All rights reserved.
@ -120,7 +120,7 @@
#include <dev/cons.h>
#include <machine/cpu.h>
#include <sh3/pclock.h>
#include <sh3/clock.h>
#include <sh3/scireg.h>
#include <sh3/tmureg.h>
@ -275,36 +275,10 @@ void InitializeSci (unsigned int);
#define I2C_ADRS (*(volatile unsigned int *)0xa8000000)
#define USART_ON (unsigned int)~0x08
static void WaitFor(int);
void sci_putc(unsigned char);
unsigned char sci_getc(void);
int SciErrCheck(void);
/*
* WaitFor
* : int mSec;
*/
static void
WaitFor(int mSec)
{
/* Disable Under Flow interrupt, rising edge, 1/4 */
SHREG_TCR2 = 0x0000;
/* Set counter value (count down with 4 KHz) */
SHREG_TCNT2 = mSec * 4;
/* start Channel2 */
SHREG_TSTR |= TSTR_STR2;
/* wait for under flag ON of channel2 */
while ((SHREG_TCR2 & TCR_UNF) == 0)
;
/* stop channel2 */
SHREG_TSTR &= ~TSTR_STR2;
}
/*
* InitializeSci
* : unsigned int bps;
@ -328,7 +302,7 @@ InitializeSci(unsigned int bps)
* wait 1mSec, because Send/Recv must begin 1 bit period after
* BRR is set.
*/
WaitFor(1);
delay(1000);
/* Send permission, Receive permission ON */
SHREG_SCSCR = SCSCR_TE | SCSCR_RE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: scif.c,v 1.20 2002/02/12 15:26:46 uch Exp $ */
/* $NetBSD: scif.c,v 1.21 2002/02/22 19:44:04 uch Exp $ */
/*-
* Copyright (C) 1999 T.Horiuchi and SAITOH Masanobu. All rights reserved.
@ -120,9 +120,9 @@
#include <dev/cons.h>
#include <machine/cpu.h>
#include <sh3/pclock.h>
#include <sh3/clock.h>
#include <sh3/scifreg.h>
#include <sh3/tmureg.h>
//#include <sh3/tmureg.h>
#include <machine/shbvar.h>
@ -276,36 +276,10 @@ void InitializeScif (unsigned int);
#define CR 0x0D
#define USART_ON (unsigned int)~0x08
static void WaitFor(int);
void scif_putc(unsigned char);
unsigned char scif_getc(void);
int ScifErrCheck(void);
/*
* WaitFor
* : int mSec;
*/
static void
WaitFor(int mSec)
{
/* Disable Under Flow interrupt, rising edge, 1/4 */
SHREG_TCR2 = 0x0000;
/* Set counter value (count down with 4 KHz) */
SHREG_TCNT2 = mSec * 4;
/* start Channel2 */
SHREG_TSTR |= TSTR_STR2;
/* wait for under flag ON of channel2 */
while ((SHREG_TCR2 & TCR_UNF) == 0)
;
/* stop channel2 */
SHREG_TSTR &= ~TSTR_STR2;
}
/*
* InitializeScif
* : unsigned int bps;
@ -328,13 +302,13 @@ InitializeScif(unsigned int bps)
SHREG_SCSMR2 = 0x00; /* 8bit,NonParity,Even,1Stop */
/* Bit Rate Register */
SHREG_SCBRR2 = divrnd(PCLOCK, 32 * bps) - 1;
SHREG_SCBRR2 = divrnd(sh_clock_get_pclock(), 32 * bps) - 1;
/*
* wait 1mSec, because Send/Recv must begin 1 bit period after
* BRR is set.
*/
WaitFor(1);
delay(1000);
#if 0
SHREG_SCFCR2 = FIFO_RCV_TRIGGER_14 | FIFO_XMT_TRIGGER_1 | SCFCR2_MCE;
@ -635,7 +609,7 @@ scifparam(struct tty *tp, struct termios *t)
SHREG_SCFCR2 &= ~SCFCR2_MCE;
}
SHREG_SCBRR2 = divrnd(PCLOCK, 32 * ospeed) -1;
SHREG_SCBRR2 = divrnd(sh_clock_get_pclock(), 32 * ospeed) -1;
/*
* Set the FIFO threshold based on the receive speed.

View File

@ -0,0 +1,89 @@
/* $NetBSD: clock.h,v 1.1 2002/02/22 19:44:01 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* void sh_clock_init(int flags, struct rtc_ops *):
* flags:
* SH_CLOCK_NORTC ... If SH RTC module is disabled, set this.
* internal module don't use RTCCLK.
* SH_CLOCK_NOINITTODR ... Don't initialize RTC time.
* rtc_ops:
* Machine dependent RTC ops pointer. If NULL is specified, use SH
* internal RTC.
*
* void machine_clock_init(void):
* Implement machine specific part of clock routines.
* must call sh_clock_init() at exit.
*
* int sh_clock_get_cpuclock(void):
* returns CPU clock estimated by sh_clock_init().
*
* int sh_clock_get_pclock(void):
* returns PCLOCK. when PCLOCK is not specified by kernel configuration
* file, this value is estimated by sh_clock_init().
*
*/
struct rtc_ops;
struct clock_ymdhms;
void sh_clock_init(int, struct rtc_ops *);
#define SH_CLOCK_NORTC 0x00000001
#define SH_CLOCK_NOINITTODR 0x00000002
void machine_clock_init(void);
int sh_clock_get_cpuclock(void);
int sh_clock_get_pclock(void);
/*
* SH RTC module interface.
*/
void sh_rtc_init(void *);
void sh_rtc_get(void *, time_t, struct clock_ymdhms *);
void sh_rtc_set(void *, struct clock_ymdhms *);
/*
* machine specific RTC ops
*/
struct clock_ymdhms;
struct rtc_ops {
void *_cookie;
void (*init)(void *);
void (*get)(void *, time_t, struct clock_ymdhms *);
void (*set)(void *, struct clock_ymdhms *);
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.17 2002/02/19 17:22:34 uch Exp $ */
/* $NetBSD: cpu.h,v 1.18 2002/02/22 19:44:02 uch Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -178,8 +178,6 @@ void sh3_startup(void);
void delay(int);
struct pcb;
void savectx(struct pcb *);
void startrtclock(void);
#endif /* _KERNEL */
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc.h,v 1.12 2002/02/19 17:21:20 uch Exp $ */
/* $NetBSD: cpufunc.h,v 1.13 2002/02/22 19:44:02 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -62,7 +62,10 @@ void _cpu_intr_resume(u_int32_t);
u_int32_t _cpu_exception_suspend(void);
void _cpu_exception_resume(u_int32_t);
/* Hard reset */
/* for delay loop. */
void _cpu_spin(u_int32_t);
/* Soft reset */
void cpu_reset(void);
#endif /* !_LOCORE */

View File

@ -1,4 +1,4 @@
/* $NetBSD: mmu.h,v 1.1 2002/02/17 20:55:50 uch Exp $ */
/* $NetBSD: mmu.h,v 1.2 2002/02/22 19:44:02 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -61,6 +61,7 @@
*/
extern void sh_mmu_init(void);
extern void sh_mmu_information(void);
extern void (*__sh_mmu_start)(void);
extern void sh3_mmu_start(void);

View File

@ -1,5 +1,4 @@
/* $Id: rtcreg.h,v 1.4 2001/04/22 16:50:17 uch Exp $ */
/* $NetBSD: rtcreg.h,v 1.4 2001/04/22 16:50:17 uch Exp $ */
/* $NetBSD: rtcreg.h,v 1.5 2002/02/22 19:44:02 uch Exp $ */
/*-
* Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
@ -31,67 +30,53 @@
#define _SH3_RTCREG_H__
/*
* Real Time Clock
* RTC
*/
#define SH3_R64CNT 0xfffffec0
#define SH3_RSECCNT 0xfffffec2
#define SH3_RMINCNT 0xfffffec4
#define SH3_RHRCNT 0xfffffec6
#define SH3_RWKCNT 0xfffffec8
#define SH3_RDAYCNT 0xfffffeca
#define SH3_RMONCNT 0xfffffecc
#define SH3_RYRCNT 0xfffffece
#define SH3_RSECAR 0xfffffed0
#define SH3_RMINAR 0xfffffed2
#define SH3_RHRAR 0xfffffed4
#define SH3_RWKAR 0xfffffed6
#define SH3_RDAYAR 0xfffffed8
#define SH3_RMONAR 0xfffffeda
#define SH3_RCR1 0xfffffedc
#define SH3_RCR2 0xfffffede
#if !defined(SH4)
#define SH4_R64CNT 0xffc80000
#define SH4_RSECCNT 0xffc80004
#define SH4_RMINCNT 0xffc80008
#define SH4_RHRCNT 0xffc8000c
#define SH4_RWKCNT 0xffc80010
#define SH4_RDAYCNT 0xffc80014
#define SH4_RMONCNT 0xffc80018
#define SH4_RYRCNT 0xffc8001c /* 16 bit */
#define SH4_RSECAR 0xffc80020
#define SH4_RMINAR 0xffc80024
#define SH4_RHRAR 0xffc80028
#define SH4_RWKAR 0xffc8002c
#define SH4_RDAYAR 0xffc80030
#define SH4_RMONAR 0xffc80034
#define SH4_RCR1 0xffc80038
#define SH4_RCR2 0xffc8003c
/* SH3 definitions */
#define SHREG_R64CNT (*(volatile unsigned char *) 0xFFFFFEC0)
#define SHREG_RSECCNT (*(volatile unsigned char *) 0xFFFFFEC2)
#define SHREG_RMINCNT (*(volatile unsigned char *) 0xFFFFFEC4)
#define SHREG_RHRCNT (*(volatile unsigned char *) 0xFFFFFEC6)
#define SHREG_RWKCNT (*(volatile unsigned char *) 0xFFFFFEC8)
#define SHREG_RDAYCNT (*(volatile unsigned char *) 0xFFFFFECA)
#define SHREG_RMONCNT (*(volatile unsigned char *) 0xFFFFFECC)
#define SHREG_RYRCNT (*(volatile unsigned char *) 0xFFFFFECE)
#define SHREG_RSECAR (*(volatile unsigned char *) 0xFFFFFED0)
#define SHREG_RMINAR (*(volatile unsigned char *) 0xFFFFFED2)
#define SHREG_RHRAR (*(volatile unsigned char *) 0xFFFFFED4)
#define SHREG_RWKAR (*(volatile unsigned char *) 0xFFFFFED6)
#define SHREG_RDAYAR (*(volatile unsigned char *) 0xFFFFFED8)
#define SHREG_RMONAR (*(volatile unsigned char *) 0xFFFFFEDA)
#define SHREG_RCR1 (*(volatile unsigned char *) 0xFFFFFEDC)
#define SHREG_RCR2 (*(volatile unsigned char *) 0xFFFFFEDE)
#else
/* SH4 definitions */
#define SHREG_R64CNT (*(volatile unsigned char *) 0xffc80000)
#define SHREG_RSECCNT (*(volatile unsigned char *) 0xffc80004)
#define SHREG_RMINCNT (*(volatile unsigned char *) 0xffc80008)
#define SHREG_RHRCNT (*(volatile unsigned char *) 0xffc8000c)
#define SHREG_RWKCNT (*(volatile unsigned char *) 0xffc80010)
#define SHREG_RDAYCNT (*(volatile unsigned char *) 0xffc80014)
#define SHREG_RMONCNT (*(volatile unsigned char *) 0xffc80018)
#define SHREG_RYRCNT (*(volatile unsigned short *) 0xffc8001c)
#define SHREG_RSECAR (*(volatile unsigned char *) 0xffc80020)
#define SHREG_RMINAR (*(volatile unsigned char *) 0xffc80024)
#define SHREG_RHRAR (*(volatile unsigned char *) 0xffc80028)
#define SHREG_RWKAR (*(volatile unsigned char *) 0xffc8002c)
#define SHREG_RDAYAR (*(volatile unsigned char *) 0xffc80030)
#define SHREG_RMONAR (*(volatile unsigned char *) 0xffc80034)
#define SHREG_RCR1 (*(volatile unsigned char *) 0xffc80038)
#define SHREG_RCR2 (*(volatile unsigned char *) 0xffc8003c)
#endif
#define SHREG_RCR1_CF 0x80
#define SHREG_RCR1_CIE 0x10
#define SHREG_RCR1_AIE 0x08
#define SHREG_RCR1_AF 0x01
#define SHREG_RCR2_PEF 0x80
#define SHREG_RCR2_PES2 0x40
#define SHREG_RCR2_PES1 0x20
#define SHREG_RCR2_PES0 0x10
#define SHREG_RCR2_ENABLE 0x08
#define SHREG_RCR2_ADJ 0x04
#define SHREG_RCR2_RESET 0x02
#define SHREG_RCR2_START 0x01
#define SHREG_RCR2_P64 (SHREG_RCR2_PES1)
#define SH_RCR1_CF 0x80
#define SH_RCR1_CIE 0x10
#define SH_RCR1_AIE 0x08
#define SH_RCR1_AF 0x01
#define SH_RCR2_PEF 0x80
#define SH_RCR2_PES2 0x40
#define SH_RCR2_PES1 0x20
#define SH_RCR2_PES0 0x10
#define SH_RCR2_ENABLE 0x08
#define SH_RCR2_ADJ 0x04
#define SH_RCR2_RESET 0x02
#define SH_RCR2_START 0x01
#endif /* !_SH3_RTCREG_H__ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: tmureg.h,v 1.4 2000/03/20 20:36:58 msaitoh Exp $ */
/* $NetBSD: tmureg.h,v 1.5 2002/02/22 19:44:02 uch Exp $ */
/*-
* Copyright (C) 1999 SAITOH Masanobu. All rights reserved.
@ -30,87 +30,56 @@
#define _SH3_TMUREG_H_
/*
* Timer Unit
* TMU
*/
#define SH3_TOCR 0xfffffe90
#define SH3_TSTR 0xfffffe92
#define SH3_TCOR0 0xfffffe94
#define SH3_TCNT0 0xfffffe98
#define SH3_TCR0 0xfffffe9c
#define SH3_TCOR1 0xfffffea0
#define SH3_TCNT1 0xfffffea4
#define SH3_TCR1 0xfffffea8
#define SH3_TCOR2 0xfffffeac
#define SH3_TCNT2 0xfffffeb0
#define SH3_TCR2 0xfffffeb4
#define SH3_TCPR2 0xfffffeb8
#if !defined(SH4)
#define SH4_TOCR 0xffd80000
#define SH4_TSTR 0xffd80004
#define SH4_TCOR0 0xffd80008
#define SH4_TCNT0 0xffd8000c
#define SH4_TCR0 0xffd80010
#define SH4_TCOR1 0xffd80014
#define SH4_TCNT1 0xffd80018
#define SH4_TCR1 0xffd8001c
#define SH4_TCOR2 0xffd80020
#define SH4_TCNT2 0xffd80024
#define SH4_TCR2 0xffd80028
#define SH4_TCPR2 0xffd8002c
/* SH3 definition */
/* common */
#define SHREG_TOCR (*(volatile unsigned char *) 0xfffffe90)
#define SHREG_TSTR (*(volatile unsigned char *) 0xfffffe92)
/* ch. 0 */
#define SHREG_TCOR0 (*(volatile unsigned int *) 0xfffffe94)
#define SHREG_TCNT0 (*(volatile unsigned int *) 0xfffffe98)
#define SHREG_TCR0 (*(volatile unsigned short *) 0xfffffe9c)
/* ch. 1 */
#define SHREG_TCOR1 (*(volatile unsigned int *) 0xfffffea0)
#define SHREG_TCNT1 (*(volatile unsigned int *) 0xfffffea4)
#define SHREG_TCR1 (*(volatile unsigned short *) 0xfffffea8)
/* ch. 2 */
#define SHREG_TCOR2 (*(volatile unsigned int *) 0xfffffeac)
#define SHREG_TCNT2 (*(volatile unsigned int *) 0xfffffeb0)
#define SHREG_TCR2 (*(volatile unsigned short *) 0xfffffeb4)
#define SHREG_TCPR2 (*(volatile unsigned int *) 0xfffffeb8)
#else
/* SH4 address definition */
/* common */
#define SHREG_TOCR (*(volatile unsigned char *) 0xffd80000)
#define SHREG_TSTR (*(volatile unsigned char *) 0xffd80004)
/* ch. 0 */
#define SHREG_TCOR0 (*(volatile unsigned int *) 0xffd80008)
#define SHREG_TCNT0 (*(volatile unsigned int *) 0xffd8000c)
#define SHREG_TCR0 (*(volatile unsigned short *) 0xffd80010)
/* ch. 1 */
#define SHREG_TCOR1 (*(volatile unsigned int *) 0xffd80014)
#define SHREG_TCNT1 (*(volatile unsigned int *) 0xffd80018)
#define SHREG_TCR1 (*(volatile unsigned short *) 0xffd8001c)
/* ch. 2 */
#define SHREG_TCOR2 (*(volatile unsigned int *) 0xffd80020)
#define SHREG_TCNT2 (*(volatile unsigned int *) 0xffd80024)
#define SHREG_TCR2 (*(volatile unsigned short *) 0xffd80028)
#define SHREG_TCPR2 (*(volatile unsigned int *) 0xffd8002c)
#endif
#define TOCR_TCOE 0x01
#define TSTR_STR2 0x04
#define TSTR_STR1 0x02
#define TSTR_STR0 0x01
#define TCR_ICPF 0x0200
#define TCR_UNF 0x0100
#define TCR_ICPE1 0x0080
#define TCR_ICPE0 0x0040
#define TCR_UNIE 0x0020
#define TCR_CKEG1 0x0010
#define TCR_CKEG0 0x0008
#define TCR_TPSC2 0x0004
#define TCR_TPSC1 0x0002
#define TCR_TPSC0 0x0001
#define TCR_TPSC_P4 0x0000
#define TCR_TPSC_P16 0x0001
#define TCR_TPSC_P64 0x0002
#define TCR_TPSC_P256 0x0003
#if !defined(SH4)
#define TCR_TPSC_RTC 0x0004
#define TCR_TPSC_TCLK 0x0005
#else
#define TCR_TPSC_P512 0x0004
#define TCR_TPSC_RTC 0x0006
#define TCR_TPSC_TCLK 0x0007
#endif
#define TOCR_TCOE 0x01
#define TSTR_STR2 0x04
#define TSTR_STR1 0x02
#define TSTR_STR0 0x01
#define TCR_ICPF 0x0200
#define TCR_UNF 0x0100
#define TCR_ICPE1 0x0080
#define TCR_ICPE0 0x0040
#define TCR_UNIE 0x0020
#define TCR_CKEG1 0x0010
#define TCR_CKEG0 0x0008
#define TCR_TPSC2 0x0004
#define TCR_TPSC1 0x0002
#define TCR_TPSC0 0x0001
#define TCR_TPSC_P4 0x0000
#define TCR_TPSC_P16 0x0001
#define TCR_TPSC_P64 0x0002
#define TCR_TPSC_P256 0x0003
#define SH3_TCR_TPSC_RTC 0x0004
#define SH3_TCR_TPSC_TCLK 0x0005
#define SH4_TCR_TPSC_P512 0x0004
#define SH4_TCR_TPSC_RTC 0x0006
#define SH4_TCR_TPSC_TCLK 0x0007
#endif /* !_SH3_TMUREG_H_ */

View File

@ -1,12 +1,11 @@
/* $NetBSD: clock.c,v 1.20 2002/02/19 17:21:18 uch Exp $ */
/* $NetBSD: clock.c,v 1.21 2002/02/22 19:44:04 uch Exp $ */
/*-
* Copyright (c) 1993, 1994 Charles Hannum.
* Copyright (c) 1990 The Regents of the University of California.
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz and Don Ahn.
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -18,463 +17,587 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)clock.c 7.2 (Berkeley) 5/12/91
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Primitive clock interrupt routines.
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_pclock.h"
#include "wdog.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <dev/clock_subr.h>
#include <sh3/pclock.h>
#include <sh3/rtcreg.h>
#include <sh3/cpufunc.h>
#include <sh3/clock.h>
#include <sh3/tmureg.h>
#include <sh3/rtcreg.h>
#include <sh3/wdogvar.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/cpufunc.h>
#include <sh3/wdtreg.h>
#include <machine/shbvar.h>
void findcpuspeed(void);
int clockintr(void *);
int gettick(void);
void rtcinit(void);
/* RTC */
#if defined(SH3) && defined(SH4)
int __sh_R64CNT;
int __sh_RSECCNT;
int __sh_RMINCNT;
int __sh_RHRCNT;
int __sh_RWKCNT;
int __sh_RDAYCNT;
int __sh_RMONCNT;
int __sh_RYRCNT;
int __sh_RSECAR;
int __sh_RMINAR;
int __sh_RHRAR;
int __sh_RWKAR;
int __sh_RDAYAR;
int __sh_RMONAR;
int __sh_RCR1;
int __sh_RCR2;
int timer0speed;
/* TMU */
int __sh_TOCR;
int __sh_TSTR;
int __sh_TCOR0;
int __sh_TCNT0;
int __sh_TCR0;
int __sh_TCOR1;
int __sh_TCNT1;
int __sh_TCR1;
int __sh_TCOR2;
int __sh_TCNT2;
int __sh_TCR2;
int __sh_TCPR2;
static void clock_register_init(void);
#endif /* SH3 && SH4 */
#if defined(SH3) && defined(SH4)
#define SH_(x) __sh_ ## x
#elif defined(SH3)
#define SH_(x) SH3_ ## x
#elif defined(SH4)
#define SH_(x) SH4_ ## x
#endif
#ifndef HZ
#define HZ 64
#endif
#define MINYEAR 2002 /* "today" */
#define SH_RTC_CLOCK 16384 /* Hz */
/*
* microtime() makes use of the following globals. Note that isa_timer_tick
* may be redundant to the `tick' variable, but is kept here for stability.
* isa_timer_count is the countdown count for the timer. timer_msb_table[]
* and timer_lsb_table[] are used to compute the microsecond increment
* for time.tv_usec in the follow fashion:
*
* time.tv_usec += isa_timer_msb_table[cnt_msb] - isa_timer_lsb_table[cnt_lsb];
* NetBSD/sh3 clock module
* + default 64Hz
* + use TMU channel 0 as clock interrupt source.
* + If RTC module is active, TMU channel 0 input source is RTC output.
* (1.6384kHz)
*/
struct {
/* Hard clock */
u_int32_t hz_cnt; /* clock interrupt interval count */
u_int32_t cpucycle_1us; /* calibrated loop variable (1 us) */
u_int32_t tmuclk; /* source clock of TMU0 (Hz) */
/* RTC ops holder. default SH RTC module */
struct rtc_ops rtc;
int rtc_initialized;
u_int32_t pclock; /* PCLOCK */
u_int32_t cpuclock; /* CPU clock */
int flags;
} sh_clock = {
#ifdef PCLOCK
.pclock = PCLOCK,
#endif
.rtc = {
/* SH RTC module to default RTC */
.init = sh_rtc_init,
.get = sh_rtc_get,
.set = sh_rtc_set
}
};
u_int32_t maxwdog;
/* TMU */
/* interrupt handler is timing critical. prepared for each. */
int sh3_clock_intr(void *);
int sh4_clock_intr(void *);
/*
* Estimate CPU and Peripheral clock.
*/
#define TMU_START(x) \
do { \
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) & ~TSTR_STR##x); \
_reg_write_4(SH_(TCNT ## x), 0xffffffff); \
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) | TSTR_STR##x); \
} while (/*CONSTCOND*/0)
#define TMU_ELAPSED(x) \
(0xffffffff - _reg_read_4(SH_(TCNT ## x)))
void
startrtclock()
sh_clock_init(int flags, struct rtc_ops *rtc)
{
u_int32_t s, t0, t1 __attribute__((__unused__));
sh_clock.flags = flags;
if (rtc != NULL)
sh_clock.rtc = *rtc; /* structure copy */
#if defined(SH3) && defined(SH4)
clock_register_init();
#endif
/* Initialize TMU */
_reg_write_2(SH_(TCR0), 0);
_reg_write_2(SH_(TCR1), 0);
_reg_write_2(SH_(TCR2), 0);
/* Reset RTC alarm and interrupt */
_reg_write_1(SH_(RCR1), 0);
/* Stop all counter */
_reg_write_1(SH_(TSTR), 0);
/*
* Estimate CPU clock.
*/
if (sh_clock.flags & SH_CLOCK_NORTC) {
/* Set TMU channel 0 source to PCLOCK / 16 */
_reg_write_2(SH_(TCR0), TCR_TPSC_P16);
sh_clock.tmuclk = sh_clock.pclock / 16;
} else {
/* Set TMU channel 0 source to RTC counter clock (16.384kHz) */
_reg_write_2(SH_(TCR0),
CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC);
sh_clock.tmuclk = SH_RTC_CLOCK;
}
s = _cpu_exception_suspend();
_cpu_spin(1); /* load function on cache. */
TMU_START(0);
_cpu_spin(10000000);
t0 = TMU_ELAPSED(0);
_cpu_exception_resume(s);
sh_clock.cpuclock = ((10000000 * 10) / t0) * sh_clock.tmuclk;
sh_clock.cpucycle_1us = (sh_clock.tmuclk * 10) / t0;
if (CPU_IS_SH4)
sh_clock.cpuclock >>= 1; /* two-issue */
/*
* Estimate PCLOCK
*/
if (sh_clock.pclock == 0) {
/* set TMU channel 1 source to PCLOCK / 4 */
_reg_write_2(SH_(TCR1), TCR_TPSC_P4);
s = _cpu_exception_suspend();
_cpu_spin(1); /* load function on cache. */
TMU_START(0);
TMU_START(1);
_cpu_spin(sh_clock.cpucycle_1us * 1000000); /* 1 sec. */
t0 = TMU_ELAPSED(0);
t1 = TMU_ELAPSED(1);
_cpu_exception_resume(s);
sh_clock.pclock = ((t1 * 4)/ t0) * SH_RTC_CLOCK;
}
/* Stop all counter */
_reg_write_1(SH_(TSTR), 0);
#undef TMU_START
#undef TMU_ELAPSED
}
int
sh_clock_get_cpuclock()
{
findcpuspeed(); /* use the clock (while it's free)
to find the cpu speed */
return (sh_clock.cpuclock);
}
int
sh_clock_get_pclock()
{
return (sh_clock.pclock);
}
void
setstatclockrate(int newhz)
{
/* XXX not yet */
}
/*
* Fill in *tvp with current time with microsecond resolution.
* Return the best possible estimate of the time in the timeval to
* which tv points.
*/
void
microtime(struct timeval *tvp)
microtime(struct timeval *tv)
{
int s = splclock();
long diff;
static struct timeval lasttime;
static u_long numerator = 0;
static u_long denominator = 0;
/*
* 1/hz resolution ``time'' which is counted up at hardclock().
*/
*tvp = time;
/*
* diff = (PCLOCK/16/hz - 1 - SHREG_TCNT1) / (PCLOCK/16/hz - 1)
* * 1/hz * 10^6. [usec]
*/
if (denominator == 0) {
numerator = 1000000 / hz;
denominator = PCLOCK/16/hz - 1;
}
diff = (denominator - SHREG_TCNT1) * numerator / denominator;
/*
* add ``diff'' to ``time''
*/
tvp->tv_usec += diff;
while (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
/*
* microtime() always gains 1usec at least.
*/
if (tvp->tv_sec == lasttime.tv_sec &&
tvp->tv_usec <= lasttime.tv_usec &&
(tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
tvp->tv_sec++;
tvp->tv_usec -= 1000000;
}
lasttime = *tvp;
int s;
s = splclock();
*tv = time;
splx(s);
}
#include <sh3/wdtreg.h>
unsigned int maxwdog;
tv->tv_usec += ((sh_clock.hz_cnt - _reg_read_4(SH_(TCNT0)))
* 1000000) / sh_clock.tmuclk;
while (tv->tv_usec >= 1000000) {
tv->tv_usec -= 1000000;
tv->tv_sec++;
}
int
clockintr(void *arg)
{
struct clockframe *frame = arg; /* not strictly necessary */
#if (NWDOG > 0)
unsigned int i;
i = (unsigned int)SHREG_WTCNT_R;
if (i > maxwdog)
maxwdog = i;
wdog_wr_cnt(0); /* reset to zero */
#endif
/* clear timer counter under flow interrupt flag */
#ifdef USE_RTCCLK
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_RTC;
#else
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_P16;
#endif
hardclock(frame);
return -1;
}
int
gettick()
{
int counter;
/* Don't want someone screwing with the counter while we're here. */
_cpu_exception_suspend();
counter = SHREG_TCNT0;
_cpu_exception_resume(0);
return counter;
if (tv->tv_sec == lasttime.tv_sec &&
tv->tv_usec <= lasttime.tv_usec &&
(tv->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
tv->tv_usec -= 1000000;
tv->tv_sec++;
}
lasttime = *tv;
}
/*
* Wait "n" microseconds.
* Relies on timer 1 counting down from (TIMER_FREQ / hz) at TIMER_FREQ Hz.
* Note: timer had better have been programmed before this is first used!
* (Note that we use `rate generator' mode, which counts at 1:1; `square
* wave' mode counts at 2:1).
* Wait at least `n' usec.
*/
void
delay(int n)
{
unsigned int limit, tick, otick;
/*
* Read the counter first, so that the rest of the setup overhead is
* counted.
*/
n *= timer0speed;
otick = gettick();
limit = 0xffffffff;
while (n > 0) {
tick = gettick();
if (tick > otick)
n -= limit - (tick - otick);
else
n -= otick - tick;
otick = tick;
}
}
unsigned int delaycount; /* calibrated loop variable (1 millisecond) */
#define FIRST_GUESS 0x2000
void
findcpuspeed()
{
int i;
unsigned int remainder;
/* using clock = Internal RTC */
SHREG_TOCR = TOCR_TCOE;
/* disable Under Flow int,up rising edge, 1/4 Cys */
SHREG_TCR0 = 0;
timer0speed = PCLOCK / 1000000 / 4 + 1;
/* set counter */
SHREG_TCNT0 = 0xffffffff;
/* start counter 0 */
SHREG_TSTR |= TSTR_STR0;
/* Timer counter is decremented at every 0.5 uSec */
for (i = FIRST_GUESS; i; i--)
;
/* Read the value left in the counter */
remainder = gettick();
/* 1 timer tick neary eqyal 0.5 uSec */
delaycount = (FIRST_GUESS * 2000) / (0xffffffff - remainder);
_cpu_spin(sh_clock.cpucycle_1us * n);
}
/*
* Start the clock interrupt.
*/
void
cpu_initclocks()
{
#ifdef USE_RTCCLK
/* enable under flow interrupt, up rising edge, RTCCLK */
/* RTCCLK == 16kHz */
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_RTC;
SHREG_TCOR1 = 16384 / hz - 1; /* about 1/HZ Sec */
SHREG_TCNT1 = 16384 / hz - 1; /* about 1/HZ Sec */
#else
/* enable under flow interrupt, up rising edge, 1/16 Pcyc */
SHREG_TCR1 = TCR_UNIE | TCR_TPSC_P16;
SHREG_TCOR1 = PCLOCK / 16 / hz - 1; /* about 1/HZ Sec */
SHREG_TCNT1 = PCLOCK / 16 / hz - 1; /* about 1/HZ Sec */
#endif
if (sh_clock.pclock == 0)
panic("No PCLOCK information.");
/* start timer counter 1 */
SHREG_TSTR |= TSTR_STR1;
/* Set global variables. */
hz = HZ;
tick = 1000000 / hz;
(void)shb_intr_establish(TMU1_IRQ, IST_EDGE, IPL_CLOCK, clockintr, 0);
/*
* Use TMU channel 0 as hard clock
*/
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) & ~TSTR_STR0);
if (sh_clock.flags & SH_CLOCK_NORTC) {
/* use PCLOCK/16 as TMU0 source */
_reg_write_2(SH_(TCR0), TCR_UNIE | TCR_TPSC_P16);
} else {
/* use RTC clock as TMU0 source */
_reg_write_2(SH_(TCR0), TCR_UNIE |
(CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC));
}
sh_clock.hz_cnt = sh_clock.tmuclk / hz - 1;
_reg_write_4(SH_(TCOR0), sh_clock.hz_cnt);
_reg_write_4(SH_(TCNT0), sh_clock.hz_cnt);
shb_intr_establish(TMU0_IRQ, IST_EDGE, IPL_CLOCK,
CPU_IS_SH3 ? sh3_clock_intr : sh4_clock_intr, 0);
/* start hardclock */
_reg_write_1(SH_(TSTR), _reg_read_1(SH_(TSTR)) | TSTR_STR0);
/*
* TMU channel 1, 2 are one shot timer.
*/
_reg_write_2(SH_(TCR1), TCR_UNIE | TCR_TPSC_P4);
_reg_write_4(SH_(TCOR1), 0xffffffff);
_reg_write_2(SH_(TCR2), TCR_UNIE | TCR_TPSC_P4);
_reg_write_4(SH_(TCOR2), 0xffffffff);
/* Make sure to start RTC */
sh_clock.rtc.init(sh_clock.rtc._cookie);
}
void
rtcinit()
{
static int first_rtcopen_ever = 1;
if (!first_rtcopen_ever)
return;
first_rtcopen_ever = 0;
}
static int timeset;
/*
* Initialize the time of day register, based on the time base which is, e.g.
* from a filesystem.
*/
void
inittodr(time_t base)
{
struct clock_ymdhms dt;
int doreset = 0;
time_t rtc;
int s;
/*
* We mostly ignore the suggested time and go for the RTC clock time
* stored in the CMOS RAM. If the time can't be obtained from the
* CMOS, or if the time obtained from the CMOS is 5 or more years
* less than the suggested time, we used the suggested time. (In
* the latter case, it's likely that the CMOS battery has died.)
*/
if (!sh_clock.rtc_initialized)
sh_clock.rtc_initialized = 1;
if (base < 15*SECYR) { /* if before 1985, something's odd... */
printf("WARNING: preposterous time in file system\n");
/* read the system clock anyway */
base = 17*SECYR + 186*SECDAY + SECDAY/2;
}
#ifdef SH4
#define FROMBCD2(x) ((((x) & 0xf000) >> 12) * 1000 + \
(((x) & 0x0f00) >> 8) * 100 + \
(((x) & 0x00f0) >> 4) * 10 + ((x) & 0xf))
dt.dt_year = FROMBCD2(SHREG_RYRCNT);
#else
dt.dt_year = 1900 + FROMBCD(SHREG_RYRCNT);
#endif
dt.dt_mon = FROMBCD(SHREG_RMONCNT);
dt.dt_day = FROMBCD(SHREG_RDAYCNT);
dt.dt_wday = FROMBCD(SHREG_RWKCNT);
dt.dt_hour = FROMBCD(SHREG_RHRCNT);
dt.dt_min = FROMBCD(SHREG_RMINCNT);
dt.dt_sec = FROMBCD(SHREG_RSECCNT);
sh_clock.rtc.get(sh_clock.rtc._cookie, base, &dt);
rtc = clock_ymdhms_to_secs(&dt);
#ifdef DEBUG
printf("readclock: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year - 1900,
dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
dt.dt_wday);
printf("inittodr: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year,
dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
dt.dt_wday);
#endif
#ifndef SH4
if (dt.dt_year < 1970)
dt.dt_year += 100;
#endif
if (dt.dt_mon < 1 || dt.dt_mon > 12)
doreset = 1;
if (dt.dt_day < 1 || dt.dt_day > 31)
doreset = 1;
if (dt.dt_hour > 23)
doreset = 1;
if (dt.dt_min > 59)
doreset = 1;
if (dt.dt_sec > 59)
doreset = 1;
if (doreset == 1) {
printf("WARNING: clock time is invalid.\n");
printf("WARNING: reset to epoch time!\n");
time.tv_sec = 0;
} else
time.tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60;
#ifndef INITTODR_ALWAYS_USE_RTC
if (base < time.tv_sec - 5*SECYR)
printf("WARNING: file system time much less than clock time\n");
else if (base > time.tv_sec + 5*SECYR) {
printf("WARNING: clock time much less than file system time\n");
printf("WARNING: using file system time\n");
goto fstime;
if (!(sh_clock.flags & SH_CLOCK_NOINITTODR) &&
(rtc < base ||
dt.dt_year < MINYEAR || dt.dt_year > 2037 ||
dt.dt_mon < 1 || dt.dt_mon > 12 ||
dt.dt_wday > 6 ||
dt.dt_day < 1 || dt.dt_day > 31 ||
dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59)) {
/*
* Believe the time in the file system for lack of
* anything better, resetting the RTC.
*/
s = splclock();
time.tv_sec = base;
time.tv_usec = 0;
splx(s);
printf("WARNING: preposterous clock chip time\n");
resettodr();
printf(" -- CHECK AND RESET THE DATE!\n");
return;
}
#endif
timeset = 1;
s = splclock();
time.tv_sec = rtc + rtc_offset * 60;
time.tv_usec = 0;
splx(s);
return;
#ifndef INITTODR_ALWAYS_USE_RTC
fstime:
timeset = 1;
time.tv_sec = base;
time.tv_usec = 0;
printf("WARNING: CHECK AND RESET THE DATE!\n");
#endif
}
/*
* Reset the clock.
*/
void
resettodr()
{
struct clock_ymdhms dt;
int s;
/*
* We might have been called by boot() due to a crash early
* on. Don't reset the clock chip in this case.
*/
if (!timeset)
if (!sh_clock.rtc_initialized)
return;
s = splclock();
clock_secs_to_ymdhms(time.tv_sec - rtc_offset * 60, &dt);
/* stop RTC */
SHREG_RCR2 = SHREG_RCR2_RESET|SHREG_RCR2_ENABLE;
SHREG_RSECCNT = TOBCD(dt.dt_sec);
SHREG_RMINCNT = TOBCD(dt.dt_min);
SHREG_RHRCNT = TOBCD(dt.dt_hour);
SHREG_RWKCNT = TOBCD(dt.dt_wday);
SHREG_RDAYCNT = TOBCD(dt.dt_day);
SHREG_RMONCNT = TOBCD(dt.dt_mon);
#ifdef SH4
#define TOBCD2(x) ((((x) % 10000) / 1000 * 4096) + \
(((x) % 1000) / 100 * 256) + \
((((x) % 100) / 10) * 16) + ((x) % 10))
SHREG_RYRCNT = TOBCD2(dt.dt_year);
#else
SHREG_RYRCNT = TOBCD(dt.dt_year % 100);
#endif
/* start RTC */
SHREG_RCR2 = SHREG_RCR2_RESET|SHREG_RCR2_ENABLE|SHREG_RCR2_START;
splx(s);
sh_clock.rtc.set(sh_clock.rtc._cookie, &dt);
#ifdef DEBUG
printf("setclock: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year % 100,
dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
dt.dt_wday);
printf("%s: %d/%d/%d/%d/%d/%d(%d) rtc_offset %d\n", __FUNCTION__,
dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec,
dt.dt_wday, rtc_offset);
#endif
}
#ifdef SH3
int
sh3_clock_intr(void *arg) /* trap frame */
{
#if (NWDOG > 0)
u_int32_t i;
i = (u_int32_t)SHREG_WTCNT_R;
if (i > maxwdog)
maxwdog = i;
wdog_wr_cnt(0); /* reset to zero */
#endif
/* clear underflow status */
_reg_write_2(SH3_TCR0, _reg_read_2(SH3_TCR0) & ~TCR_UNF);
hardclock(arg);
return (1);
}
#endif /* SH3 */
#ifdef SH4
int
sh4_clock_intr(void *arg) /* trap frame */
{
#if (NWDOG > 0)
u_int32_t i;
i = (u_int32_t)SHREG_WTCNT_R;
if (i > maxwdog)
maxwdog = i;
wdog_wr_cnt(0); /* reset to zero */
#endif
/* clear underflow status */
_reg_write_2(SH4_TCR0, _reg_read_2(SH4_TCR0) & ~TCR_UNF);
hardclock(arg);
return (1);
}
#endif /* SH4 */
/*
* SH3 RTC module ops.
*/
void
sh_rtc_init(void *cookie)
{
/* Make sure to start RTC */
_reg_write_1(SH_(RCR2), SH_RCR2_ENABLE | SH_RCR2_START);
}
void
setstatclockrate(int arg)
sh_rtc_get(void *cookie, time_t base, struct clock_ymdhms *dt)
{
int retry = 8;
/* disable carry interrupt */
_reg_write_1(SH_(RCR1), _reg_read_1(SH_(RCR1)) & ~SH_RCR1_CIE);
do {
u_int8_t r = _reg_read_1(SH_(RCR1));
r &= ~SH_RCR1_CF;
r |= SH_RCR1_AF; /* don't clear alarm flag */
_reg_write_1(SH_(RCR1), r);
if (CPU_IS_SH3)
dt->dt_year = FROMBCD(_reg_read_1(SH3_RYRCNT));
else
dt->dt_year = FROMBCD(_reg_read_2(SH4_RYRCNT) & 0x00ff);
/* read counter */
#define RTCGET(x, y) dt->dt_ ## x = FROMBCD(_reg_read_1(SH_(R ## y ## CNT)))
RTCGET(mon, MON);
RTCGET(wday, WK);
RTCGET(day, DAY);
RTCGET(hour, HR);
RTCGET(min, MIN);
RTCGET(sec, SEC);
#undef RTCGET
} while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0);
if (retry == 0) {
printf("rtc_gettime: couldn't read RTC register.\n");
memset(dt, sizeof(*dt), 0);
return;
}
dt->dt_year = (dt->dt_year % 100) + 1900;
if (dt->dt_year < 1970)
dt->dt_year += 100;
}
void
sh_rtc_set(void *cookie, struct clock_ymdhms *dt)
{
u_int8_t r;
/* stop clock */
r = _reg_read_1(SH_(RCR2));
r |= SH_RCR2_RESET;
r &= ~SH_RCR2_START;
_reg_write_1(SH_(RCR2), r);
/* set time */
if (CPU_IS_SH3)
_reg_write_1(SH3_RYRCNT, TOBCD(dt->dt_year % 100));
else
_reg_write_2(SH4_RYRCNT, TOBCD(dt->dt_year % 100));
#define RTCSET(x, y) _reg_write_1(SH_(R ## x ## CNT), TOBCD(dt->dt_ ## y))
RTCSET(MON, mon);
RTCSET(WK, wday);
RTCSET(DAY, day);
RTCSET(HR, hour);
RTCSET(MIN, min);
RTCSET(SEC, sec);
#undef RTCSET
/* start clock */
_reg_write_1(SH_(RCR2), r | SH_RCR2_START);
}
#if defined(SH3) && defined(SH4)
#define SH3REG(x) __sh_ ## x = SH3_ ## x
#define SH4REG(x) __sh_ ## x = SH4_ ## x
static void
clock_register_init()
{
if (CPU_IS_SH3) {
SH3REG(R64CNT);
SH3REG(RSECCNT);
SH3REG(RMINCNT);
SH3REG(RHRCNT);
SH3REG(RWKCNT);
SH3REG(RDAYCNT);
SH3REG(RMONCNT);
SH3REG(RYRCNT);
SH3REG(RSECAR);
SH3REG(RMINAR);
SH3REG(RHRAR);
SH3REG(RWKAR);
SH3REG(RDAYAR);
SH3REG(RMONAR);
SH3REG(RCR1);
SH3REG(RCR2);
SH3REG(TOCR);
SH3REG(TSTR);
SH3REG(TCOR0);
SH3REG(TCNT0);
SH3REG(TCR0);
SH3REG(TCOR1);
SH3REG(TCNT1);
SH3REG(TCR1);
SH3REG(TCOR2);
SH3REG(TCNT2);
SH3REG(TCR2);
SH3REG(TCPR2);
}
if (CPU_IS_SH4) {
SH4REG(R64CNT);
SH4REG(RSECCNT);
SH4REG(RMINCNT);
SH4REG(RHRCNT);
SH4REG(RWKCNT);
SH4REG(RDAYCNT);
SH4REG(RMONCNT);
SH4REG(RYRCNT);
SH4REG(RSECAR);
SH4REG(RMINAR);
SH4REG(RHRAR);
SH4REG(RWKAR);
SH4REG(RDAYAR);
SH4REG(RMONAR);
SH4REG(RCR1);
SH4REG(RCR2);
SH4REG(TOCR);
SH4REG(TSTR);
SH4REG(TCOR0);
SH4REG(TCNT0);
SH4REG(TCR0);
SH4REG(TCOR1);
SH4REG(TCNT1);
SH4REG(TCR1);
SH4REG(TCOR2);
SH4REG(TCNT2);
SH4REG(TCR2);
SH4REG(TCPR2);
}
}
#undef SH3REG
#undef SH4REG
#endif /* SH3 && SH4 */

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore_subr.S,v 1.1 2002/02/19 17:21:18 uch Exp $ */
/* $NetBSD: locore_subr.S,v 1.2 2002/02/22 19:44:04 uch Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -33,6 +33,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include <machine/asm.h>
.text
@ -98,3 +101,69 @@ NENTRY(_cpu_exception_resume)
ldc r0, sr /* SR = r0 (don't move to delay slot) */
rts
nop
/*
* void _cpu_spin(u_int32_t count)
* loop 'count' * 10 cycle.
* [...]
* add IF ID EX MA WB
* nop IF ID EX MA WB
* cmp/pl IF ID EX MA WB - -
* nop IF ID EX MA - - WB
* bt IF ID EX . . MA WB
* nop IF ID - - EX MA WB
* nop IF - - ID EX MA WB
* nop - - - IF ID EX MA WB
* add IF ID EX MA WB
* nop IF ID EX MA WB
* cmp/pl IF ID EX MA WB - -
* nop IF ID EX MA - - WB
* bt IF ID EX . . MA
* [...]
*/
.align 5 /* align cache line size (32B) */
NENTRY(_cpu_spin)
1: nop /* 1 */
nop /* 2 */
nop /* 3 */
add #-1, r4 /* 4 */
nop /* 5 */
cmp/pl r4 /* 6 */
nop /* 7 */
bt 1b /* 8, 9, 10 */
rts
nop
#if defined(DDB) || defined(KGDB)
/*
* int setjmp(label_t *):
*/
ENTRY(setjmp)
add #4*9, r4
mov.l r8, @-r4
mov.l r9, @-r4
mov.l r10, @-r4
mov.l r11, @-r4
mov.l r12, @-r4
mov.l r13, @-r4
mov.l r14, @-r4
mov.l r15, @-r4
sts.l pr, @-r4
rts
xor r0, r0
/*
* void longjmp(label_t *):
*/
ENTRY(longjmp)
lds.l @r4+, pr
mov.l @r4+, r15
mov.l @r4+, r14
mov.l @r4+, r13
mov.l @r4+, r12
mov.l @r4+, r11
mov.l @r4+, r10
mov.l @r4+, r9
mov.l @r4+, r8
rts
nop
#endif /* DDB || KGDB */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sh3_machdep.c,v 1.24 2002/02/17 20:57:10 uch Exp $ */
/* $NetBSD: sh3_machdep.c,v 1.25 2002/02/22 19:44:05 uch Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@ -99,13 +99,13 @@
#include <sh3/cache.h>
#include <sh3/mmu.h>
#include <sh3/clock.h>
char cpu_model[120];
/*
* if PCLOCK isn't defined in config file, use this.
*/
int sh3_pclock;
int cpu_arch;
int cpu_product;
@ -131,6 +131,9 @@ sh_cpu_init(int arch, int product)
/* MMU access ops. */
sh_mmu_init();
/* Hardclock, RTC initialize. */
machine_clock_init();
}
void
@ -147,7 +150,11 @@ sh3_startup()
printf(version);
sprintf(cpu_model, "Hitachi SH3");
#define MHZ(x) ((x) / 1000000), (((x) % 1000000) / 1000)
sprintf(cpu_model, "HITACHI SH%d %d.%02dMHz PCLOCK %d.%02d MHz",
CPU_IS_SH3 ? 3 : 4, MHZ(sh_clock_get_cpuclock()),
MHZ(sh_clock_get_pclock()));
#undef MHZ
format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
printf("total memory = %s\n", pbuf);
@ -230,6 +237,10 @@ sh3_startup()
* Print cache configuration.
*/
sh_cache_information();
/*
* Print MMU configuration.
*/
sh_mmu_information();
/*
* Set up buffers, so they can be used to read disk labels.