Subject: Re: hardclock(9) for cobalt
To: None <port-cobalt@netbsd.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-cobalt
Date: 08/22/2004 02:17:08
In article <20040817.110641.74750627.kiyohara@kk.iij4u.or.jp>
kiyohara@kk.iij4u.or.jp wrote:
:
> The former is performed. ;-)
I rewrite your patch a bit:
- rename timer_enable() to timer_start()
- no need to make timer_disable() global
- set and pass timer_cookie for an arg for timer_start() and timer_read()
(so that struct gttmr_core is not needed)
- declare timer_*() functions in cpu.h rather than autoconf.h
- use address passed via mainbus_attach_args for GT64111 base address
- I'm not sure gt64111reg.h and gt64111var.h are acceptable for MI part yet,
put them in MD as dev/gtreg.h and dev/gtvar.h for now
- put more register definitions in gtreg.h
etc.
> > > 1. attach gt
> > > 2. attach gttmr
> > > 3. disable timer0
> > > 4. set func pointers
> > > 5. clear INTR_CAUSE register
> >
> > Looks good. Maybe 5. could be done by calling a special
> > function in gt.c.
>
> Is doing by gt_attach() useless?
>
> However, now, gt(4) is not very well. Should gt(4) also be corrected?
Umm...
Well, now I wonder if it's really better to attach the timer in GT64111.
It may be simpler to map whole region of GT64111 and to initialize
all registers in gt_attach() rather than to have separate gttimer
device attachment. I'll rethink how this should be implemented.
In article <20040818.040347.74752442.kiyohara@kk.iij4u.or.jp>
kiyohara@kk.iij4u.or.jp wrote:q
> Is it better to all also write the configuration register of GT64111 ?
If it is confirmed that all other registers are initialized properly
by the firmware, we don't have to reset them again in the device
attachment.
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp
Index: cobalt/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/cobalt/clock.c,v
retrieving revision 1.7
diff -u -r1.7 clock.c
--- cobalt/clock.c 5 Jul 2004 07:28:45 -0000 1.7
+++ cobalt/clock.c 21 Aug 2004 16:50:39 -0000
@@ -34,6 +34,8 @@
#include <sys/kernel.h>
#include <sys/device.h>
+#include <machine/cpu.h>
+
#include <dev/clock_subr.h>
#include <dev/ic/mc146818reg.h>
@@ -47,6 +49,9 @@
cpu_initclocks()
{
+ /* start timer */
+ (*timer_start)(timer_cookie);
+
return;
}
Index: cobalt/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/cobalt/machdep.c,v
retrieving revision 1.51
diff -u -r1.51 machdep.c
--- cobalt/machdep.c 2 Apr 2004 23:18:09 -0000 1.51
+++ cobalt/machdep.c 21 Aug 2004 16:50:39 -0000
@@ -69,6 +69,8 @@
#include <dev/cons.h>
+#include <cobalt/dev/gtreg.h>
+
#ifdef KGDB
#include <sys/kgdb.h>
#endif
@@ -121,7 +123,9 @@
extern caddr_t esym;
extern struct user *proc0paddr;
-
+void (*timer_start)(void *);
+uint32_t (*timer_read)(void *);
+void *timer_cookie;
/*
* Do all the stuff that locore normally does before calling main().
@@ -365,7 +369,7 @@
*tvp = time;
- counter0 = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000850);
+ counter0 = (*timer_read)(timer_cookie);
/*
* XXX
@@ -453,10 +457,11 @@
uvmexp.intrs++;
if (ipending & MIPS_INT_MASK_0) {
+ /* XXX */
volatile u_int32_t *irq_src =
- (u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000c18);
+ (u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000000 + GT_INTR_CAUSE);
- if (*irq_src & 0x00000100) {
+ if (*irq_src & T0EXP) {
*irq_src = 0;
cf.pc = pc;
Index: cobalt/mainbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/cobalt/mainbus.c,v
retrieving revision 1.8
diff -u -r1.8 mainbus.c
--- cobalt/mainbus.c 12 Sep 2003 14:59:13 -0000 1.8
+++ cobalt/mainbus.c 21 Aug 2004 16:50:39 -0000
@@ -106,7 +106,7 @@
return QUIET;
if (ma->ma_addr != MAINBUSCF_ADDR_DEFAULT)
- aprint_normal(" addr 0x%lx", ma->ma_addr);
+ aprint_normal(" addr 0x%x", ma->ma_addr);
if (ma->ma_level != MAINBUSCF_LEVEL_DEFAULT)
aprint_normal(" level %d", ma->ma_level);
Index: conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/conf/GENERIC,v
retrieving revision 1.61
diff -u -r1.61 GENERIC
--- conf/GENERIC 15 Jul 2004 03:53:46 -0000 1.61
+++ conf/GENERIC 21 Aug 2004 16:50:39 -0000
@@ -151,6 +151,7 @@
panel0 at mainbus? addr 0x1f000000
gt0 at mainbus? addr 0x14000000
+gttimer0 at gt0
pci* at gt0
pchb* at pci? dev ? function ?
Index: conf/files.cobalt
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/conf/files.cobalt,v
retrieving revision 1.19
diff -u -r1.19 files.cobalt
--- conf/files.cobalt 17 Oct 2003 18:20:10 -0000 1.19
+++ conf/files.cobalt 21 Aug 2004 16:50:39 -0000
@@ -19,10 +19,15 @@
attach panel at mainbus
file arch/cobalt/dev/panel.c panel
-device gt: pcibus
+define gt {}
+device gt: gt, pcibus
attach gt at mainbus
file arch/cobalt/dev/gt.c gt
+device gttimer
+attach gttimer at gt
+file arch/cobalt/dev/gttimer.c gttimer
+
file arch/cobalt/cobalt/autoconf.c
file arch/cobalt/cobalt/bus.c
file arch/cobalt/cobalt/clock.c
Index: dev/gt.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/dev/gt.c,v
retrieving revision 1.9
diff -u -r1.9 gt.c
--- dev/gt.c 15 Jul 2003 01:29:23 -0000 1.9
+++ dev/gt.c 21 Aug 2004 16:50:39 -0000
@@ -43,14 +43,21 @@
#include <sys/types.h>
#include <sys/device.h>
+#include <machine/autoconf.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <dev/pci/pcivar.h>
+
+#include <cobalt/dev/gtreg.h>
+#include <cobalt/dev/gtvar.h>
+
#include "pci.h"
struct gt_softc {
struct device sc_dev;
+
+ uint32_t sc_addr;
};
static int gt_match(struct device *, struct cfdata *, void *);
@@ -60,6 +67,12 @@
CFATTACH_DECL(gt, sizeof(struct gt_softc),
gt_match, gt_attach, NULL, NULL);
+/* XXX */
+#define GT_READ_REG(sc, reg) \
+ *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1((sc)->sc_addr + (reg))
+#define GT_WRITE_REG(sc, reg, val) \
+ *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1((sc)->sc_addr + (reg)) = (val)
+
static int
gt_match(parent, match, aux)
struct device *parent;
@@ -75,14 +88,32 @@
struct device *self;
void *aux;
{
+ struct mainbus_attach_args *ma = aux;
+ struct gt_softc *sc = (void *)self;
+ struct gt_attach_args ga;
+#if NPCI > 0
struct pcibus_attach_args pba;
+#endif
printf("\n");
- /* XXX */
- *((volatile u_int32_t *)0xb4000c00) =
- (*((volatile u_int32_t *)0xb4000c00) & ~0x6) | 0x2;
+ sc->sc_addr = ma->ma_addr;
+ /*
+ * timer0 is working at the time of BIOS. It might be got blocked
+ * and timer interruption may already have generated it. A timer0
+ * interruption must be cleared.
+ */
+ ga.ga_name = "gttimer";
+ ga.ga_bst = ma->ma_iot;
+ ga.ga_base = sc->sc_addr;
+ config_found(self, &ga, gt_print);
+ GT_WRITE_REG(sc, GT_INTR_CAUSE,
+ GT_READ_REG(sc, GT_INTR_CAUSE) & ~T0EXP);
+
+ /* XXX */
+ GT_WRITE_REG(sc, GT_PCI_COMMAND,
+ (GT_READ_REG(sc, GT_PCI_COMMAND) & ~PCI_SYNCMODE) | PCI_PCLK_HIGH);
#if NPCI > 0
pba.pba_busname = "pci";
pba.pba_dmat = &pci_bus_dma_tag;
@@ -94,7 +125,6 @@
PCI_FLAGS_MRL_OKAY | /*PCI_FLAGS_MRM_OKAY|*/ PCI_FLAGS_MWI_OKAY;
config_found(self, &pba, gt_print);
#endif
- return;
}
static int
Index: include/autoconf.h
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/include/autoconf.h,v
retrieving revision 1.2
diff -u -r1.2 autoconf.h
--- include/autoconf.h 5 May 2000 03:27:22 -0000 1.2
+++ include/autoconf.h 21 Aug 2004 16:50:39 -0000
@@ -29,7 +29,7 @@
struct mainbus_attach_args {
char *ma_name;
- unsigned long ma_addr;
+ uint32_t ma_addr;
bus_space_tag_t ma_iot;
bus_space_handle_t ma_ioh;
int ma_level;
Index: include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/include/cpu.h,v
retrieving revision 1.10
diff -u -r1.10 cpu.h
--- include/cpu.h 4 Sep 2001 06:23:16 -0000 1.10
+++ include/cpu.h 21 Aug 2004 16:50:39 -0000
@@ -1,3 +1,11 @@
/* $NetBSD: cpu.h,v 1.10 2001/09/04 06:23:16 simonb Exp $ */
#include <mips/cpu.h>
+
+#ifdef _KERNEL
+#ifndef _LOCORE
+extern void (*timer_start)(void *);
+extern uint32_t (*timer_read)(void *);
+extern void *timer_cookie;
+#endif /* _LOCORE */
+#endif /* _KERNEL */
--- /dev/null 2004-08-22 01:45:17.000000000 +0900
+++ dev/gtreg.h 2004-08-22 01:14:08.000000000 +0900
@@ -0,0 +1,88 @@
+/* $NetBSD$ */
+/*
+ * Copyright (c) 2003
+ * KIYOHARA Takashi. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#define GT_TIMER_COUNT 0x850
+#define TIMER_COUNT_REGSIZE 16
+#define TIMER_COUNT_T0 0x0 /* offsets from GT_TIMER_COUNT */
+#define TIMER_COUNT_T1 0x4
+#define TIMER_COUNT_T2 0x8
+#define TIMER_COUNT_T3 0xc
+
+
+#define GT_TIMER_CTRL 0x864
+#define TIMER_CTRL_REGSIZE 4
+#define ENTC0 0x01
+#define TCSEL0 0x02
+#define ENTC1 0x04
+#define TCSEL1 0x08
+#define ENTC2 0x10
+#define TCSEL2 0x20
+#define ENTC3 0x40
+#define TCSEL3 0x80
+
+#define GT_PCI_COMMAND 0xc00
+#define PCI_BYTESWAP 0x00000001
+#define PCI_SYNCMODE 0x00000006
+#define PCI_PCLK_LOW 0x00000000
+#define PCI_PCLK_HIGH 0x00000002
+#define PCI_PCLK_SYNC 0x00000004
+
+#define GT_INTR_CAUSE 0xc18
+#define INTSUM 0x00000001
+#define MEMOUT 0x00000002
+#define DMAOUT 0x00000004
+#define MASTEROUT 0x00000008
+#define DMA0COMP 0x00000010
+#define DMA1COMP 0x00000020
+#define DMA2COMP 0x00000040
+#define DMA3COMP 0x00000080
+#define T0EXP 0x00000100
+#define T1EXP 0x00000200
+#define T2EXP 0x00000400
+#define T3EXP 0x00000800
+#define MASRDERR 0x00001000
+#define SLVWRERR 0x00002000
+#define MASWRERR 0x00004000
+#define SLVRDERR 0x00008000
+#define ADDRERR 0x00010000
+#define MEMERR 0x00020000
+#define MASABORT 0x00040000
+#define TARABORT 0x00080000
+#define RETRYCTR 0x00100000
+#define MASTER_INT0 0x00200000
+#define MASTER_INT1 0x00400000
+#define MASTER_INT2 0x00800000
+#define MASTER_INT3 0x01000000
+#define MASTER_INT4 0x02000000
+#define PCI_INT0 0x04000000
+#define PCI_INT1 0x08000000
+#define PCI_INT2 0x10000000
+#define PCI_INT3 0x20000000
+#define MASTER_INTSUM 0x40000000
+#define PCI_INTSUM 0x80000000
+
+#define GT_MASTER_MASK 0xc1c
+#define GT_PCI_MASK 0xc24
--- /dev/null 2004-08-22 01:45:17.000000000 +0900
+++ dev/gtvar.h 2004-08-22 00:04:57.000000000 +0900
@@ -0,0 +1,31 @@
+/* $NetBSD$ */
+/*
+ * Copyright (c) 2003
+ * KIYOHARA Takashi. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+struct gt_attach_args {
+ char *ga_name; /* device name */
+ bus_space_tag_t ga_bst; /* bus space tag */
+ uint32_t ga_base; /* base address */
+};
--- /dev/null 2004-08-22 01:45:17.000000000 +0900
+++ dev/gttimer.c 2004-08-22 01:43:35.000000000 +0900
@@ -0,0 +1,113 @@
+/* $NetBSD$ */
+/*
+ * Copyright (c) 2003
+ * KIYOHARA Takashi. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/device.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+
+#include <machine/autoconf.h>
+#include <machine/bus.h>
+
+#include <cobalt/dev/gtreg.h>
+#include <cobalt/dev/gtvar.h>
+
+#define TIMER0_INIT_VALUE 500000
+
+struct gttimer_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_tmrh;
+ bus_space_handle_t sc_tmrch;
+};
+
+static int gttimer_match(struct device *, struct cfdata *, void *);
+static void gttimer_attach(struct device *, struct device *, void *);
+void timer0_start(void *);
+uint32_t timer0_read(void *);
+
+CFATTACH_DECL(gttimer, sizeof(struct gttimer_softc),
+ gttimer_match, gttimer_attach, NULL, NULL);
+
+void
+timer0_start(void *cookie)
+{
+ struct gttimer_softc *sc = cookie;
+
+ bus_space_write_4(sc->sc_bst, sc->sc_tmrh,
+ TIMER_COUNT_T0, TIMER0_INIT_VALUE);
+ bus_space_write_4(sc->sc_bst, sc->sc_tmrch,
+ 0, bus_space_read_4(sc->sc_bst, sc->sc_tmrch, 0) | ENTC0);
+}
+
+uint32_t
+timer0_read(void *cookie)
+{
+ struct gttimer_softc *sc = cookie;
+
+ return bus_space_read_4(sc->sc_bst, sc->sc_tmrh, TIMER_COUNT_T0);
+}
+
+static int
+gttimer_match(struct device *parent, struct cfdata *match, void *aux)
+{
+ char **name = aux;
+
+ if (strcmp(*name, "gttimer") == 0)
+ return 1;
+ return 0;
+}
+
+static void
+gttimer_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct gttimer_softc *sc = (void *)self;
+ struct gt_attach_args *ga = aux;
+
+ sc->sc_bst = ga->ga_bst;
+ if (bus_space_map(sc->sc_bst, ga->ga_base + GT_TIMER_COUNT,
+ TIMER_COUNT_REGSIZE, 0, &sc->sc_tmrh)) {
+ printf(": unable to map registers\n");
+ return;
+ }
+ if (bus_space_map(sc->sc_bst, ga->ga_base + GT_TIMER_CTRL,
+ TIMER_CTRL_REGSIZE, 0, &sc->sc_tmrch)) {
+ printf(": unable to map control register\n");
+ bus_space_unmap(sc->sc_bst, sc->sc_tmrch, 16);
+ return;
+ }
+
+ printf(": 32/24bit-wide timer/counter on GT-64111\n");
+
+ /* stop timer0 */
+ bus_space_write_4(sc->sc_bst, sc->sc_tmrch, 0,
+ bus_space_read_4(sc->sc_bst, sc->sc_tmrch, 0) & ~ENTC0);
+
+ timer_start = timer0_start;
+ timer_read = timer0_read;
+ timer_cookie = sc;
+}