Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/dnard/isa Add isa_machdep.c for dnard



details:   https://anonhg.NetBSD.org/src/rev/08f27ceed1bd
branches:  trunk
changeset: 509637:08f27ceed1bd
user:      matt <matt%NetBSD.org@localhost>
date:      Wed May 09 15:58:50 2001 +0000

description:
Add isa_machdep.c for dnard

diffstat:

 sys/arch/dnard/isa/isa_machdep.c |  224 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 224 insertions(+), 0 deletions(-)

diffs (228 lines):

diff -r 43149dcbe047 -r 08f27ceed1bd sys/arch/dnard/isa/isa_machdep.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/dnard/isa/isa_machdep.c  Wed May 09 15:58:50 2001 +0000
@@ -0,0 +1,224 @@
+/*     $NetBSD: isa_machdep.c,v 1.1 2001/05/09 15:58:50 matt Exp $     */
+
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and conditions.
+ * Subject to these conditions, you may download, copy, install,
+ * use, modify and distribute this software in source and/or binary
+ * form. No title or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ *    and retain this copyright notice and list of conditions as
+ *    they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of
+ *    Digital Equipment Corporation. Neither the "Digital Equipment
+ *    Corporation" name nor any trademark or logo of Digital Equipment
+ *    Corporation may be used to endorse or promote products derived
+ *    from this software without the prior written permission of
+ *    Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied
+ *    warranties, including but not limited to, any implied warranties
+ *    of merchantability, fitness for a particular purpose, or
+ *    non-infringement are disclaimed. In no event shall DIGITAL be
+ *    liable for any damages whatsoever, and in particular, DIGITAL
+ *    shall not be liable for special, indirect, consequential, or
+ *    incidental damages or damages for lost profits, loss of
+ *    revenue or loss of use, whether such damages arise in contract,
+ *    negligence, tort, under statute, in equity, at law or otherwise,
+ *    even if advised of the possibility of such damage.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/irqhandler.h>
+#include <machine/pio.h>
+
+#include <dev/isa/isareg.h>
+#include <dev/isa/isavar.h>
+#include <dev/isa/isadmavar.h>
+#include <arm32/isa/icu.h>
+
+#include <machine/ofw.h>
+
+struct arm32_isa_chipset isa_chipset_tag;
+
+unsigned i8259_mask;
+
+/* Notes on the interaction of StrongARM and ISA.  A lot of the nastiness
+   is caused by consciously prostituting shark to a low bill of materials.
+   
+   It takes on the order of 700ns (about 150 instruction cycles at
+   233 MHz) to access the ISA bus, so it is important to minimize the number
+   of ISA accesses, in particular to the 8259 interrupt controllers.
+   
+   To reduce the number of accesses, the 8259's are NOT run in the
+   same mode as on a typical Intel (IBM AT) system, which requires
+   an interrupt acknowledge sequence (INTA) for every interrupt.
+   Instead, the 8259's are used as big OR gates with interrupt masks
+   on the front.  The code in irq.S takes particular care to cache
+   the state of the interrupt masks and only update them when absolutely
+   necessary.
+   
+   Unfortunately, resetting the 8259 edge detectors without a real
+   INTA sequence is problematic at best.  To complicate matters further,
+   (unlike EISA components) the 8259s on the Sequoia core logic do
+   not allow configuration of edge vs. level on an IRQ-by-IRQ basis.
+   Thus, all interrupts must be either edge-triggered or level-triggered.
+   To preserve the sanity of the system, this code chooses the 
+   level-triggered configuration.
+   
+   None of the possible operation modes of the 8254 interval timers can 
+   be used to generate a periodic, level-triggered, clearable clock 
+   interrupt.  This restriction means that TIMER0 -- hardwired to IRQ0 -- 
+   may not be used as the heartbeat timer, as it is on Intel-based PCs.  
+   Instead, the real-time clock (RTC) interrupt -- connected to 
+   IRQ8 -- has the right properties and is used for the heartbeat interrupt.
+   TIMER0 may still be used to implement a microsecond timer.
+   See clock.c for details.
+   
+   As on most PC systems, 8254 TIMER1 is used for the ISA refresh signal.
+   
+   Unlike most PC systems, 8254 TIMER2 is not used for cheap tone
+   generation.  Instead, it is used to create a high-availability interrupt
+   for bit-bashing functions (e.g. for SmartCard access).  TIMER2 output,
+   called "SPKR" on Sequoia 2, is routed back into the SWTCH input on
+   Sequoia 1.  This input eventually reemerges from Sequoia 1 on the SMI pin,
+   which is then converted into the StrongARM FIQ (fast interrupt request).
+   To clear this interrupt, the StrongARM clears the SMI.
+   See .../shark/fiq.S for details.
+   
+   One more complication: ISA devices can be rather nasty with respect
+   to ISA bus usage.  For example, the CS8900 ethernet chip will occupy
+   the bus for very long DMA streams.  It is possible to configure the
+   chip so it relinquishes the ISA bus every 28 usec or so
+   (about every 6500 instructions).  This causes problems when trying
+   to run the TIMER2/SMI/FIQ at 50 kHz, which is required to detect the
+   baud rate of the SmartCard.  A modification to .../dev/isa/isadma.c 
+   allows the processor to freeze DMA during critial periods of time.  
+   This is a working -- but not very satisfactory -- solution to the problem.
+*/
+
+/*
+ * Initialize the interrupt controllers.
+ */
+void
+isa_init8259s()
+{
+  /* initialize 8259's */
+  outb(IO_ICU1, 0x19);            /* reset; four bytes, level triggered */
+  outb(IO_ICU1+1, ICU_OFFSET);    /* int base: not used */
+  outb(IO_ICU1+1, 1 << IRQ_SLAVE); /* slave on line 2 */
+  outb(IO_ICU1+1, 2 | 1);         /* auto EOI, 8086 mode */
+  outb(IO_ICU1+1, 0xff);          /* disable all interrupts */
+  outb(IO_ICU1, 0x68);            /* special mask mode (if available) */
+  outb(IO_ICU1, 0x0a);            /* Read IRR, not ISR */
+
+  outb(IO_ICU2, 0x19);            /* reset; four bytes, level triggered */
+  outb(IO_ICU2+1, ICU_OFFSET+8);   /* int base + offset for master: not used */
+  outb(IO_ICU2+1, IRQ_SLAVE);      /* who ami i? */
+  outb(IO_ICU2+1, 2 | 1);         /* auto EOI, 8086 mode */
+  outb(IO_ICU2+1, 0xff);          /* disable all interrupts */
+  outb(IO_ICU2, 0x68);            /* special mask mode (if available) */
+  outb(IO_ICU2, 0x0a);            /* Read IRR by default. */
+
+  i8259_mask = 0x0000ffff;         /* everything disabled */
+}
+
+#define        LEGAL_IRQ(x)    ((x) >= 0 && (x) < ICU_LEN && (x) != 2)
+
+const struct evcnt *
+isa_intr_evcnt(isa_chipset_tag_t ic, int irq)
+{
+
+       /* XXX for now, no evcnt parent reported */
+       return NULL;
+}
+
+/*
+ * Set up an interrupt handler to start being called.
+ */
+void *
+isa_intr_establish(ic, irq, type, level, ih_fun, ih_arg)
+       isa_chipset_tag_t ic;
+       int irq;
+       int type;
+       int level;
+       int (*ih_fun) __P((void *));
+       void *ih_arg;
+{
+           irqhandler_t *ih;
+
+           /* no point in sleeping unless someone can free memory. */
+           ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+           if (ih == NULL)
+               panic("isa_intr_establish: can't malloc handler info");
+
+           if (!LEGAL_IRQ(irq) || type == IST_NONE)
+               panic("intr_establish: bogus irq or type");
+
+           /* Note: sequoia doesn't allow configuration of edge vs. level
+              on an IRQ-by-IRQ basis.  */
+           if (type != IST_LEVEL)
+             printf("WARNING: irq %d not level triggered\n", irq);
+
+           memset(ih, 0, sizeof *ih);
+           ih->ih_func = ih_fun;
+           ih->ih_arg = ih_arg;
+           ih->ih_level = level;
+           ih->ih_name = "isa intr";
+
+           if (irq_claim(irq, ih) == -1)
+               panic("isa_intr_establish: can't install handler");
+
+           return (ih);
+}
+
+
+/*
+ * Deregister an interrupt handler.
+ */
+void
+isa_intr_disestablish(ic, arg)
+       isa_chipset_tag_t ic;
+       void *arg;
+{
+    panic("isa_intr_disestablish");
+}
+
+/* isa_init() might eventually become the ISA attach routine */
+void
+isa_init(vm_offset_t isa_io_addr, vm_offset_t isa_mem_addr)
+{
+  /* initialize the bus space functions */
+  isa_io_init(isa_io_addr, isa_mem_addr);
+
+  /* Clear the IRQ/FIQ masks */
+  isa_init8259s();
+
+  /* Initialize the ISA interrupt handling code */
+  irq_init();
+}
+
+void
+isa_attach_hook(parent, self, iba)
+        struct device *parent, *self;
+        struct isabus_attach_args *iba;
+{
+
+       /*
+        * Since we can only have one ISA bus, we just use a single
+        * statically allocated ISA chipset structure.  Pass it up
+        * now.
+        */
+       iba->iba_ic = &isa_chipset_tag;
+}



Home | Main Index | Thread Index | Old Index