ctl.c revision 1.1.4.2 1 /* $NetBSD: ctl.c,v 1.1.4.2 2009/05/04 08:11:49 yamt Exp $ */
2
3 /*
4 * Copyright (c) 2009 Stephen M. Rumble
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ctl.c,v 1.1.4.2 2009/05/04 08:11:49 yamt Exp $");
32
33 #include <sys/param.h>
34 #include <sys/kernel.h>
35 #include <sys/device.h>
36 #include <sys/systm.h>
37 #include <sys/callout.h>
38
39 #include <machine/cpu.h>
40 #include <machine/locore.h>
41 #include <machine/autoconf.h>
42 #include <machine/bus.h>
43 #include <machine/machtype.h>
44 #include <machine/sysconf.h>
45
46 #include <sgimips/dev/ctlreg.h>
47
48 struct ctl_softc {
49 struct device sc_dev;
50
51 bus_space_tag_t iot;
52 bus_space_handle_t ioh;
53
54 };
55
56 static int ctl_match(struct device *, struct cfdata *, void *);
57 static void ctl_attach(struct device *, struct device *, void *);
58 static void ctl_bus_reset(void);
59 static void ctl_bus_error(uint32_t, uint32_t, uint32_t, uint32_t);
60 static void ctl_watchdog_enable(void);
61 static void ctl_watchdog_disable(void);
62 static void ctl_watchdog_tickle(void);
63
64 #if defined(BLINK)
65 static callout_t ctl_blink_ch;
66 static void ctl_blink(void *);
67 #endif
68
69 CFATTACH_DECL(ctl, sizeof(struct ctl_softc),
70 ctl_match, ctl_attach, NULL, NULL);
71
72 static struct ctl_softc csc;
73
74 static int
75 ctl_match(struct device * parent, struct cfdata * match, void *aux)
76 {
77 /*
78 * CTL exists on IP6/IP10 systems.
79 */
80 if (mach_type == MACH_SGI_IP6 || mach_type == MACH_SGI_IP10)
81 return 1;
82 else
83 return 0;
84 }
85
86 static void
87 ctl_attach(struct device * parent, struct device * self, void *aux)
88 {
89 struct mainbus_attach_args *ma = aux;
90
91 #ifdef BLINK
92 callout_init(&ctl_blink_ch, 0);
93 #endif
94
95 csc.iot = SGIMIPS_BUS_SPACE_NORMAL;
96 if (bus_space_map(csc.iot, ma->ma_addr, 0,
97 BUS_SPACE_MAP_LINEAR, &csc.ioh))
98 panic("ctl_attach: could not allocate memory\n");
99
100 platform.bus_reset = ctl_bus_reset;
101 platform.intr5 = ctl_bus_error;
102 platform.watchdog_enable = ctl_watchdog_enable;
103 platform.watchdog_disable = ctl_watchdog_disable;
104 platform.watchdog_reset = ctl_watchdog_tickle;
105
106 bus_space_write_2(csc.iot, csc.ioh, CTL_CPUCTRL,
107 (CTL_CPUCTRL_PARITY | CTL_CPUCTRL_SLAVE));
108
109 printf("\n");
110
111 ctl_bus_reset();
112
113 #if defined(BLINK)
114 ctl_blink(&csc);
115 #endif
116 }
117
118 static void
119 ctl_bus_reset(void)
120 {
121
122 bus_space_read_1(csc.iot, csc.ioh, CTL_LAN_PAR_CLR);
123 bus_space_read_1(csc.iot, csc.ioh, CTL_DMA_PAR_CLR);
124 bus_space_read_1(csc.iot, csc.ioh, CTL_CPU_PAR_CLR);
125 bus_space_read_1(csc.iot, csc.ioh, CTL_VME_PAR_CLR);
126 }
127
128 static void
129 ctl_bus_error(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
130 {
131
132 printf("ctl0: bus error\n");
133 ctl_bus_reset();
134 }
135
136 static void
137 ctl_watchdog_enable(void)
138 {
139 uint32_t reg;
140
141 /* XXX- doesn't seem to work properly */
142 return;
143
144 reg = bus_space_read_2(csc.iot, csc.ioh, CTL_CPUCTRL);
145 reg |= CTL_CPUCTRL_WDOG;
146 bus_space_write_2(csc.iot, csc.ioh, CTL_CPUCTRL, reg);
147 }
148
149 static void
150 ctl_watchdog_disable(void)
151 {
152 uint16_t reg;
153
154 /* XXX- doesn't seem to work properly */
155 return;
156
157 reg = bus_space_read_2(csc.iot, csc.ioh, CTL_CPUCTRL_WDOG);
158 reg &= ~(CTL_CPUCTRL_WDOG);
159 bus_space_write_2(csc.iot, csc.ioh, CTL_CPUCTRL, reg);
160 }
161
162 static void
163 ctl_watchdog_tickle(void)
164 {
165
166 ctl_watchdog_disable();
167 ctl_watchdog_enable();
168 }
169
170 #if defined(BLINK)
171 static void
172 ctl_blink(void *self)
173 {
174 struct ctl_softc *sc = (struct ctl_softc *) self;
175 int s, value;
176
177 s = splhigh();
178
179 value = bus_space_read_1(sc->iot, sc->ioh, CTL_AUX_CPUCTRL);
180 value ^= CTL_AUX_CPUCTRL_CONSLED;
181 bus_space_write_1(sc->iot, sc->ioh, CTL_AUX_CPUCTRL, value);
182 splx(s);
183
184 /*
185 * Blink rate is:
186 * full cycle every second if completely idle (loadav = 0)
187 * full cycle every 2 seconds if loadav = 1
188 * full cycle every 3 seconds if loadav = 2
189 * etc.
190 */
191 s = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
192 callout_reset(&ctl_blink_ch, s, ctl_blink, sc);
193 }
194 #endif
195