Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sgimips/sgimips Support for the IP22 (Indigo2, Indy...
details: https://anonhg.NetBSD.org/src/rev/a69af4daf166
branches: trunk
changeset: 509725:a69af4daf166
user: thorpej <thorpej%NetBSD.org@localhost>
date: Fri May 11 04:56:09 2001 +0000
description:
Support for the IP22 (Indigo2, Indy, Challenge S). From Rafal K. Boni.
diffstat:
sys/arch/sgimips/sgimips/ip22.c | 425 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 425 insertions(+), 0 deletions(-)
diffs (truncated from 429 to 300 lines):
diff -r 01fdcb91b081 -r a69af4daf166 sys/arch/sgimips/sgimips/ip22.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sgimips/sgimips/ip22.c Fri May 11 04:56:09 2001 +0000
@@ -0,0 +1,425 @@
+/* $NetBSD: ip22.c,v 1.3 2001/05/11 04:56:09 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2001 Rafal K. Boni
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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 "opt_machtypes.h"
+
+#ifdef IP22
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+
+#include <machine/sysconf.h>
+#include <machine/machtype.h>
+#include <mips/locore.h>
+
+extern struct platform platform;
+
+extern int mach_type; /* IPxx type */
+extern int mach_subtype; /* subtype: eg., Guiness/Fullhouse for IP22 */
+extern int mach_boardrev; /* machine board revision, in case it matters */
+
+static u_int32_t iocwrite; /* IOC write register: read-only */
+static u_int32_t iocreset; /* IOC reset register: read-only */
+
+
+void ip22_init(void);
+void ip22_bus_reset(void);
+int ip22_local0_intr(void);
+int ip22_local1_intr(void);
+int ip22_mappable_intr(void *);
+void ip22_intr(u_int, u_int, u_int, u_int);
+void ip22_intr_establish(int, int, int (*)(void *), void *);
+unsigned long ip22_cal_timer(u_int32_t, u_int32_t);
+
+void
+ip22_init(void)
+{
+ u_int32_t sysid;
+ u_int32_t int23addr;
+ unsigned long cps;
+ unsigned long ctrdiff[3];
+
+ mach_type = MACH_SGI_IP22;
+
+ /* XXXrkb: enable watchdog timer, clear it */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa00004) |= 0x100;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa00014) = 0;
+
+ sysid = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9858);
+
+ if (sysid & 1)
+ mach_subtype = MACH_SGI_IP22_FULLHOUSE;
+ else
+ mach_subtype = MACH_SGI_IP22_GUINESS;
+
+ mach_boardrev = (sysid >> 1) & 0x0f;
+
+ printf("IOC rev %d, machine %s, board rev %d\n", (sysid >> 5) & 0x07,
+ (sysid & 1) ? "Indigo2 (Fullhouse)" : "Indy (Guiness)",
+ (sysid >> 1) & 0x0f);
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ /* Reset timer interrupts */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x20) = 3;
+
+ /*
+ * Reset Parallel port, Keyboard/mouse and EISA. Turn LED off.
+ * For Fullhouse, toggle magic GIO reset bit.
+ */
+ iocreset = 0x17;
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ iocreset |= 0x08;
+
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9870) = iocreset;
+
+ /*
+ * Set the 10BaseT port to use UTP cable, set autoselect mode for
+ * the ethernet interface (AUI vs. TP), set the two serial ports
+ * to PC mode.
+ */
+ iocwrite = 0x3a;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9878) = iocwrite;
+
+ /* Twiddle interrupt masks a bit */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x04) = 0xbf;
+
+ /* For Guiness, make sure to turn off video interrupts */
+ if (mach_subtype == MACH_SGI_IP22_GUINESS)
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x0c) = 0x3f;
+ else
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x0c) = 0xff;
+
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x14) = 0x00;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x18) = 0x00;
+
+ /* Set the general control registers for Guiness */
+ if (mach_subtype == MACH_SGI_IP22_GUINESS) {
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9848) = 0xff;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd984c) = 0xff;
+ }
+
+ platform.iointr = ip22_intr;
+ platform.bus_reset = ip22_bus_reset;
+ platform.intr_establish = ip22_intr_establish;
+
+ biomask = 0x0400;
+ netmask = 0x0400;
+ ttymask = 0x0c00;
+ clockmask = 0xbc00;
+
+ /* Hardcode interrupts 7, 11 to mappable interrupt 0,1 handlers */
+ intrtab[7].ih_fun = ip22_mappable_intr;
+ intrtab[7].ih_arg = (void*) 0;
+
+ intrtab[11].ih_fun = ip22_mappable_intr;
+ intrtab[11].ih_arg = (void*) 1;
+
+ /* Prime cache */
+ ip22_cal_timer(int23addr + 0x3c, int23addr + 0x38);
+
+ ctrdiff[0] = ip22_cal_timer(int23addr + 0x3c, int23addr + 0x38);
+ ctrdiff[1] = ip22_cal_timer(int23addr + 0x3c, int23addr + 0x38);
+ ctrdiff[2] = ip22_cal_timer(int23addr + 0x3c, int23addr + 0x38);
+ cps = (ctrdiff[0] + ctrdiff[1] + ctrdiff[2]) / 3;
+
+ printf("Timer calibration, got %lu cycles (%lu, %lu, %lu)\n", cps,
+ ctrdiff[0], ctrdiff[1], ctrdiff[2]);
+ printf("CPU clock speed = %lu.%02luMhz\n", cps / (1000000 / hz),
+ (cps % (1000000 / hz) / 100));
+
+ platform.ticks_per_hz = cps;
+}
+
+void
+ip22_bus_reset(void)
+{
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000ec) = 0;
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000fc) = 0;
+}
+
+void
+ip22_intr(status, cause, pc, ipending)
+ u_int32_t status;
+ u_int32_t cause;
+ u_int32_t pc;
+ u_int32_t ipending;
+{
+ static int nested = 0;
+ unsigned long cycles;
+ struct clockframe cf;
+
+ /* XXXrkb Tickle Indy/I2 MC watchdog timer */
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa00014) = 0;
+
+ nested++;
+
+ if (nested > 1)
+ panic("ip22_intr re-entered with ISR running!\n");
+
+ if (ipending & MIPS_INT_MASK_5) {
+ cycles = mips3_cp0_count_read();
+ mips3_cp0_compare_write(cycles + platform.ticks_per_hz);
+
+ cf.pc = pc;
+ cf.sr = status;
+
+ hardclock(&cf);
+
+ cause &= ~MIPS_INT_MASK_5;
+ }
+
+ if (ipending & MIPS_INT_MASK_0) {
+ if (ip22_local0_intr())
+ cause &= ~MIPS_INT_MASK_0;
+ }
+
+ if (ipending & MIPS_INT_MASK_1) {
+ if (ip22_local1_intr())
+ cause &= ~MIPS_INT_MASK_1;
+ }
+
+ if (ipending & MIPS_INT_MASK_4) {
+ printf("IP22 bus error: cpu_stat %08x addr %08x, "
+ "gio_stat %08x addr %08x\n",
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000ec),
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000e4),
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000fc),
+ *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000f4));
+ ip22_bus_reset();
+ cause &= ~MIPS_INT_MASK_4;
+ }
+
+ nested--;
+ _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
+}
+
+int
+ip22_mappable_intr(void* arg)
+{
+ int i;
+ int ret;
+ int intnum;
+ u_int32_t mstat;
+ u_int32_t mmask;
+ u_int32_t int23addr;
+ int which = (int)arg;
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ ret = 0;
+ mstat = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x10);
+ mmask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x14 +
+ (which * 4));
+
+ mstat &= mmask;
+
+ for (i = 0; i < 8; i++) {
+ intnum = i + 16 + (which * 8);
+ if (mstat & (1 << i)) {
+ if (intrtab[intnum].ih_fun != NULL)
+ ret |= (intrtab[intnum].ih_fun)(intrtab[intnum].ih_arg);
+ else
+ printf("Unexpected mappable interrupt %d\n", intnum);
+ }
+ }
+
+ return ret;
+}
+
+int
+ip22_local0_intr()
+{
+ int i;
+ int ret;
+ u_int32_t l0stat;
+ u_int32_t l0mask;
+ u_int32_t int23addr;
+
+ if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
+ int23addr = 0x1fbd9000;
+ else
+ int23addr = 0x1fbd9880;
+
+ ret = 0;
+ l0stat = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x00);
+ l0mask = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(int23addr + 0x04);
+
+ l0stat &= l0mask;
+
+ for (i = 0; i < 8; i++) {
+ if (l0stat & (1 << i)) {
+ if (intrtab[i].ih_fun != NULL)
+ ret |= (intrtab[i].ih_fun)(intrtab[i].ih_arg);
+ else
+ printf("Unexpected local0 interrupt %d\n", i);
+ }
+ }
+
+ return ret;
+}
+
Home |
Main Index |
Thread Index |
Old Index