Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/nathanw_sa]: src/sys/arch/newsmips/newsmips Reset FDC in news5000_init()...
details: https://anonhg.NetBSD.org/src/rev/f7dbdb477c2b
branches: nathanw_sa
changeset: 504644:f7dbdb477c2b
user: tsutsui <tsutsui%NetBSD.org@localhost>
date: Fri Apr 27 12:55:52 2001 +0000
description:
Reset FDC in news5000_init() to avoid spurious interrupts
after booting from floppy (since we don't have fdc driver yet).
diffstat:
sys/arch/newsmips/newsmips/news5000.c | 258 ++++++++++++++++++++++++++++++++++
1 files changed, 258 insertions(+), 0 deletions(-)
diffs (262 lines):
diff -r 5e74a325b42e -r f7dbdb477c2b sys/arch/newsmips/newsmips/news5000.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/newsmips/newsmips/news5000.c Fri Apr 27 12:55:52 2001 +0000
@@ -0,0 +1,258 @@
+/* $NetBSD: news5000.c,v 1.8.8.2 2001/04/27 12:55:52 tsutsui Exp $ */
+
+/*-
+ * Copyright (C) 1999 SHIMIZU Ryo. 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <machine/adrsmap.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <newsmips/apbus/apbusvar.h>
+#include <newsmips/newsmips/machid.h>
+
+extern void (*readmicrotime) (struct timeval *tvp);
+
+static void level1_intr (void);
+static void level0_intr (void);
+
+static void enable_intr_5000 (void);
+static void disable_intr_5000 (void);
+static void readmicrotime_5000 (struct timeval *);
+static void readidrom_5000 (u_char *);
+
+void news5000_init (void);
+
+static u_int freerun_off;
+
+/*
+ * Handle news5000 interrupts.
+ */
+void
+news5000_intr(status, cause, pc, ipending)
+ u_int status; /* status register at time of the exception */
+ u_int cause; /* cause register at time of exception */
+ u_int pc; /* program counter where to continue */
+ u_int ipending;
+{
+ if (ipending & MIPS_INT_MASK_2) {
+#ifdef DEBUG
+ static int l2cnt = 0;
+#endif
+ u_int int2stat;
+ struct clockframe cf;
+
+ int2stat = *(volatile u_int *)NEWS5000_INTST2;
+
+#ifdef DEBUG
+ l2cnt++;
+ if (l2cnt == 50) {
+ *(volatile u_int *)NEWS5000_LED_SEC = 1;
+ }
+ if (l2cnt == 100) {
+ *(volatile u_int *)NEWS5000_LED_SEC = 0;
+ l2cnt = 0;
+ }
+#endif
+
+ if (int2stat & NEWS5000_INT2_TIMER0) {
+ *(volatile u_int *)NEWS5000_TIMER0 = 1;
+ freerun_off = *(volatile u_int *)NEWS5000_FREERUN;
+
+ cf.pc = pc;
+ cf.sr = status;
+
+ hardclock(&cf);
+ intrcnt[HARDCLOCK_INTR]++;
+ }
+
+ apbus_wbflush();
+ cause &= ~MIPS_INT_MASK_2;
+ }
+ /* If clock interrupts were enabled, re-enable them ASAP. */
+ _splset(MIPS_SR_INT_IE | (status & MIPS_INT_MASK_2));
+
+ if (ipending & MIPS_INT_MASK_5) {
+ u_int int5stat = *(volatile u_int *)NEWS5000_INTST5;
+ printf("level5 interrupt (%08x)\n", int5stat);
+
+ apbus_wbflush();
+ cause &= ~MIPS_INT_MASK_5;
+ }
+
+ if (ipending & MIPS_INT_MASK_4) {
+ u_int int4stat = *(volatile u_int *)NEWS5000_INTST4;
+ printf("level4 interrupt (%08x)\n", int4stat);
+ if (int4stat & NEWS5000_INT4_APBUS) {
+ u_int stat = *(volatile u_int *)NEWS5000_APBUS_INTST;
+ printf("APbus error 0x%04x\n", stat & 0xffff);
+ if (stat & NEWS5000_APBUS_INT_DMAADDR) {
+ printf("DMA Address Error: slot=%x, addr=0x%08x\n",
+ *(volatile u_int *)NEWS5000_APBUS_DER_S,
+ *(volatile u_int *)NEWS5000_APBUS_DER_A);
+ }
+ if (stat & NEWS5000_APBUS_INT_RDTIMEO)
+ printf("IO Read Timeout: addr=0x%08x\n",
+ *(volatile u_int *)NEWS5000_APBUS_BER_A);
+ if (stat & NEWS5000_APBUS_INT_WRTIMEO)
+ printf("IO Write Timeout: addr=0x%08x\n",
+ *(volatile u_int *)NEWS5000_APBUS_BER_A);
+ *(volatile u_int *)0xb4c00014 = stat;
+ }
+
+ apbus_wbflush();
+ cause &= ~MIPS_INT_MASK_4;
+ }
+
+ if (ipending & MIPS_INT_MASK_3) {
+ u_int int3stat = *(volatile u_int *)NEWS5000_INTST3;
+ printf("level3 interrupt (%08x)\n", int3stat);
+
+ apbus_wbflush();
+ cause &= ~MIPS_INT_MASK_3;
+ }
+
+ if (ipending & MIPS_INT_MASK_1) {
+ level1_intr();
+ apbus_wbflush();
+ cause &= ~MIPS_INT_MASK_1;
+ }
+
+ if (ipending & MIPS_INT_MASK_0) {
+ level0_intr();
+ apbus_wbflush();
+ cause &= ~MIPS_INT_MASK_0;
+ }
+
+ _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
+}
+
+
+static void
+level1_intr(void)
+{
+ u_int int1stat;
+
+ int1stat = *(volatile u_int *)NEWS5000_INTST1;
+
+ if (int1stat) {
+ if (apbus_intr_call(1, int1stat) == 0)
+ printf("level1_intr: no handler (mask 0x%04x)\n",
+ int1stat);
+ } else
+ printf("level1 stray interrupt?\n");
+}
+
+static void
+level0_intr(void)
+{
+ u_int int0stat;
+
+ int0stat = *(volatile u_int *)NEWS5000_INTST0;
+
+ if (int0stat) {
+ if (apbus_intr_call(0, int0stat) == 0)
+ printf("level0_intr: no handler (mask 0x%04x)\n",
+ int0stat);
+ } else
+ printf("level0 stray interrupt?\n");
+}
+
+static void
+enable_intr_5000(void)
+{
+
+ /* INT0 and INT1 has been enabled at attach */
+ /* INT2 -- It's not a time to enable timer yet. */
+ /* INT3 -- not used for NWS-5000 */
+
+ *(volatile u_int *)NEWS5000_INTEN4 = NEWS5000_INT4_APBUS;
+ *(volatile u_int *)NEWS5000_APBUS_INTMSK = 0xffff;
+
+ /* INT5 -- currently ignored */
+ *(volatile u_int *)NEWS5000_INTEN5 = 0;
+}
+
+static void
+disable_intr_5000(void)
+{
+ *(volatile u_int *)NEWS5000_INTEN0 = 0;
+ *(volatile u_int *)NEWS5000_INTEN1 = 0;
+ *(volatile u_int *)NEWS5000_INTEN2 = 0;
+ *(volatile u_int *)NEWS5000_INTEN3 = 0;
+ *(volatile u_int *)NEWS5000_INTEN4 = 0;
+ *(volatile u_int *)NEWS5000_INTEN5 = 0;
+}
+
+static void
+readmicrotime_5000(tvp)
+ struct timeval *tvp;
+{
+ u_int freerun;
+
+ *tvp = time;
+ freerun = *(volatile u_int *)NEWS5000_FREERUN;
+ freerun -= freerun_off;
+ if (freerun > 1000000)
+ freerun = 1000000;
+ tvp->tv_usec += freerun;
+ if (tvp->tv_usec >= 1000000) {
+ tvp->tv_usec -= 1000000;
+ tvp->tv_sec++;
+ }
+}
+
+static void
+readidrom_5000(rom)
+ u_char *rom;
+{
+ u_int32_t *p = (void *)NEWS5000_IDROM;
+ int i;
+
+ for (i = 0; i < sizeof (struct idrom); i++, p += 2)
+ *rom++ = ((*p & 0x0f) << 4) + (*(p + 1) & 0x0f);
+}
+
+extern struct idrom idrom;
+
+void
+news5000_init(void)
+{
+ enable_intr = enable_intr_5000;
+ disable_intr = disable_intr_5000;
+
+ readidrom_5000((u_char *)&idrom);
+ readmicrotime = readmicrotime_5000;
+ hostid = idrom.id_serial;
+
+ /* XXX reset uPD72067 FDC to avoid spurious interrupts */
+#define NEWS5000_FDC_FDOUT 0xbed20000
+#define FDO_FRST 0x04
+ *(volatile u_int8_t *)NEWS5000_FDC_FDOUT = FDO_FRST;
+}
Home |
Main Index |
Thread Index |
Old Index