Add ISA support needed for Shark and the CATS board (CATS isa_machdep not
here yet).
This commit is contained in:
parent
636443752e
commit
ee69a0b0a0
|
@ -0,0 +1,676 @@
|
|||
/* $NetBSD: clock.c,v 1.1 1998/06/08 17:49:42 tv 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994 Charles Hannum.
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz and Don Ahn.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)clock.c 7.2 (Berkeley) 5/12/91
|
||||
*/
|
||||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie Mellon
|
||||
* the rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appears in all
|
||||
copies and that both the copyright notice and this permission notice
|
||||
appear in supporting documentation, and that the name of Intel
|
||||
not be used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
|
||||
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
|
||||
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
|
||||
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Primitive clock interrupt routines.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/irqhandler.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
#include <dev/isa/isareg.h>
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/ic/mc146818reg.h>
|
||||
#include <arm32/isa/isa_machdep.h>
|
||||
#include <arm32/isa/nvram.h>
|
||||
#include <arm32/isa/timerreg.h>
|
||||
#include <arm32/isa/spkrreg.h>
|
||||
|
||||
#ifdef SHARK
|
||||
#include <arm32/shark/hat.h>
|
||||
#endif
|
||||
|
||||
void sysbeepstop __P((void *));
|
||||
void sysbeep __P((int, int));
|
||||
void rtcinit __P((void));
|
||||
int timer_hz_to_count(int);
|
||||
|
||||
static void findcpuspeed __P((void));
|
||||
static void init_isa_timer_tables();
|
||||
static void delayloop(int);
|
||||
static int clockintr __P((void *));
|
||||
static int gettick __P((void));
|
||||
|
||||
__inline u_int mc146818_read __P((void *, u_int));
|
||||
__inline void mc146818_write __P((void *, u_int, u_int));
|
||||
|
||||
#define SECMIN ((unsigned)60) /* seconds per minute */
|
||||
#define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */
|
||||
#define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */
|
||||
#define SECYR ((unsigned)(365*SECDAY)) /* seconds per common year */
|
||||
|
||||
__inline u_int
|
||||
mc146818_read(sc, reg)
|
||||
void *sc; /* XXX use it? */
|
||||
u_int reg;
|
||||
{
|
||||
|
||||
outb(IO_RTC, reg);
|
||||
return (inb(IO_RTC+1));
|
||||
}
|
||||
|
||||
__inline void
|
||||
mc146818_write(sc, reg, datum)
|
||||
void *sc; /* XXX use it? */
|
||||
u_int reg, datum;
|
||||
{
|
||||
|
||||
outb(IO_RTC, reg);
|
||||
outb(IO_RTC+1, datum);
|
||||
}
|
||||
|
||||
unsigned int count1024usec; /* calibrated loop variable (1024 microseconds) */
|
||||
|
||||
/* number of timer ticks in a Musec = 2^20 usecs */
|
||||
#define TIMER_MUSECFREQ\
|
||||
(((((((TIMER_FREQ) * 1024) + 999) / 1000) * 1024) + 999) / 1000)
|
||||
#define TIMER_MUSECDIV(x) ((TIMER_MUSECFREQ+(x)/2)/(x))
|
||||
|
||||
/*
|
||||
* microtime() makes use of the following globals.
|
||||
* timer_msb_table[] and timer_lsb_table[] are used to compute the
|
||||
* microsecond increment.
|
||||
*
|
||||
* time.tv_usec += isa_timer_msb_table[cnt_msb] + isa_timer_lsb_table[cnt_lsb];
|
||||
*/
|
||||
|
||||
u_short isa_timer_msb_table[256]; /* timer->usec MSB */
|
||||
u_short isa_timer_lsb_table[256]; /* timer->usec conversion for LSB */
|
||||
|
||||
/* 64 bit counts from timer 0 */
|
||||
struct count64 {
|
||||
unsigned lo; /* low 32 bits */
|
||||
unsigned hi; /* high 32 bits */
|
||||
};
|
||||
|
||||
#define TIMER0_ROLLOVER 0xFFFF /* maximum rollover for 8254 counter */
|
||||
|
||||
struct count64 timer0count;
|
||||
struct count64 timer0_at_last_clockintr;
|
||||
unsigned timer0last;
|
||||
|
||||
/*#define TESTHAT*/
|
||||
#ifdef TESTHAT
|
||||
#define HATSTACKSIZE 1024
|
||||
#define HATHZ 50000
|
||||
#define HATHZ2 10000
|
||||
unsigned char hatStack[HATSTACKSIZE];
|
||||
|
||||
unsigned testHatOn = 0;
|
||||
unsigned nHats = 0;
|
||||
unsigned nHatWedges = 0;
|
||||
unsigned fiqReason = 0;
|
||||
unsigned hatCount = 0;
|
||||
unsigned hatCount2 = 0;
|
||||
|
||||
void hatTest(int testReason)
|
||||
{
|
||||
fiqReason |= testReason;
|
||||
nHats++;
|
||||
|
||||
}
|
||||
|
||||
void hatWedge(int nFIQs)
|
||||
{
|
||||
printf("Unwedging the HAT. fiqs_happened = %d\n", nFIQs);
|
||||
nHatWedges++;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
startrtclock()
|
||||
{
|
||||
findcpuspeed(); /* use the clock (while it's free)
|
||||
to find the cpu speed */
|
||||
|
||||
init_isa_timer_tables();
|
||||
|
||||
timer0count.lo = 0;
|
||||
timer0count.hi = 0;
|
||||
timer0_at_last_clockintr.lo = 0;
|
||||
timer0_at_last_clockintr.hi = 0;
|
||||
timer0last = 0;
|
||||
|
||||
/* initialize 8253 clock */
|
||||
outb(TIMER_MODE, TIMER_SEL0|TIMER_RATEGEN|TIMER_16BIT);
|
||||
outb(TIMER_CNTR0, TIMER0_ROLLOVER % 256);
|
||||
outb(TIMER_CNTR0, TIMER0_ROLLOVER / 256);
|
||||
|
||||
#ifdef TESTHAT
|
||||
hatCount = timer_hz_to_count(HATHZ);
|
||||
hatCount2 = timer_hz_to_count(HATHZ2);
|
||||
printf("HAT test on @ %d Hz = %d ticks\n", HATHZ, hatCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
init_isa_timer_tables()
|
||||
{
|
||||
int s;
|
||||
u_long t, msbmillion, quotient, remainder;
|
||||
|
||||
for (s = 0; s < 256; s++) {
|
||||
/* LSB table is easy, just divide and round */
|
||||
t = ((u_long) s * 1000000 * 2) / TIMER_FREQ;
|
||||
isa_timer_lsb_table[s] = (u_short) ((t / 2) + (t & 0x1));
|
||||
|
||||
msbmillion = s * 1000000;
|
||||
quotient = msbmillion / TIMER_FREQ;
|
||||
remainder = msbmillion % TIMER_FREQ;
|
||||
t = (remainder * 256 * 2) / TIMER_FREQ;
|
||||
isa_timer_msb_table[s] =
|
||||
(u_short)((t / 2) + (t & 1) + (quotient * 256));
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if ((s > 0) &&
|
||||
(isa_timer_msb_table[s] <
|
||||
(isa_timer_msb_table[s - 1] + isa_timer_lsb_table[0xFF])))
|
||||
panic ("time tables not monotonic %d: %d < (%d + %d) = %d\n",
|
||||
s, isa_timer_msb_table[s],
|
||||
isa_timer_msb_table[s - 1],
|
||||
isa_timer_lsb_table[0xFF],
|
||||
isa_timer_msb_table[s - 1] +
|
||||
isa_timer_lsb_table[0xFF]);
|
||||
#endif
|
||||
} /* END for */
|
||||
}
|
||||
|
||||
int
|
||||
timer_hz_to_count(timer_hz)
|
||||
int timer_hz;
|
||||
{
|
||||
u_long tval;
|
||||
|
||||
tval = (TIMER_FREQ * 2) / (u_long) timer_hz;
|
||||
tval = (tval / 2) + (tval & 0x1);
|
||||
|
||||
return (int)tval;
|
||||
|
||||
}
|
||||
|
||||
/* must be called at SPL_CLOCK or higher */
|
||||
void gettimer0count(pcount)
|
||||
struct count64 *pcount;
|
||||
{
|
||||
unsigned current, ticks, oldlo;
|
||||
|
||||
/*
|
||||
* Latch the current value of the timer and then read it.
|
||||
* This guarentees an atomic reading of the time.
|
||||
*/
|
||||
|
||||
current = gettick();
|
||||
|
||||
if (timer0last >= current)
|
||||
ticks = timer0last - current;
|
||||
else
|
||||
ticks = timer0last + (TIMER0_ROLLOVER - current);
|
||||
|
||||
timer0last = current;
|
||||
|
||||
oldlo = timer0count.lo;
|
||||
|
||||
if (oldlo > (timer0count.lo = oldlo + ticks)) /* carry? */
|
||||
timer0count.hi++;
|
||||
|
||||
*pcount = timer0count;
|
||||
}
|
||||
|
||||
static int
|
||||
clockintr(arg)
|
||||
void *arg;
|
||||
{
|
||||
struct clockframe *frame = arg; /* not strictly necessary */
|
||||
extern void isa_specific_eoi(int irq);
|
||||
#ifdef TESTHAT
|
||||
static int ticks = 0;
|
||||
#endif
|
||||
#ifdef SHARK
|
||||
static int hatUnwedgeCtr = 0;
|
||||
#endif
|
||||
|
||||
gettimer0count(&timer0_at_last_clockintr);
|
||||
|
||||
mc146818_read(NULL, MC_REGC); /* clear the clock interrupt */
|
||||
|
||||
#ifdef SHARK
|
||||
/* check to see if the high-availability timer needs to be unwedged */
|
||||
if (++hatUnwedgeCtr >= (hz / HAT_MIN_FREQ)) {
|
||||
hatUnwedgeCtr = 0;
|
||||
hatUnwedge();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TESTHAT
|
||||
++ticks;
|
||||
|
||||
if (testHatOn && ((ticks & 0x3f) == 0)) {
|
||||
if (testHatOn == 1) {
|
||||
hatClkAdjust(hatCount2);
|
||||
testHatOn = 2;
|
||||
} else {
|
||||
testHatOn = 0;
|
||||
hatClkOff();
|
||||
printf("hat off status: %d %d %x\n", nHats, nHatWedges, fiqReason);
|
||||
}
|
||||
} else if (!testHatOn && (ticks & 0x1ff) == 0) {
|
||||
printf("hat on status: %d %d %x\n", nHats, nHatWedges, fiqReason);
|
||||
testHatOn = 1;
|
||||
nHats = 0;
|
||||
fiqReason = 0;
|
||||
hatClkOn(hatCount, hatTest, 0xfeedface,
|
||||
hatStack + HATSTACKSIZE - sizeof(unsigned),
|
||||
hatWedge);
|
||||
}
|
||||
#endif
|
||||
hardclock(frame);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
gettick()
|
||||
{
|
||||
u_char lo, hi;
|
||||
u_int savedints;
|
||||
|
||||
/* Don't want someone screwing with the counter while we're here. */
|
||||
savedints = disable_interrupts(I32_bit);
|
||||
/* Select counter 0 and latch it. */
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
|
||||
lo = inb(TIMER_CNTR0);
|
||||
hi = inb(TIMER_CNTR0);
|
||||
restore_interrupts(savedints);
|
||||
return ((hi << 8) | lo);
|
||||
}
|
||||
|
||||
/* modifications from i386 to arm32 isa version:
|
||||
- removed hardcoded "n -=" values that approximated the time to
|
||||
calculate delay ticks
|
||||
- made the time to calculate delay ticks almost negligable. 4 multiplies
|
||||
= maximum of 12 cycles = 75ns on a slow SA-110, plus a bunch of shifts;
|
||||
as opposed to 4 multiplies plus a bunch of divides.
|
||||
- removed i386 assembly language hack
|
||||
- put code in findcpuspeed that works even if FIRST_GUESS is orders
|
||||
of magnitude low
|
||||
- put code in delay() to use delayloop() for short delays
|
||||
- microtime no longer in assembly language
|
||||
*/
|
||||
|
||||
/*
|
||||
* Wait "n" microseconds.
|
||||
* Relies on timer 1 counting down from (TIMER_FREQ / hz) at TIMER_FREQ Hz.
|
||||
* Note: timer had better have been programmed before this is first used!
|
||||
* (Note that we use `rate generator' mode, which counts at 1:1; `square
|
||||
* wave' mode counts at 2:1).
|
||||
*/
|
||||
void
|
||||
delay(n)
|
||||
unsigned n;
|
||||
{
|
||||
int tick, otick;
|
||||
int nticks;
|
||||
|
||||
if (n < 100) {
|
||||
/* it can take a long time (1 usec or longer) just for 1 ISA read,
|
||||
so it's best not to use the timer for short delays */
|
||||
delayloop((n * count1024usec) >> 10);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the counter first, so that the rest of the setup overhead is
|
||||
* counted.
|
||||
*/
|
||||
otick = gettick();
|
||||
|
||||
/*
|
||||
* Calculate ((n * TIMER_FREQ) / 1e6) without using floating point and
|
||||
* without any avoidable overflows.
|
||||
*/
|
||||
{
|
||||
/* a Musec = 2^20 usec */
|
||||
int Musec = n >> 20,
|
||||
usec = n & ((1 << 20) - 1);
|
||||
nticks
|
||||
= (Musec * TIMER_MUSECFREQ) +
|
||||
(usec * (TIMER_MUSECFREQ >> 20)) +
|
||||
((usec * ((TIMER_MUSECFREQ & ((1 <<20) - 1)) >>10)) >>10) +
|
||||
((usec * (TIMER_MUSECFREQ & ((1 << 10) - 1))) >> 20);
|
||||
}
|
||||
|
||||
while (nticks > 0) {
|
||||
tick = gettick();
|
||||
if (tick > otick)
|
||||
nticks -= TIMER0_ROLLOVER - (tick - otick);
|
||||
else
|
||||
nticks -= otick - tick;
|
||||
otick = tick;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
sysbeepstop(arg)
|
||||
void *arg;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
sysbeep(pitch, period)
|
||||
int pitch, period;
|
||||
{
|
||||
}
|
||||
|
||||
#define FIRST_GUESS 0x2000
|
||||
|
||||
static void
|
||||
findcpuspeed()
|
||||
{
|
||||
int ticks;
|
||||
unsigned int guess = FIRST_GUESS;
|
||||
|
||||
while (1) { /* loop until accurate enough */
|
||||
/* Put counter in count down mode */
|
||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
|
||||
outb(TIMER_CNTR0, 0xff);
|
||||
outb(TIMER_CNTR0, 0xff);
|
||||
delayloop(guess);
|
||||
|
||||
/* Read the value left in the counter */
|
||||
/*
|
||||
* Formula for delaycount is:
|
||||
* (loopcount * timer clock speed) / (counter ticks * 1000)
|
||||
*/
|
||||
ticks = 0xFFFF - gettick();
|
||||
if (ticks == 0) ticks = 1; /* just in case */
|
||||
if (ticks < (TIMER_MUSECDIV(1024))) { /* not accurate enough */
|
||||
guess *= max(2, (TIMER_MUSECDIV(1024) / ticks));
|
||||
continue;
|
||||
}
|
||||
count1024usec = (guess * (TIMER_MUSECDIV(1024))) / ticks;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delayloop(counts)
|
||||
{
|
||||
while (counts--);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_initclocks()
|
||||
{
|
||||
unsigned hzval;
|
||||
|
||||
printf("clock: hz=%d stathz = %d profhz = %d\n", hz, stathz, profhz);
|
||||
|
||||
/* install RTC interrupt handler */
|
||||
(void)isa_intr_establish(NULL, IRQ_RTC, IST_LEVEL, IPL_CLOCK,
|
||||
clockintr, 0);
|
||||
|
||||
/* code for values of hz that don't divide 1000000 exactly */
|
||||
tickfix = 1000000 - (hz * tick);
|
||||
if (tickfix) {
|
||||
int ftp;
|
||||
|
||||
ftp = min(ffs(tickfix), ffs(hz));
|
||||
tickfix >>= (ftp - 1);
|
||||
tickfixinterval = hz >> (ftp - 1);
|
||||
}
|
||||
|
||||
/* set up periodic interrupt @ hz
|
||||
this is the subset of hz values in kern_clock.c that are
|
||||
supported by the ISA RTC */
|
||||
switch (hz) {
|
||||
case 64:
|
||||
hzval = MC_RATE_64_Hz;
|
||||
break;
|
||||
case 128:
|
||||
hzval = MC_RATE_128_Hz;
|
||||
break;
|
||||
case 256:
|
||||
hzval = MC_RATE_256_Hz;
|
||||
break;
|
||||
case 1024:
|
||||
hzval = MC_RATE_1024_Hz;
|
||||
break;
|
||||
default:
|
||||
panic("cannot configure hz = %d\n", hz);
|
||||
}
|
||||
|
||||
rtcinit(); /* make sure basics are done by now */
|
||||
|
||||
/* blast values to set up clock interrupt */
|
||||
mc146818_write(NULL, MC_REGA, MC_BASE_32_KHz | hzval);
|
||||
/* enable periodic interrupt */
|
||||
mc146818_write(NULL, MC_REGB,
|
||||
mc146818_read(NULL, MC_REGB) | MC_REGB_PIE);
|
||||
}
|
||||
|
||||
void
|
||||
rtcinit()
|
||||
{
|
||||
static int first_rtcopen_ever = 1;
|
||||
|
||||
if (!first_rtcopen_ever)
|
||||
return;
|
||||
first_rtcopen_ever = 0;
|
||||
|
||||
mc146818_write(NULL, MC_REGA, /* XXX softc */
|
||||
MC_BASE_32_KHz | MC_RATE_1024_Hz);
|
||||
mc146818_write(NULL, MC_REGB, MC_REGB_24HR); /* XXX softc */
|
||||
}
|
||||
|
||||
void
|
||||
setstatclockrate(arg)
|
||||
int arg;
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* void microtime(struct timeval *tvp)
|
||||
*
|
||||
* Fill in the specified timeval struct with the current time
|
||||
* accurate to the microsecond.
|
||||
*/
|
||||
|
||||
void
|
||||
microtime(tvp)
|
||||
struct timeval *tvp;
|
||||
{
|
||||
int s;
|
||||
unsigned lsb, msb;
|
||||
int tm;
|
||||
static struct timeval oldtv;
|
||||
struct count64 timer0current;
|
||||
int ticks;
|
||||
|
||||
s = splstatclock();
|
||||
|
||||
gettimer0count(&timer0current);
|
||||
|
||||
tm = time.tv_usec;
|
||||
|
||||
/* unsigned arithmetic should take care of overflow */
|
||||
/* with a >= 32 Hz clock, ticks will always be < 0x7FFF */
|
||||
ticks = (int)((unsigned)
|
||||
(timer0current.lo - timer0_at_last_clockintr.lo));
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if ((ticks < 0) || (ticks > 0xffff))
|
||||
printf("microtime bug: ticks = %x\n", ticks);
|
||||
#endif
|
||||
|
||||
while (ticks > 0) {
|
||||
|
||||
if (ticks < 0xffff) {
|
||||
msb = (ticks >> 8) & 0xFF;
|
||||
lsb = ticks & 0xFF;
|
||||
} else {
|
||||
msb = 0xff;
|
||||
lsb = 0xff;
|
||||
}
|
||||
|
||||
/* see comments above */
|
||||
tm += isa_timer_msb_table[msb] + isa_timer_lsb_table[lsb];
|
||||
|
||||
/* for a 64 Hz RTC, ticks will never overflow table */
|
||||
/* microtime will be less accurate if the RTC is < 36 Hz */
|
||||
ticks -= 0xffff;
|
||||
}
|
||||
|
||||
tvp->tv_sec = time.tv_sec;
|
||||
if (tm > 1000000) {
|
||||
tvp->tv_sec += 1;
|
||||
tm -= 1000000;
|
||||
}
|
||||
|
||||
tvp->tv_usec = tm;
|
||||
|
||||
/* Make sure the time has advanced. */
|
||||
|
||||
if (tvp->tv_sec == oldtv.tv_sec &&
|
||||
tvp->tv_usec <= oldtv.tv_usec) {
|
||||
tvp->tv_usec = oldtv.tv_usec + 1;
|
||||
if (tvp->tv_usec > 1000000) {
|
||||
tvp->tv_usec -= 1000000;
|
||||
++tvp->tv_sec;
|
||||
}
|
||||
}
|
||||
|
||||
oldtv = *tvp;
|
||||
(void)splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
need_proftick(p)
|
||||
struct proc *p;
|
||||
{
|
||||
}
|
||||
|
||||
/* End of clock.c */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,254 @@
|
|||
/* $NetBSD: essreg.h,v 1.1 1998/06/08 17:49:43 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
** @(#) $RCSfile: essreg.h,v $ $Revision: 1.1 $ (SHARK) $Date: 1998/06/08 17:49:43 $
|
||||
**
|
||||
**++
|
||||
**
|
||||
** essreg.h
|
||||
**
|
||||
** FACILITY:
|
||||
**
|
||||
** DIGITAL Network Appliance Reference Design (DNARD)
|
||||
**
|
||||
** MODULE DESCRIPTION:
|
||||
**
|
||||
** This module contains the constant definitions for the device
|
||||
** registers on the ESS Technologies 1888/1887/888 sound chip.
|
||||
**
|
||||
** AUTHORS:
|
||||
**
|
||||
** Blair Fidler Software Engineering Australia
|
||||
** Gold Coast, Australia.
|
||||
**
|
||||
** CREATION DATE:
|
||||
**
|
||||
** March 10, 1997.
|
||||
**
|
||||
** MODIFICATION HISTORY:
|
||||
**
|
||||
**--
|
||||
*/
|
||||
|
||||
/*
|
||||
* DSP commands. This unit handles MIDI and audio capabilities.
|
||||
* The DSP can be reset, data/commands can be read or written to it,
|
||||
* and it can generate interrupts. Interrupts are generated for MIDI
|
||||
* input or DMA completion. They seem to have neglected the fact
|
||||
* that it would be nice to have a MIDI transmission complete interrupt.
|
||||
* Worse, the DMA engine is half-duplex. This means you need to do
|
||||
* (timed) programmed I/O to be able to record and play simulataneously.
|
||||
*/
|
||||
#define ESS_ACMD_DAC8WRITE 0x10 /* direct-mode 8-bit DAC write */
|
||||
#define ESS_ACMD_DAC16WRITE 0x11 /* direct-mode 16-bit DAC write */
|
||||
#define ESS_ACMD_DMA8OUT 0x14 /* 8-bit linear DMA output */
|
||||
#define ESS_ACMD_DMA16OUT 0x15 /* 16-bit linear DMA output */
|
||||
#define ESS_ACMD_AUTODMA8OUT 0x1C /* auto-init 8-bit linear DMA output */
|
||||
#define ESS_ACMD_AUTODMA16OUT 0x1D /* auto-init 16-bit linear DMA output */
|
||||
#define ESS_ACMD_ADC8READ 0x20 /* direct-mode 8-bit ADC read */
|
||||
#define ESS_ACMD_ADC16READ 0x21 /* direct-mode 16-bit ADC read */
|
||||
#define ESS_ACMD_DMA8IN 0x24 /* 8-bit linear DMA input */
|
||||
#define ESS_ACMD_DMA16IN 0x25 /* 16-bit linear DMA input */
|
||||
#define ESS_ACMD_AUTODMA8IN 0x2C /* auto-init 8-bit linear DMA input */
|
||||
#define ESS_ACMD_AUTODMA16IN 0x2D /* auto-init 16-bit linear DMA input */
|
||||
#define ESS_ACMD_SETTIMECONST1 0x40 /* set time constant (1MHz base) */
|
||||
#define ESS_ACMD_SETTIMECONST15 0x41 /* set time constant (1.5MHz base) */
|
||||
#define ESS_ACMD_SETFILTER 0x42 /* set filter clock independently */
|
||||
#define ESS_ACMD_BLOCKSIZE 0x48 /* set blk size for high speed xfer */
|
||||
|
||||
#define ESS_ACMD_DMA4OUT 0x74 /* 4-bit ADPCM DMA output */
|
||||
#define ESS_ACMD_DMA4OUTREF 0x75 /* 4-bit ADPCM DMA output with ref */
|
||||
#define ESS_ACMD_DMA2_6OUT 0x76 /* 2.6-bit ADPCM DMA output */
|
||||
#define ESS_ACMD_DMA2_6OUTREF 0x77 /* 2.6-bit ADPCM DMA output with ref */
|
||||
#define ESS_ACMD_DMA2OUT 0x7A /* 2-bit ADPCM DMA output */
|
||||
#define ESS_ACMD_DMA2OUTREF 0x7B /* 2-bit ADPCM DMA output with ref */
|
||||
#define ESS_ACMD_SILENCEOUT 0x80 /* output a block of silence */
|
||||
#define ESS_ACMD_START_AUTO_OUT 0x90 /* start auto-init 8-bit DMA output */
|
||||
#define ESS_ACMD_START_OUT 0x91 /* start 8-bit DMA output */
|
||||
#define ESS_ACMD_START_AUTO_IN 0x98 /* start auto-init 8-bit DMA input */
|
||||
#define ESS_ACMD_START_IN 0x99 /* start 8-bit DMA input */
|
||||
|
||||
#define ESS_XCMD_SAMPLE_RATE 0xA1 /* sample rate for Audio1 channel */
|
||||
#define ESS_XCMD_FILTER_CLOCK 0xA2 /* filter clock for Audio1 channel*/
|
||||
#define ESS_XCMD_XFER_COUNTLO 0xA4 /* */
|
||||
#define ESS_XCMD_XFER_COUNTHI 0xA5 /* */
|
||||
#define ESS_XCMD_AUDIO_CTRL 0xA8 /* */
|
||||
#define ESS_AUDIO_CTRL_MONITOR 0x08
|
||||
/* 0=disable/1=enable */
|
||||
#define ESS_AUDIO_CTRL_MONO 0x02
|
||||
/* 0=disable/1=enable */
|
||||
#define ESS_AUDIO_CTRL_STEREO 0x01
|
||||
/* 0=disable/1=enable */
|
||||
#define ESS_XCMD_PREAMP_CTRL 0xA9 /* */
|
||||
#define ESS_PREAMP_CTRL_ENABLE 0x04
|
||||
|
||||
#define ESS_XCMD_IRQ_CTRL 0xB1 /* legacy audio interrupt control */
|
||||
#define ESS_XCMD_DRQ_CTRL 0xB2 /* audio DRQ control */
|
||||
#define ESS_XCMD_VOLIN_CTRL 0xB4 /* stereo input volume control */
|
||||
#define ESS_XCMD_AUDIO1_CTRL1 0xB7 /* */
|
||||
#define ESS_AUDIO1_CTRL1_FIFO_SIGNED 0x20
|
||||
/* 0=unsigned/1=signed */
|
||||
#define ESS_AUDIO1_CTRL1_FIFO_SIZE 0x04
|
||||
/* 0=8-bit/1=16-bit */
|
||||
#define ESS_XCMD_AUDIO1_CTRL2 0xB8 /* */
|
||||
#define ESS_AUDIO1_CTRL2_FIFO_ENABLE 0x01
|
||||
/* 0=disable/1=enable */
|
||||
#define ESS_AUDIO1_CTRL2_DMA_READ 0x02
|
||||
/* 0=DMA write/1=DMA read */
|
||||
#define ESS_AUDIO1_CTRL2_ADC_ENABLE 0x08
|
||||
/* 0=DAC mode/1=ADC mode */
|
||||
#define ESS_XCMD_DEMAND_CTRL 0xB9 /* */
|
||||
|
||||
#define ESS_ACMD_ENABLE_EXT 0xC6 /* enable ESS extension commands */
|
||||
#define ESS_ACMD_DISABLE_EXT 0xC7 /* enable ESS extension commands */
|
||||
|
||||
#define ESS_ACMD_PAUSE_DMA 0xD0 /* pause DMA */
|
||||
#define ESS_ACMD_ENABLE_SPKR 0xD1 /* enable Audio1 DAC input to mixer */
|
||||
#define ESS_ACMD_DISABLE_SPKR 0xD3 /* disable Audio1 DAC input to mixer */
|
||||
#define ESS_ACMD_CONT_DMA 0xD4 /* continue paused DMA */
|
||||
#define ESS_ACMD_SPKR_STATUS 0xD8 /* return Audio1 DAC status: */
|
||||
#define ESS_SPKR_OFF 0x00
|
||||
#define ESS_SPKR_ON 0xFF
|
||||
#define ESS_ACMD_VERSION 0xE1 /* get version number */
|
||||
#define ESS_ACMD_LEGACY_ID 0xE7 /* get legacy ES688/ES1688 ID bytes */
|
||||
/*
|
||||
* Macros to detect valid hardware configuration data.
|
||||
*/
|
||||
#define ESS_IRQ1_VALID(irq, model) ((irq) == 5 || (irq) == 7 || (irq) == 9 || (irq) == 10 || ((model) == ESS_1887 && (irq) == 15))
|
||||
|
||||
#define ESS_IRQ2_VALID(irq, model) (((model) != ESS_1887) ? ((irq) == 15) : ((irq) == 5 || (irq) == 7 || (irq) == 9 || (irq) == 10) || (irq) == 15)
|
||||
|
||||
#define ESS_DRQ1_VALID(chan, model) ((chan) == 0 || (chan) == 1 || (chan) == 3 || ((model) == ESS_1887 && (chan) == 5))
|
||||
|
||||
#define ESS_DRQ2_VALID(chan, model) (((model) != ESS_1887) ? ((chan) == 5) : ((chan) == 0 || (chan) == 1 || (chan) == 3 || (chan) == 5))
|
||||
|
||||
#define ESS_BASE_VALID(base) ((base) == 0x220 || (base) == 0x230 || (base) == 0x240 || (base) == 0x250)
|
||||
|
||||
#define ESS_DMA_SIZE(chan) ((chan & 4) ? ESS_MODE_16BIT: ESS_MODE_8BIT)
|
||||
|
||||
/*
|
||||
* Macros to manipulate gain values
|
||||
*/
|
||||
#define ESS_4BIT_GAIN(x) ((x) & 0xf0)
|
||||
#define ESS_3BIT_GAIN(x) (((x) & 0xe0) >> 1)
|
||||
#define ESS_STEREO_GAIN(l, r) ((l) | ((r) >> 4))
|
||||
#define ESS_MONO_GAIN(x) ((x) >> 4)
|
||||
|
||||
#ifdef ESS_AMODE_LOW
|
||||
/*
|
||||
* Registers used to configure ESS chip via Read Key Sequence
|
||||
*/
|
||||
#define ESS_CONFIG_KEY_BASE 0x229
|
||||
#define ESS_CONFIG_KEY_PORTS 3
|
||||
#else
|
||||
/*
|
||||
* Registers used to configure ESS chip via System Control Register (SCR)
|
||||
*/
|
||||
#define ESS_SCR_ACCESS_BASE 0xF9
|
||||
#define ESS_SCR_ACCESS_PORTS 3
|
||||
#define ESS_SCR_LOCK 0
|
||||
#define ESS_SCR_UNLOCK 2
|
||||
|
||||
#define ESS_SCR_BASE 0xE0
|
||||
#define ESS_SCR_PORTS 2
|
||||
#define ESS_SCR_INDEX 0
|
||||
#define ESS_SCR_DATA 1
|
||||
|
||||
/*
|
||||
* Bit definitions for SCR
|
||||
*/
|
||||
#define ESS_SCR_AUDIO_ENABLE 0x04
|
||||
#define ESS_SCR_AUDIO_220 0x00
|
||||
#define ESS_SCR_AUDIO_230 0x01
|
||||
#define ESS_SCR_AUDIO_240 0x02
|
||||
#define ESS_SCR_AUDIO_250 0x03
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* DSP Timeout Definitions */
|
||||
/*****************************************************************************/
|
||||
#define ESS_RESET_TIMEOUT 5000 /* ??? */
|
||||
#define ESS_READ_TIMEOUT 5000 /* number of times to try a read */
|
||||
#define ESS_WRITE_TIMEOUT 5000 /* number of times to try a write */
|
||||
|
||||
|
||||
#define ESS_NPORT 16
|
||||
#define ESS_DSP_RESET 0x06
|
||||
#define ESS_MAGIC 0xAA /* response to successful reset */
|
||||
|
||||
#define ESS_DSP_READ 0x0A
|
||||
#define ESS_DSP_WRITE 0x0C
|
||||
|
||||
#define ESS_DSP_RW_STATUS 0x0C
|
||||
#define ESS_CLEAR_INTR 0x0E
|
||||
|
||||
#define ESS_DSP_READ_STATUS 0x0C
|
||||
#define ESS_DSP_READ_MASK 0x40
|
||||
#define ESS_DSP_READ_READY 0x40
|
||||
|
||||
#define ESS_DSP_WRITE_STATUS 0x0C
|
||||
#define ESS_DSP_WRITE_MASK 0x80
|
||||
#define ESS_DSP_WRITE_READY 0x00
|
||||
|
||||
|
||||
#define ESS_MIX_REG_SELECT 0x04
|
||||
#define ESS_MIX_REG_DATA 0x05
|
||||
#define ESS_MIX_RESET 0x00 /* mixer reset port and value */
|
||||
|
||||
|
||||
/*
|
||||
* ESS Mixer registers
|
||||
*/
|
||||
#define ESS_MREG_SAMPLE_RATE 0x70 /* sample rate for Audio2 channel */
|
||||
#define ESS_MREG_FILTER_CLOCK 0x72 /* filter clock for Audio2 channel */
|
||||
#define ESS_MREG_XFER_COUNTLO 0x74 /* low-byte of DMA transfer size */
|
||||
#define ESS_MREG_XFER_COUNTHI 0x76 /* high-byte of DMA transfer size */
|
||||
#define ESS_MREG_AUDIO2_CTRL1 0x78 /* control register 1 for Audio2: */
|
||||
#define ESS_AUDIO2_CTRL1_XFER_SIZE 0x20
|
||||
/* 0=8-bit/1=16-bit */
|
||||
#define ESS_AUDIO2_CTRL1_FIFO_ENABLE 0x02
|
||||
/* 0=disable/1=enable */
|
||||
#define ESS_AUDIO2_CTRL1_DAC_ENABLE 0x01
|
||||
/* 0=disable/1=enable */
|
||||
#define ESS_MREG_AUDIO2_CTRL2 0x7A /* control register 2 for Audio2: */
|
||||
#define ESS_AUDIO2_CTRL2_FIFO_SIZE 0x01
|
||||
/* 0=8-bit/1=16-bit */
|
||||
#define ESS_AUDIO2_CTRL2_CHANNELS 0x02
|
||||
/* 0=mono/1=stereo */
|
||||
#define ESS_AUDIO2_CTRL2_FIFO_SIGNED 0x04
|
||||
/* 0=unsigned/1=signed */
|
||||
#define ESS_AUDIO2_CTRL2_DMA_ENABLE 0x20
|
||||
/* 0=disable/1=enable */
|
|
@ -0,0 +1,211 @@
|
|||
/* $NetBSD: essvar.h,v 1.1 1998/06/08 17:49:43 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
** @(#) $RCSfile: essvar.h,v $ $Revision: 1.1 $ (SHARK) $Date: 1998/06/08 17:49:43 $
|
||||
**
|
||||
**++
|
||||
**
|
||||
** essvar.h
|
||||
**
|
||||
** FACILITY:
|
||||
**
|
||||
** DIGITAL Network Appliance Reference Design (DNARD)
|
||||
**
|
||||
** MODULE DESCRIPTION:
|
||||
**
|
||||
** This module contains the structure definitions and function
|
||||
** prototypes for the ESS Technologies 1887/888 sound chip
|
||||
** driver.
|
||||
**
|
||||
** AUTHORS:
|
||||
**
|
||||
** Blair Fidler Software Engineering Australia
|
||||
** Gold Coast, Australia.
|
||||
**
|
||||
** CREATION DATE:
|
||||
**
|
||||
** May 12, 1997.
|
||||
**
|
||||
** MODIFICATION HISTORY:
|
||||
**
|
||||
**--
|
||||
*/
|
||||
#define ESS_DAC_PLAY_VOL 0
|
||||
#define ESS_MIC_PLAY_VOL 1
|
||||
#define ESS_LINE_PLAY_VOL 2
|
||||
#define ESS_SYNTH_PLAY_VOL 3
|
||||
#define ESS_CD_PLAY_VOL 4
|
||||
#define ESS_AUXB_PLAY_VOL 5
|
||||
#define ESS_INPUT_CLASS 6
|
||||
|
||||
#define ESS_MASTER_VOL 7
|
||||
#define ESS_PCSPEAKER_VOL 8
|
||||
#define ESS_OUTPUT_CLASS 9
|
||||
|
||||
#define ESS_DAC_REC_VOL 10
|
||||
#define ESS_MIC_REC_VOL 11
|
||||
#define ESS_LINE_REC_VOL 12
|
||||
#define ESS_SYNTH_REC_VOL 13
|
||||
#define ESS_CD_REC_VOL 14
|
||||
#define ESS_AUXB_REC_VOL 15
|
||||
#define ESS_MIC_PREAMP 16
|
||||
#define ESS_RECORD_VOL 17
|
||||
#define ESS_RECORD_SOURCE 18
|
||||
#define ESS_RECORD_CLASS 19
|
||||
|
||||
#define ESS_RECORD_MONITOR 20
|
||||
#define ESS_MONITOR_CLASS 21
|
||||
|
||||
#define ESS_NDEVS 22
|
||||
|
||||
struct ess_audio_channel
|
||||
{
|
||||
int drq; /* DMA channel */
|
||||
int mode; /* DMA mode */
|
||||
#define ESS_MODE_8BIT 0
|
||||
#define ESS_MODE_16BIT 1
|
||||
int irq; /* IRQ line for this DMA channel */
|
||||
void *ih; /* interrupt vectoring */
|
||||
u_long nintr; /* number of interrupts taken */
|
||||
void (*intr)(void*); /* ISR for DMA complete */
|
||||
void *arg; /* arg for intr() */
|
||||
|
||||
/* Status information */
|
||||
int active; /* boolean: channel in use? */
|
||||
int dmaflags; /* value last passed to isa_dmastart */
|
||||
caddr_t dmaaddr; /* value last passed to isa_dmastart */
|
||||
vm_size_t dmacnt; /* value last passed to isa_dmastart */
|
||||
|
||||
u_int rate; /* sample rate in Hz*/
|
||||
u_int channels; /* 1:mono, 2:stereo */
|
||||
u_int precision; /* size of each sample in bits */
|
||||
u_int encoding; /* method used to encode samples */
|
||||
};
|
||||
|
||||
struct ess_softc
|
||||
{
|
||||
/* REVISIT: currently the initial part of this is directly from sbdsp */
|
||||
struct device sc_dev; /* base device */
|
||||
struct isadev sc_id; /* ISA device */
|
||||
isa_chipset_tag_t sc_ic;
|
||||
bus_space_tag_t sc_iot; /* tag */
|
||||
bus_space_handle_t sc_ioh; /* handle */
|
||||
void *sc_ih; /* interrupt vectoring */
|
||||
|
||||
int sc_iobase; /* I/O port base address */
|
||||
|
||||
u_short sc_open; /* reference count of open calls */
|
||||
|
||||
u_char gain[ESS_NDEVS][2]; /* kept in input levels */
|
||||
#define ESS_LEFT 0
|
||||
#define ESS_RIGHT 1
|
||||
|
||||
u_int out_port; /* output port */
|
||||
u_int in_mask; /* input ports */
|
||||
u_int in_port; /* XXX needed for MI interface */
|
||||
|
||||
u_int spkr_state; /* non-null is on */
|
||||
|
||||
struct ess_audio_channel sc_in; /* audio channel for record */
|
||||
struct ess_audio_channel sc_out;/* audio channel for playback */
|
||||
|
||||
void (*sc_mintr)(void*, int);/* midi input intr handler */
|
||||
|
||||
u_int sc_model;
|
||||
#define ESS_UNSUPPORTED 0
|
||||
#define ESS_1888 1
|
||||
#define ESS_1887 2
|
||||
#define ESS_888 3
|
||||
|
||||
u_int sc_version; /* Legacy ES688/ES1688 ID */
|
||||
};
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
#ifdef __BROKEN_INDIRECT_CONFIG
|
||||
int ess_probe __P((struct device *, void *, void *));
|
||||
#else
|
||||
int ess_probe __P((struct device *, struct cfdata *, void *));
|
||||
#endif
|
||||
void ess_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
int ess_open __P((dev_t, int));
|
||||
void ess_close __P((void *));
|
||||
int ess_getdev __P((void *, struct audio_device *));
|
||||
int ess_drain __P((void *));
|
||||
|
||||
int ess_query_encoding __P((void *, struct audio_encoding *));
|
||||
|
||||
int ess_set_params __P((void *, int, struct audio_params *, struct audio_params *));
|
||||
int ess_set_in_sr __P((void *, u_long, int));
|
||||
int ess_set_out_sr __P((void *, u_long, int));
|
||||
int ess_set_in_precision __P((void *, u_int));
|
||||
int ess_set_out_precision __P((void *, u_int));
|
||||
int ess_set_in_channels __P((void *, int));
|
||||
int ess_set_out_channels __P((void *, int));
|
||||
|
||||
int ess_round_blocksize __P((void *, int));
|
||||
|
||||
int ess_set_out_port __P((void *, int));
|
||||
int ess_get_out_port __P((void *));
|
||||
int ess_set_in_port __P((void *, int));
|
||||
int ess_get_in_port __P((void *));
|
||||
|
||||
int ess_commit_settings __P((void *));
|
||||
|
||||
u_int ess_get_silence __P((int));
|
||||
|
||||
int ess_dma_output __P((void *, void *, int, void (*)(void *), void *));
|
||||
int ess_dma_input __P((void *, void *, int, void (*)(void *), void *));
|
||||
int ess_halt_output __P((void *));
|
||||
int ess_halt_input __P((void *));
|
||||
int ess_cont_output __P((void *));
|
||||
int ess_cont_input __P((void *));
|
||||
|
||||
int ess_intr_output __P((void *));
|
||||
int ess_intr_input __P((void *));
|
||||
|
||||
int ess_speaker_ctl __P((void *, int));
|
||||
|
||||
int ess_getdev __P((void *, struct audio_device *));
|
||||
int ess_setfd __P((void *, int));
|
||||
|
||||
int ess_set_port __P((void *, mixer_ctrl_t *));
|
||||
int ess_get_port __P((void *, mixer_ctrl_t *));
|
||||
|
||||
int ess_query_devinfo __P((void *, mixer_devinfo_t *));
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/* $NetBSD: icu.h,v 1.1 1998/06/08 17:49:43 tv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)icu.h 5.6 (Berkeley) 5/9/91
|
||||
*/
|
||||
|
||||
/*
|
||||
* AT/386 Interrupt Control constants
|
||||
* W. Jolitz 8/89
|
||||
*/
|
||||
|
||||
#ifndef _ARM32_ISA_ICU_H_
|
||||
#define _ARM32_ISA_ICU_H_
|
||||
|
||||
#ifndef _LOCORE
|
||||
|
||||
/*
|
||||
* Interrupt "level" mechanism variables, masks, and macros
|
||||
*/
|
||||
extern unsigned imen; /* interrupt mask enable */
|
||||
|
||||
#define SET_ICUS() (outb(IO_ICU1 + 1, imen), outb(IO_ICU2 + 1, imen >> 8))
|
||||
|
||||
#endif /* !_LOCORE */
|
||||
|
||||
/*
|
||||
* Interrupt enable bits -- in order of priority
|
||||
*/
|
||||
#define IRQ_SLAVE 2
|
||||
|
||||
/*
|
||||
* Interrupt Control offset into Interrupt descriptor table (IDT)
|
||||
*/
|
||||
#define ICU_OFFSET 32 /* 0-31 are processor exceptions */
|
||||
#define ICU_LEN 16 /* 32-47 are ISA interrupts */
|
||||
|
||||
#endif /* !_ARM32_ISA_ICU_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,420 @@
|
|||
/* $NetBSD: if_csvar.h,v 1.1 1998/06/08 17:49:43 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
**++
|
||||
** FACILITY Crystal CS8900 Ethernet driver header file
|
||||
**
|
||||
** ABSTRACT
|
||||
**
|
||||
** This module provides CS8900 register defines in addition
|
||||
** to defining the driver softc structure.
|
||||
**
|
||||
** AUTHORS
|
||||
**
|
||||
** Peter Dettori SEA - Software Engineering.
|
||||
**
|
||||
** CREATION DATE:
|
||||
**
|
||||
** 13-Feb-1997.
|
||||
**
|
||||
** MODIFICATION HISTORY:
|
||||
**
|
||||
**--
|
||||
*/
|
||||
|
||||
#ifndef __IF_CSVAR_H__
|
||||
#define __IF_CSVAR_H__
|
||||
|
||||
extern struct cfdriver cs_cd;
|
||||
|
||||
/* Individual Address (Ethernet Address) */
|
||||
typedef struct
|
||||
{
|
||||
ushort word[3];
|
||||
} ia, *pia;
|
||||
|
||||
/*
|
||||
* Ethernet software status per interface.
|
||||
*
|
||||
* Each interface is referenced by a network interface structure,
|
||||
* arpcom.ac_if, which the routing code uses to locate the interface.
|
||||
* This structure contains the output queue for the interface,
|
||||
* its address, ...
|
||||
*/
|
||||
struct cs_softc {
|
||||
struct device sc_dev; /* base device glue */
|
||||
struct ethercom sc_ethercom; /* Ethernet common */
|
||||
|
||||
void *sc_ih; /* interupt handler */
|
||||
void *sc_sh; /* shutdown hook */
|
||||
bus_space_tag_t sc_iot; /* bus space tag for IO */
|
||||
bus_space_tag_t sc_memt; /* bus space tag for memory mode */
|
||||
bus_space_handle_t sc_ioh; /* bus space handles */
|
||||
bus_space_handle_t sc_memh;
|
||||
ushort sc_iobase; /* base IO port address */
|
||||
ushort sc_int; /* interrupt level */
|
||||
int pPacketPagePhys; /* physical io address */
|
||||
ushort mediaType; /* 10BaseT, thin wire */
|
||||
ushort configFlags; /* chip configuration software flag */
|
||||
int inMemoryMode; /* status */
|
||||
int txInProgress; /* flags */
|
||||
int resetting; /* chip in reset mode flag */
|
||||
uint dmaMemSize; /* 16K or 64K if DMA being used */
|
||||
char *dmaBase; /* DMA memory base */
|
||||
char *dma_offset; /* offset into DMA space */
|
||||
int sc_drq; /* DMA request channel : 5,6,7 */
|
||||
|
||||
int sc_xe_ent; /* current early-xmit table entry */
|
||||
int sc_xe_togo; /* # of packets to go at this ent */
|
||||
|
||||
u_int8_t sc_enaddr[6]; /* MAC address */
|
||||
};
|
||||
|
||||
/* Debug Status */
|
||||
/*#define CS_DEBUG 0*/
|
||||
|
||||
#ifdef CS_DEBUG
|
||||
#define dbg_print(x) printf x
|
||||
#else
|
||||
#define dbg_print(x)
|
||||
#endif
|
||||
|
||||
/* Return Status */
|
||||
#define CS_ERROR -1
|
||||
#define CS_OK 1
|
||||
|
||||
/* Hardcoded CS8900 specific configuration information */
|
||||
#define CS8900_IOSIZE 16 /* CS8900 has 8 2byte IO registers */
|
||||
#define CS8900_DMA_BUFFER_SIZE 16384 /* 16Kbyte or 64Kbyte, if
|
||||
* supported
|
||||
*/
|
||||
|
||||
/* Receive buffer status */
|
||||
|
||||
#define RXBUF_FREE 0x0000
|
||||
#define RXBUF_ALLOCATED 0x0001
|
||||
#define RXBUF_LOANED 0x0002
|
||||
|
||||
|
||||
/* Config Flags in cs_softc */
|
||||
|
||||
#define CFGFLG_MEM_MODE 0x0001
|
||||
#define CFGFLG_USE_SA 0x0002
|
||||
#define CFGFLG_IOCHRDY 0x0004
|
||||
#define CFGFLG_DCDC_POL 0x0008
|
||||
#define CFGFLG_FDX 0x0010
|
||||
#define CFGFLG_DMA_MODE 0x0020
|
||||
#define CFGFLG_NOT_EEPROM 0x8000
|
||||
|
||||
|
||||
/* Media Type in cs_softc */
|
||||
|
||||
#define MEDIA_AUI 0x0001
|
||||
#define MEDIA_10BASE2 0x0002
|
||||
#define MEDIA_10BASET 0x0003
|
||||
|
||||
|
||||
/* Chip Identification */
|
||||
|
||||
#define EISA_NUM_CRYSTAL 0x630E
|
||||
#define PROD_ID_MASK 0xE000
|
||||
#define PROD_ID_CS8900 0x0000
|
||||
#define PROD_ID_CS8920 0x4000
|
||||
#define PROD_ID_CS892X 0x6000
|
||||
#define PROD_REV_MASK 0x1F00
|
||||
|
||||
|
||||
/* IO Port Offsets */
|
||||
|
||||
#define PORT_RXTX_DATA 0x0000
|
||||
#define PORT_RXTX_DATA_1 0x0002
|
||||
#define PORT_TX_CMD 0x0004
|
||||
#define PORT_TX_LENGTH 0x0006
|
||||
#define PORT_ISQ 0x0008
|
||||
#define PORT_PKTPG_PTR 0x000A
|
||||
#define PORT_PKTPG_DATA 0x000C
|
||||
#define PORT_PKTPG_DATA_1 0x000E
|
||||
|
||||
|
||||
/* PacketPage Offsets */
|
||||
|
||||
#define PKTPG_EISA_NUM 0x0000
|
||||
#define PKTPG_PRODUCT_ID 0x0002
|
||||
#define PKTPG_IO_BASE 0x0020
|
||||
#define PKTPG_INT_NUM 0x0022
|
||||
#define PKTPG_DMA_CHANNEL 0x0024
|
||||
#define PKTPG_DMA_START_FRAME 0x0026
|
||||
#define PKTPG_DMA_FRAME_COUNT 0x0028
|
||||
#define PKTPG_DMA_BYTE_COUNT 0x002A
|
||||
#define PKTPG_MEM_BASE 0x002C
|
||||
#define PKTPG_EEPROM_CMD 0x0040
|
||||
#define PKTPG_EEPROM_DATA 0x0042
|
||||
#define PKTPG_FRAME_BYTE_COUNT 0x0050
|
||||
#define PKTPG_RX_CFG 0x0102
|
||||
#define PKTPG_RX_CTL 0x0104
|
||||
#define PKTPG_TX_CFG 0x0106
|
||||
#define PKTPG_BUF_CFG 0x010A
|
||||
#define PKTPG_LINE_CTL 0x0112
|
||||
#define PKTPG_SELF_CTL 0x0114
|
||||
#define PKTPG_BUS_CTL 0x0116
|
||||
#define PKTPG_TEST_CTL 0x0118
|
||||
#define PKTPG_ISQ 0x0120
|
||||
#define PKTPG_RX_EVENT 0x0124
|
||||
#define PKTPG_TX_EVENT 0x0128
|
||||
#define PKTPG_BUF_EVENT 0x012C
|
||||
#define PKTPG_RX_MISS 0x0130
|
||||
#define PKTPG_TX_COL 0x0132
|
||||
#define PKTPG_LINE_ST 0x0134
|
||||
#define PKTPG_SELF_ST 0x0136
|
||||
#define PKTPG_BUS_ST 0x0138
|
||||
#define PKTPG_TX_CMD 0x0144
|
||||
#define PKTPG_TX_LENGTH 0x0146
|
||||
#define PKTPG_LOG_ADDR 0x0150 /* logical address filter
|
||||
* (hash table)
|
||||
*/
|
||||
#define PKTPG_IND_ADDR 0x0158
|
||||
#define PKTPG_RX_STATUS 0x0400
|
||||
#define PKTPG_RX_LENGTH 0x0402
|
||||
#define PKTPG_RX_FRAME 0x0404
|
||||
#define PKTPG_TX_FRAME 0x0A00
|
||||
|
||||
|
||||
/* EEPROM Offsets */
|
||||
|
||||
#define EEPROM_IND_ADDR_H 0x001C
|
||||
#define EEPROM_IND_ADDR_M 0x001D
|
||||
#define EEPROM_IND_ADDR_L 0x001E
|
||||
#define EEPROM_ISA_CFG 0x001F
|
||||
#define EEPROM_MEM_BASE 0x0020
|
||||
#define EEPROM_XMIT_CTL 0x0023
|
||||
#define EEPROM_ADPTR_CFG 0x0024
|
||||
|
||||
|
||||
/* Register Numbers */
|
||||
|
||||
#define REG_NUM_MASK 0x003F
|
||||
#define REG_NUM_RX_EVENT 0x0004
|
||||
#define REG_NUM_TX_EVENT 0x0008
|
||||
#define REG_NUM_BUF_EVENT 0x000C
|
||||
#define REG_NUM_RX_MISS 0x0010
|
||||
#define REG_NUM_TX_COL 0x0012
|
||||
|
||||
|
||||
/* Self Control Register */
|
||||
|
||||
#define SELF_CTL_RESET 0x0040
|
||||
#define SELF_CTL_HC1E 0x2000
|
||||
#define SELF_CTL_HCB1 0x8000
|
||||
|
||||
|
||||
/* Self Status Register */
|
||||
|
||||
#define SELF_ST_INIT_DONE 0x0080
|
||||
#define SELF_ST_SI_BUSY 0x0100
|
||||
#define SELF_ST_EEP_PRES 0x0200
|
||||
#define SELF_ST_EEP_OK 0x0400
|
||||
#define SELF_ST_EL_PRES 0x0800
|
||||
|
||||
|
||||
/* EEPROM Command Register */
|
||||
|
||||
#define EEPROM_CMD_READ 0x0200
|
||||
#define EEPROM_CMD_ELSEL 0x0400
|
||||
|
||||
|
||||
/* Bus Control Register */
|
||||
|
||||
#define BUS_CTL_RESET_DMA 0x0040
|
||||
#define BUS_CTL_USE_SA 0x0200
|
||||
#define BUS_CTL_MEM_MODE 0x0400
|
||||
#define BUS_CTL_DMA_BURST 0x0800
|
||||
#define BUS_CTL_IOCHRDY 0x1000
|
||||
#define BUS_CTL_DMA_SIZE 0x2000
|
||||
#define BUS_CTL_INT_ENBL 0x8000
|
||||
|
||||
|
||||
/* Bus Status Register */
|
||||
|
||||
#define BUS_ST_TX_BID_ERR 0x0080
|
||||
#define BUS_ST_RDY4TXNOW 0x0100
|
||||
|
||||
|
||||
/* Line Control Register */
|
||||
|
||||
#define LINE_CTL_RX_ON 0x0040
|
||||
#define LINE_CTL_TX_ON 0x0080
|
||||
#define LINE_CTL_AUI_ONLY 0x0100
|
||||
#define LINE_CTL_10BASET 0x0000
|
||||
#define LINE_CTL_AUTO_SEL 0x0200
|
||||
|
||||
|
||||
/* Test Control Register */
|
||||
|
||||
#define TEST_CTL_DIS_LT 0x0080
|
||||
#define TEST_CTL_ENDEC_LP 0x0200
|
||||
#define TEST_CTL_AUI_LOOP 0x0400
|
||||
#define TEST_CTL_DIS_BKOFF 0x0800
|
||||
#define TEST_CTL_FDX 0x4000
|
||||
|
||||
|
||||
/* Receiver Configuration Register */
|
||||
|
||||
#define RX_CFG_SKIP 0x0040
|
||||
#define RX_CFG_RX_OK_IE 0x0100
|
||||
#define RX_CFG_RX_DMA_ONLY 0x0200
|
||||
#define RX_CFG_CRC_ERR_IE 0x1000
|
||||
#define RX_CFG_RUNT_IE 0x2000
|
||||
#define RX_CFG_X_DATA_IE 0x4000
|
||||
#define RX_CFG_ALL_IE 0x7100
|
||||
|
||||
|
||||
/* Receiver Event Register */
|
||||
|
||||
#define RX_EVENT_DRIBBLE 0x0080
|
||||
#define RX_EVENT_RX_OK 0x0100
|
||||
#define RX_EVENT_IND_ADDR 0x0400
|
||||
#define RX_EVENT_BCAST 0x0800
|
||||
#define RX_EVENT_CRC_ERR 0x1000
|
||||
#define RX_EVENT_RUNT 0x2000
|
||||
#define RX_EVENT_X_DATA 0x4000
|
||||
|
||||
|
||||
/* Receiver Control Register */
|
||||
|
||||
#define RX_CTL_INDHASH_A 0x0040
|
||||
#define RX_CTL_PROMISC_A 0x0080
|
||||
#define RX_CTL_RX_OK_A 0x0100
|
||||
#define RX_CTL_MCAST_A 0x0200
|
||||
#define RX_CTL_IND_A 0x0400
|
||||
#define RX_CTL_BCAST_A 0x0800
|
||||
#define RX_CTL_CRC_ERR_A 0x1000
|
||||
#define RX_CTL_RUNT_A 0x2000
|
||||
#define RX_CTL_X_DATA_A 0x4000
|
||||
|
||||
|
||||
/* Transmit Configuration Register */
|
||||
|
||||
#define TX_CFG_LOSS_CRS_IE 0x0040
|
||||
#define TX_CFG_SQE_ERR_IE 0x0080
|
||||
#define TX_CFG_TX_OK_IE 0x0100
|
||||
#define TX_CFG_OUT_WIN_IE 0x0200
|
||||
#define TX_CFG_JABBER_IE 0x0400
|
||||
#define TX_CFG_16_COLL_IE 0x8000
|
||||
#define TX_CFG_ALL_IE 0x8FC0
|
||||
|
||||
|
||||
|
||||
/* Transmit Configuration Register */
|
||||
|
||||
#define TX_EVENT_LOSS_CRS 0x0040
|
||||
#define TX_EVENT_SQE_ERR 0x0080
|
||||
#define TX_EVENT_TX_OK 0x0100
|
||||
#define TX_EVENT_OUT_WIN 0x0200
|
||||
#define TX_EVENT_JABBER 0x0400
|
||||
#define TX_EVENT_COLL_MASK 0x7800
|
||||
#define TX_EVENT_16_COLL 0x8000
|
||||
|
||||
|
||||
/* Transmit Command Register */
|
||||
|
||||
#define TX_CMD_START_5 0x0000
|
||||
#define TX_CMD_START_381 0x0080
|
||||
#define TX_CMD_START_1021 0x0040
|
||||
#define TX_CMD_START_ALL 0x00C0
|
||||
#define TX_CMD_FORCE 0x0100
|
||||
#define TX_CMD_ONE_COLL 0x0200
|
||||
#define TX_CMD_NO_CRC 0x1000
|
||||
#define TX_CMD_NO_PAD 0x2000
|
||||
|
||||
|
||||
/* Buffer Configuration Register */
|
||||
|
||||
#define BUF_CFG_SW_INT 0x0040
|
||||
#define BUF_CFG_RX_DMA_IE 0x0080
|
||||
#define BUF_CFG_RDY4TX_IE 0x0100
|
||||
#define BUF_CFG_RX_MISS_IE 0x0400
|
||||
#define BUF_CFG_TX_UNDR_IE 0x0200
|
||||
#define BUF_CFG_RX_128_IE 0x0800
|
||||
#define BUF_CFG_TX_COL_OVER_IE 0x1000
|
||||
#define BUF_CFG_RX_MISS_OVER_IE 0x2000
|
||||
#define BUF_CFG_RX_DEST_IE 0x8000
|
||||
|
||||
/* Buffer Event Register */
|
||||
|
||||
#define BUF_EVENT_SW_INT 0x0040
|
||||
#define BUF_EVENT_RX_DMA 0x0080
|
||||
#define BUF_EVENT_RDY4TX 0x0100
|
||||
#define BUF_EVENT_TX_UNDR 0x0200
|
||||
#define BUF_EVENT_RX_MISS 0x0400
|
||||
#define BUF_EVENT_RX_128 0x0800
|
||||
#define BUF_EVENT_RX_DEST 0x8000
|
||||
|
||||
|
||||
/* ISA Configuration from EEPROM */
|
||||
|
||||
#define ISA_CFG_IRQ_MASK 0x000F
|
||||
#define ISA_CFG_USE_SA 0x0080
|
||||
#define ISA_CFG_IOCHRDY 0x0100
|
||||
#define ISA_CFG_MEM_MODE 0x8000
|
||||
|
||||
|
||||
/* Memory Base from EEPROM */
|
||||
|
||||
#define MEM_BASE_MASK 0xFFF0
|
||||
|
||||
|
||||
/* Adpater Configuration from EEPROM */
|
||||
|
||||
#define ADPTR_CFG_MEDIA 0x0060
|
||||
#define ADPTR_CFG_10BASET 0x0020
|
||||
#define ADPTR_CFG_AUI 0x0040
|
||||
#define ADPTR_CFG_10BASE2 0x0060
|
||||
#define ADPTR_CFG_DCDC_POL 0x0080
|
||||
|
||||
|
||||
/* Transmission Control from EEPROM */
|
||||
|
||||
#define XMIT_CTL_FDX 0x8000
|
||||
|
||||
|
||||
/* Miscellaneous definitions */
|
||||
|
||||
#define MAXLOOP 0x8888
|
||||
#define CS_DMA_FRAME_HEADER_SIZE (sizeof(ushort) * 2)
|
||||
#define RXBUFCOUNT 16
|
||||
#define MC_LOANED 5
|
||||
|
||||
#endif
|
|
@ -0,0 +1,290 @@
|
|||
/* $NetBSD: isa_io.c,v 1.1 1998/06/08 17:49:44 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bus_space I/O functions for isa
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/pio.h>
|
||||
#include <arm32/isa/isa_machdep.h>
|
||||
|
||||
/* Proto types for all the bus_space structure functions */
|
||||
|
||||
bs_protos(isa);
|
||||
bs_protos(bs_notimpl);
|
||||
|
||||
/* Declare the isa bus space tags */
|
||||
/* The IO and MEM structs are identical, except for the cookies, */
|
||||
/* which contain the address space bases. */
|
||||
|
||||
/*
|
||||
* NOTE: ASSEMBLY LANGUAGE RELIES ON THE COOKIE -- THE FIRST MEMBER OF
|
||||
* THIS STRUCTURE -- TO BE THE VIRTUAL ADDRESS OF ISA/IO!
|
||||
*/
|
||||
struct bus_space isa_io_bs_tag = {
|
||||
/* cookie */
|
||||
NULL, /* initialized below */
|
||||
|
||||
/* mapping/unmapping */
|
||||
isa_map,
|
||||
isa_unmap,
|
||||
isa_subregion,
|
||||
|
||||
/* allocation/deallocation */
|
||||
isa_alloc,
|
||||
isa_free,
|
||||
|
||||
/* barrier */
|
||||
isa_barrier,
|
||||
|
||||
/* read (single) */
|
||||
isa_r_1,
|
||||
isa_r_2,
|
||||
isa_r_4,
|
||||
bs_notimpl_r_8,
|
||||
|
||||
/* read multiple */
|
||||
isa_rm_1,
|
||||
isa_rm_2,
|
||||
isa_rm_4,
|
||||
bs_notimpl_rm_8,
|
||||
|
||||
/* read region */
|
||||
isa_rr_1,
|
||||
isa_rr_2,
|
||||
isa_rr_4,
|
||||
bs_notimpl_rr_8,
|
||||
|
||||
/* write (single) */
|
||||
isa_w_1,
|
||||
isa_w_2,
|
||||
isa_w_4,
|
||||
bs_notimpl_w_8,
|
||||
|
||||
/* write multiple */
|
||||
isa_wm_1,
|
||||
isa_wm_2,
|
||||
isa_wm_4,
|
||||
bs_notimpl_wm_8,
|
||||
|
||||
/* write region */
|
||||
isa_wr_1,
|
||||
isa_wr_2,
|
||||
isa_wr_4,
|
||||
bs_notimpl_wr_8,
|
||||
|
||||
/* set multiple */
|
||||
bs_notimpl_sm_1,
|
||||
bs_notimpl_sm_2,
|
||||
bs_notimpl_sm_4,
|
||||
bs_notimpl_sm_8,
|
||||
|
||||
/* set region */
|
||||
bs_notimpl_sr_1,
|
||||
bs_notimpl_sr_2,
|
||||
bs_notimpl_sr_4,
|
||||
bs_notimpl_sr_8,
|
||||
|
||||
/* copy */
|
||||
bs_notimpl_c_1,
|
||||
bs_notimpl_c_2,
|
||||
bs_notimpl_c_4,
|
||||
bs_notimpl_c_8,
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: ASSEMBLY LANGUAGE RELIES ON THE COOKIE -- THE FIRST MEMBER OF
|
||||
* THIS STRUCTURE -- TO BE THE VIRTUAL ADDRESS OF ISA/MEMORY!
|
||||
*/
|
||||
struct bus_space isa_mem_bs_tag = {
|
||||
/* cookie */
|
||||
NULL, /* initialized below */
|
||||
|
||||
/* mapping/unmapping */
|
||||
isa_map,
|
||||
isa_unmap,
|
||||
isa_subregion,
|
||||
|
||||
/* allocation/deallocation */
|
||||
isa_alloc,
|
||||
isa_free,
|
||||
|
||||
/* barrier */
|
||||
isa_barrier,
|
||||
|
||||
/* read (single) */
|
||||
isa_r_1,
|
||||
isa_r_2,
|
||||
isa_r_4,
|
||||
bs_notimpl_r_8,
|
||||
|
||||
/* read multiple */
|
||||
isa_rm_1,
|
||||
isa_rm_2,
|
||||
isa_rm_4,
|
||||
bs_notimpl_rm_8,
|
||||
|
||||
/* read region */
|
||||
isa_rr_1,
|
||||
isa_rr_2,
|
||||
isa_rr_4,
|
||||
bs_notimpl_rr_8,
|
||||
|
||||
/* write (single) */
|
||||
isa_w_1,
|
||||
isa_w_2,
|
||||
isa_w_4,
|
||||
bs_notimpl_w_8,
|
||||
|
||||
/* write multiple */
|
||||
isa_wm_1,
|
||||
isa_wm_2,
|
||||
isa_wm_4,
|
||||
bs_notimpl_wm_8,
|
||||
|
||||
/* write region */
|
||||
isa_wr_1,
|
||||
isa_wr_2,
|
||||
isa_wr_4,
|
||||
bs_notimpl_wr_8,
|
||||
|
||||
/* set multiple */
|
||||
bs_notimpl_sm_1,
|
||||
bs_notimpl_sm_2,
|
||||
bs_notimpl_sm_4,
|
||||
bs_notimpl_sm_8,
|
||||
|
||||
/* set region */
|
||||
bs_notimpl_sr_1,
|
||||
bs_notimpl_sr_2,
|
||||
bs_notimpl_sr_4,
|
||||
bs_notimpl_sr_8,
|
||||
|
||||
/* copy */
|
||||
bs_notimpl_c_1,
|
||||
bs_notimpl_c_2,
|
||||
bs_notimpl_c_4,
|
||||
bs_notimpl_c_8,
|
||||
};
|
||||
|
||||
/* bus space functions */
|
||||
|
||||
void
|
||||
isa_io_init(vm_offset_t isa_io_addr, vm_offset_t isa_mem_addr)
|
||||
{
|
||||
isa_io_bs_tag.bs_cookie = (void *)isa_io_addr;
|
||||
isa_mem_bs_tag.bs_cookie = (void *)isa_mem_addr;
|
||||
}
|
||||
|
||||
/* break the abstraction: sometimes, other parts of the system
|
||||
(e.g. X servers) need to map ISA space directly. use these
|
||||
functions sparingly! */
|
||||
vm_offset_t
|
||||
isa_io_data_vaddr()
|
||||
{
|
||||
return (vm_offset_t)isa_io_bs_tag.bs_cookie;
|
||||
}
|
||||
|
||||
vm_offset_t
|
||||
isa_mem_data_vaddr()
|
||||
{
|
||||
return (vm_offset_t)isa_mem_bs_tag.bs_cookie;
|
||||
}
|
||||
|
||||
int
|
||||
isa_map(t, bpa, size, cacheable, bshp)
|
||||
void *t;
|
||||
bus_addr_t bpa;
|
||||
bus_size_t size;
|
||||
int cacheable;
|
||||
bus_space_handle_t *bshp;
|
||||
{
|
||||
*bshp = bpa + (bus_addr_t)t;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
isa_unmap(t, bsh, size)
|
||||
void *t;
|
||||
bus_space_handle_t bsh;
|
||||
bus_size_t size;
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
int
|
||||
isa_subregion(t, bsh, offset, size, nbshp)
|
||||
void *t;
|
||||
bus_space_handle_t bsh;
|
||||
bus_size_t offset, size;
|
||||
bus_space_handle_t *nbshp;
|
||||
{
|
||||
panic("isa_subregion(): Help!\n");
|
||||
}
|
||||
|
||||
int
|
||||
isa_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
|
||||
bpap, bshp)
|
||||
void *t;
|
||||
bus_addr_t rstart, rend;
|
||||
bus_size_t size, alignment, boundary;
|
||||
int cacheable;
|
||||
bus_addr_t *bpap;
|
||||
bus_space_handle_t *bshp;
|
||||
{
|
||||
panic("isa_alloc(): Help!\n");
|
||||
}
|
||||
|
||||
void
|
||||
isa_free(t, bsh, size)
|
||||
void *t;
|
||||
bus_space_handle_t bsh;
|
||||
bus_size_t size;
|
||||
{
|
||||
panic("isa_free(): Help!\n");
|
||||
}
|
||||
|
||||
void
|
||||
isa_barrier(t, bsh, offset, len, flags)
|
||||
void *t;
|
||||
bus_space_handle_t bsh;
|
||||
bus_size_t offset, len;
|
||||
int flags;
|
||||
{
|
||||
panic("isa_barrier(): Help!\n");
|
||||
}
|
|
@ -0,0 +1,391 @@
|
|||
/* $NetBSD: isa_io_asm.S,v 1.1 1998/06/08 17:49:44 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bus_space I/O functions for isa
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
fp .req r11
|
||||
ip .req r12
|
||||
sp .req r13
|
||||
lr .req r14
|
||||
pc .req r15
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* read single
|
||||
*/
|
||||
|
||||
ENTRY(isa_r_1)
|
||||
ldrb r0, [r1, r2]
|
||||
#ifdef GPROF
|
||||
nop ; nop ; nop ; nop ; nop
|
||||
#endif
|
||||
mov pc, lr
|
||||
|
||||
ENTRY(isa_r_2)
|
||||
add r0, r1, r2
|
||||
/* ldrh r0, [r0] */ .word 0xe1d000b0
|
||||
#ifdef GPROF
|
||||
nop ; nop ; nop ; nop ; nop
|
||||
#endif
|
||||
mov pc, lr
|
||||
|
||||
ENTRY(isa_r_4)
|
||||
ldr r0, [r1, r2]
|
||||
#ifdef GPROF
|
||||
nop ; nop ; nop ; nop ; nop
|
||||
#endif
|
||||
mov pc, lr
|
||||
/*
|
||||
* read multiple.
|
||||
*
|
||||
* cloned from assembly generated for:
|
||||
*
|
||||
* void
|
||||
* isa_rm_4(v, h, o, p, s)
|
||||
* void *v;
|
||||
* bus_space_handle_t h;
|
||||
* bus_size_t o, s;
|
||||
* u_int32_t *p;
|
||||
* {
|
||||
* u_int32_t *port, *lim;
|
||||
*
|
||||
* port = (u_in32_t *)(h + o);
|
||||
* lim = p + s;
|
||||
*
|
||||
* while (p < lim)
|
||||
* *p++ = *port;;
|
||||
* }
|
||||
*/
|
||||
|
||||
ENTRY(isa_rm_1)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add ip, r0, r3
|
||||
cmp r0, ip
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_rm_1_loop:
|
||||
ldrb r3, [r1, #0]
|
||||
strb r3, [r0], #1
|
||||
cmp r0, ip
|
||||
bcc Lisa_rm_1_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_rm_2)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add ip, r0, r3, asl #1
|
||||
cmp r0, ip
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_rm_2_loop:
|
||||
/* ldrh r3, [r1] */ .word 0xe1d130b0
|
||||
/* strh r3, [r0], #2 */ .word 0xe0c030b2
|
||||
cmp r0, ip
|
||||
bcc Lisa_rm_2_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_rm_4)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add ip, r0, r3, asl #2
|
||||
cmp r0, ip
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_rm_4_loop:
|
||||
ldr r3, [r1, #0]
|
||||
str r3, [r0], #4
|
||||
cmp r0, ip
|
||||
bcc Lisa_rm_4_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
/*
|
||||
* read region.
|
||||
*
|
||||
* cloned from assembly generated for:
|
||||
*
|
||||
* void
|
||||
* isa_wr_4(v, h, o, p, s)
|
||||
* void *v;
|
||||
* bus_space_handle_t h;
|
||||
* bus_size_t o, s;
|
||||
* u_int32_t *p;
|
||||
* {
|
||||
* u_int32_t *cur, *lim;
|
||||
*
|
||||
* cur = (u_in32_t *)(h + o);
|
||||
* lim = cur + s;
|
||||
*
|
||||
* while (cur < lim)
|
||||
* *cur++ = *p++;
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(isa_rr_1)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add r2, r1, r3
|
||||
cmp r1, r2
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_rr_1_loop:
|
||||
ldrb r3, [r1], #1
|
||||
strb r3, [r0], #1
|
||||
cmp r1, r2
|
||||
bcc Lisa_rr_1_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_rr_2)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add r2, r1, r3, asl #1
|
||||
cmp r1, r2
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_rr_2_loop:
|
||||
/* ldrh r3, [r1], #2 */ .word 0xe0d130b2
|
||||
/* strh r3, [r0], #2 */ .word 0xe0c030b2
|
||||
cmp r1, r2
|
||||
bcc Lisa_rr_2_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_rr_4)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add r2, r1, r3, asl #2
|
||||
cmp r1, r2
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_rr_4_loop:
|
||||
ldr r3, [r1], #4
|
||||
str r3, [r0], #4
|
||||
cmp r1, r2
|
||||
bcc Lisa_rr_4_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
/*
|
||||
* write single
|
||||
*/
|
||||
|
||||
ENTRY(isa_w_1)
|
||||
strb r3, [r1, r2]
|
||||
#ifdef GPROF
|
||||
nop ; nop ; nop ; nop ; nop
|
||||
#endif
|
||||
mov pc, lr
|
||||
|
||||
ENTRY(isa_w_2)
|
||||
add r0, r1, r2
|
||||
/* strh r3, [r0] */ .word 0xe1c030b0
|
||||
#ifdef GPROF
|
||||
nop ; nop ; nop ; nop ; nop
|
||||
#endif
|
||||
mov pc, lr
|
||||
|
||||
ENTRY(isa_w_4)
|
||||
str r3, [r1, r2]
|
||||
#ifdef GPROF
|
||||
nop ; nop ; nop ; nop ; nop
|
||||
#endif
|
||||
mov pc, lr
|
||||
|
||||
/* write multiple
|
||||
*
|
||||
* cloned from assembly generated for:
|
||||
*
|
||||
* void
|
||||
* isa_wm_4(v, h, o, p, s)
|
||||
* void *v;
|
||||
* bus_space_handle_t h;
|
||||
* bus_size_t o, s;
|
||||
* u_int32_t *p;
|
||||
* {
|
||||
* u_int32_t *port, *lim;
|
||||
*
|
||||
* port = (u_in32_t *)(h + o);
|
||||
* lim = p + s;
|
||||
*
|
||||
* while (p < lim)
|
||||
* *port = *p++;
|
||||
* }
|
||||
*/
|
||||
ENTRY(isa_wm_1)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add ip, r0, r3
|
||||
cmp r0, ip
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_wm_1_loop:
|
||||
ldrb r3, [r0], #1
|
||||
strb r3, [r1]
|
||||
cmp r0, ip
|
||||
bcc Lisa_wm_1_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_wm_2)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add ip, r0, r3, asl #1
|
||||
cmp r0, ip
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_wm_2_loop:
|
||||
/* ldrh r3, [r0], #2 */ .word 0xe0d030b2
|
||||
/* strh r3, [r1] */ .word 0xe1c130b0
|
||||
cmp r0, ip
|
||||
bcc Lisa_wm_2_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_wm_4)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add ip, r0, r3, asl #2
|
||||
cmp r0, ip
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_wm_4_loop:
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1]
|
||||
cmp r0, ip
|
||||
bcc Lisa_wm_4_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
/*
|
||||
* write region.
|
||||
*
|
||||
* cloned from assembly generated for:
|
||||
*
|
||||
* void
|
||||
* isa_wr_4(v, h, o, p, s)
|
||||
* void *v;
|
||||
* bus_space_handle_t h;
|
||||
* bus_size_t o, s;
|
||||
* u_int32_t *p;
|
||||
* {
|
||||
* u_int32_t *cur, *lim;
|
||||
*
|
||||
* cur = (u_in32_t *)(h + o);
|
||||
* lim = cur + s;
|
||||
*
|
||||
* while (cur < lim)
|
||||
* *cur++ = *p++;
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
ENTRY(isa_wr_1)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add r2, r1, r3
|
||||
cmp r1, r2
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_wr_1_loop:
|
||||
ldrb r3, [r0], #1
|
||||
strb r3, [r1], #1
|
||||
cmp r1, r2
|
||||
bcc Lisa_wr_1_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_wr_2)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add r2, r1, r3, asl #1
|
||||
cmp r1, r2
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_wr_2_loop:
|
||||
/* ldrh r3, [r0], #2 */ .word 0xe0d030b2
|
||||
/* strh r3, [r1], #2 */ .word 0xe0c130b2
|
||||
cmp r1, r2
|
||||
bcc Lisa_wr_2_loop
|
||||
ldmea fp, {fp, sp, pc}
|
||||
|
||||
ENTRY(isa_wr_4)
|
||||
mov ip, sp
|
||||
stmfd sp!, {fp, ip, lr, pc}
|
||||
mov r0, r3
|
||||
add r1, r1, r2
|
||||
sub fp, ip, #4
|
||||
ldr r3, [fp, #4]
|
||||
add r2, r1, r3, asl #2
|
||||
cmp r1, r2
|
||||
ldmcsea fp, {fp, sp, pc}
|
||||
Lisa_wr_4_loop:
|
||||
ldr r3, [r0], #4
|
||||
str r3, [r1], #4
|
||||
cmp r1, r2
|
||||
bcc Lisa_wr_4_loop
|
||||
ldmea fp, {fp, sp, pc}
|
|
@ -0,0 +1,585 @@
|
|||
/* $NetBSD: isa_irq.S,v 1.1 1998/06/08 17:49:44 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994-1997 Mark Brinicombe.
|
||||
* Copyright (c) 1994 Brini.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software written for Brini by Mark Brinicombe
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Brini.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI OR CONTRIBUTORS 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.
|
||||
*
|
||||
* RiscBSD kernel project
|
||||
*
|
||||
* irq.S
|
||||
*
|
||||
* Low level irq and fiq handlers
|
||||
*
|
||||
* Created : 27/09/94
|
||||
*/
|
||||
|
||||
#include "assym.h"
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/frame.h>
|
||||
#include <dev/isa/isareg.h>
|
||||
#include <arm32/isa/icu.h>
|
||||
#include <machine/asm.h>
|
||||
#include <machine/irqhandler.h>
|
||||
|
||||
sp .req r13
|
||||
lr .req r14
|
||||
pc .req r15
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
*
|
||||
* irq_entry
|
||||
*
|
||||
* Main entry point for the IRQ vector
|
||||
*
|
||||
* This function reads the irq request bits in the IOMD registers
|
||||
* IRQRQA, IRQRQB and DMARQ
|
||||
* It then calls an installed handler for each bit that is set.
|
||||
* The function stray_irqhandler is called if a handler is not defined
|
||||
* for a particular interrupt.
|
||||
* If a interrupt handler is found then it is called with r0 containing
|
||||
* the argument defined in the handler structure. If the field ih_arg
|
||||
* is zero then a pointer to the IRQ frame on the stack is passed instead.
|
||||
*/
|
||||
|
||||
Ldisabled_mask:
|
||||
.word _disabled_mask
|
||||
|
||||
Lcurrent_spl_level:
|
||||
.word _current_spl_level
|
||||
|
||||
Lcurrent_intr_depth:
|
||||
.word _current_intr_depth
|
||||
|
||||
Lvam_io_data:
|
||||
.word _isa_io_bs_tag
|
||||
|
||||
.text
|
||||
|
||||
.global irq_entry
|
||||
|
||||
/*
|
||||
* Register usage
|
||||
*
|
||||
* r6 - Address of current handler
|
||||
* r7 - Pointer to handler pointer list
|
||||
* r8 - Current IRQ requests.
|
||||
* r9 - Used to count through possible IRQ bits.
|
||||
* r10 - Base address of IOMD
|
||||
*/
|
||||
|
||||
/* Some documentation is in isa_machdep.c */
|
||||
irq_entry:
|
||||
sub lr, lr, #0x00000004 /* Adjust the lr */
|
||||
|
||||
PUSHFRAMEINSVC /* Push an interrupt frame */
|
||||
|
||||
/* mov r11, #0x00000000*/ /* Trace back stops here */
|
||||
|
||||
/* Load r8 with the ISA 8259 irqs */
|
||||
/* r8 <- irq's pending [15:0] */
|
||||
|
||||
/* address of 8259 #1 */
|
||||
ldr r0, Lvam_io_data
|
||||
ldr r0, [r0]
|
||||
ldrb r8, [r0, #IO_ICU1] /* ocw3 = irr */
|
||||
|
||||
/* clear the IRR bits that are currently masked. */
|
||||
ldr r2, Li8259_mask
|
||||
ldr r2, [r2]
|
||||
mvn r2, r2 /* disabled -> enabled */
|
||||
|
||||
/* address of 8259 #2 */
|
||||
tst r2, #(1 << IRQ_SLAVE) /* if slave is enabled */
|
||||
tstne r8, #(1 << IRQ_SLAVE) /* anything from slave? */
|
||||
ldrneb r1, [r0, #IO_ICU2] /* ocw3 = irr */
|
||||
orrne r8, r8, r1, lsl #8
|
||||
|
||||
and r8, r8, r2 /* clear disabled */
|
||||
|
||||
/* clear IRQ 2, which is only used for slave 8259 */
|
||||
bic r8, r8, #(1 << IRQ_SLAVE)
|
||||
|
||||
/*
|
||||
* Note that we have entered the IRQ handler.
|
||||
* We are in SVC mode so we cannot use the processor mode
|
||||
* to determine if we are in an IRQ. Instead we will count the
|
||||
* each time the interrupt handler is nested.
|
||||
*/
|
||||
|
||||
ldr r0, Lcurrent_intr_depth
|
||||
ldr r1, [r0]
|
||||
add r1, r1, #1
|
||||
str r1, [r0]
|
||||
|
||||
/* Block the current requested interrupts */
|
||||
|
||||
ldr r1, Ldisabled_mask
|
||||
ldr r0, [r1]
|
||||
stmfd sp!, {r0}
|
||||
orr r0, r0, r8
|
||||
str r0, [r1]
|
||||
|
||||
/*
|
||||
* Need to block all interrupts at the IPL or lower for
|
||||
* all asserted interrupts.
|
||||
* This basically emulates hardware interrupt priority levels.
|
||||
* Means we need to go through the interrupt mask and for
|
||||
* every asserted interrupt we need to mask out all other
|
||||
* interrupts at the same or lower IPL.
|
||||
* If only we could wait until the main loop but we need to sort
|
||||
* this out first so interrupts can be re-enabled.
|
||||
*
|
||||
* This would benefit from a special ffs type routine
|
||||
*/
|
||||
|
||||
mov r9, #0x00000001
|
||||
ldr r7, Lirqblock
|
||||
|
||||
emulate_hwipl_loop:
|
||||
tst r8, r9
|
||||
ldrne r6, [r7]
|
||||
orrne r0, r0, r6
|
||||
|
||||
add r7, r7, #4
|
||||
mov r9, r9, lsl #1 /* move on to next bit */
|
||||
#ifdef CPU_ARM7500
|
||||
teq r9, #0 /* done the last bit ? */
|
||||
#else
|
||||
teq r9, #(1 << 24) /* done the last bit ? */
|
||||
#endif /* CPU_ARM7500 */
|
||||
bne emulate_hwipl_loop /* no - loop back. */
|
||||
|
||||
str r0, [r1]
|
||||
|
||||
/* Update the IOMD irq masks */
|
||||
|
||||
bl _irq_setmasks
|
||||
|
||||
mrs r0, cpsr_all /* Enable IRQ's */
|
||||
bic r0, r0, #I32_bit
|
||||
msr cpsr_all, r0
|
||||
|
||||
ldr r7, [pc, #irqhandlers - . - 8]
|
||||
mov r9, #0x00000001
|
||||
|
||||
stmfd sp!, {r8}
|
||||
|
||||
irqloop:
|
||||
/* This would benefit from a special ffs type routine */
|
||||
tst r8, r9 /* Is a bit set ? */
|
||||
beq nextirq /* No ? try next bit */
|
||||
|
||||
ldr r6, [r7] /* Get address of first handler structure */
|
||||
|
||||
teq r6, #0x00000000 /* Do we have a handler */
|
||||
moveq r0, r8 /* IRQ requests as arg 0 */
|
||||
beq _stray_irqhandler /* call special handler */
|
||||
|
||||
ldr r0, Lcnt
|
||||
ldr r1, [r0, #(V_INTR)]
|
||||
add r1, r1, #0x00000001
|
||||
str r1, [r0, #(V_INTR)]
|
||||
|
||||
irqchainloop:
|
||||
add lr, pc, #nextinchain - . - 8 /* return address */
|
||||
|
||||
/*
|
||||
* XXX: Should stats be accumlated for every interrupt routine called
|
||||
* or for every physical interrupt that is serviced.
|
||||
*/
|
||||
|
||||
#ifdef IRQSTATS
|
||||
ldr r0, Lintrcnt
|
||||
ldr r1, [r6, #(IH_NUM)]
|
||||
|
||||
add r0, r0, r1, lsl #2
|
||||
ldr r1, [r0]
|
||||
add r1, r1, #0x00000001
|
||||
str r1, [r0]
|
||||
#endif /* IRQSTATS */
|
||||
|
||||
ldr r0, [r6, #(IH_ARG)] /* Get argument pointer */
|
||||
teq r0, #0x00000000 /* If arg is zero pass stack frame */
|
||||
addeq r0, sp, #8 /* ... stack frame */
|
||||
ldr pc, [r6, #(IH_FUNC)] /* Call handler */
|
||||
|
||||
nextinchain:
|
||||
teq r0, #0x00000001 /* Was the irq serviced ? */
|
||||
beq irqdone
|
||||
|
||||
ldr r6, [r6, #(IH_NEXT)]
|
||||
teq r6, #0x00000000
|
||||
bne irqchainloop
|
||||
|
||||
irqdone:
|
||||
nextirq:
|
||||
add r7, r7, #0x00000004 /* update pointer to handlers */
|
||||
mov r9, r9, lsl #1 /* move on to next bit */
|
||||
#ifdef CPU_ARM7500
|
||||
teq r9, #0 /* done the last bit ? */
|
||||
#else
|
||||
teq r9, #(1 << 24) /* done the last bit ? */
|
||||
#endif /* CPU_ARM7500 */
|
||||
bne irqloop /* no - loop back. */
|
||||
|
||||
ldmfd sp!, {r8}
|
||||
|
||||
/* Restore previous disabled mask */
|
||||
ldmfd sp!, {r2}
|
||||
ldr r1, Ldisabled_mask
|
||||
str r2, [r1]
|
||||
bl _irq_setmasks
|
||||
|
||||
bl _dosoftints /* Handle the soft interrupts */
|
||||
|
||||
/* Manage AST's. Maybe this should be done as a soft interrupt ? */
|
||||
|
||||
ldr r0, [sp] /* Get the SPSR from stack */
|
||||
|
||||
and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */
|
||||
teq r0, #(PSR_USR32_MODE)
|
||||
ldreq r0, Lastpending /* Do we have an AST pending ? */
|
||||
ldreq r1, [r0]
|
||||
teqeq r1, #0x00000001
|
||||
|
||||
beq irqast /* call the AST handler */
|
||||
|
||||
/* Kill IRQ's in preparation for exit */
|
||||
|
||||
mrs r0, cpsr_all
|
||||
orr r0, r0, #(I32_bit)
|
||||
msr cpsr_all, r0
|
||||
|
||||
/* Decrement the nest count */
|
||||
|
||||
ldr r0, Lcurrent_intr_depth
|
||||
ldr r1, [r0]
|
||||
sub r1, r1, #1
|
||||
str r1, [r0]
|
||||
|
||||
PULLFRAMEFROMSVCANDEXIT
|
||||
|
||||
movs pc, lr /* Exit */
|
||||
|
||||
/*
|
||||
* Ok, snag with current intr depth ...
|
||||
* If ast() calls mi_sleep() the current_intr_depth will not be
|
||||
* decremented until the process is woken up. This can result
|
||||
* in the system believing it is still in the interrupt handler.
|
||||
* If we are calling ast() then correct the current_intr_depth
|
||||
* before the call.
|
||||
*/
|
||||
irqast:
|
||||
mov r1, #0x00000000 /* Clear ast_pending */
|
||||
str r1, [r0]
|
||||
|
||||
/* Kill IRQ's so we atomically decrement current_intr_depth */
|
||||
|
||||
mrs r2, cpsr_all
|
||||
orr r3, r2, #(I32_bit)
|
||||
msr cpsr_all, r3
|
||||
|
||||
/* Decrement the nest count */
|
||||
|
||||
ldr r0, Lcurrent_intr_depth
|
||||
ldr r1, [r0]
|
||||
sub r1, r1, #1
|
||||
str r1, [r0]
|
||||
|
||||
/* Restore IRQ's */
|
||||
msr cpsr_all, r2
|
||||
|
||||
mov r0, sp
|
||||
bl _ast
|
||||
|
||||
/* Kill IRQ's in preparation for exit */
|
||||
|
||||
mrs r0, cpsr_all
|
||||
orr r0, r0, #(I32_bit)
|
||||
msr cpsr_all, r0
|
||||
|
||||
PULLFRAMEFROMSVCANDEXIT
|
||||
|
||||
movs pc, lr /* Exit */
|
||||
|
||||
|
||||
Lspl_mask:
|
||||
.word _spl_mask /* irq's allowed at current spl level */
|
||||
|
||||
Lcurrent_mask:
|
||||
.word _current_mask /* irq's that are usable */
|
||||
|
||||
Lirqblock:
|
||||
.word _irqblock
|
||||
|
||||
ENTRY(irq_setmasks)
|
||||
/* Disable interrupts */
|
||||
mrs r3, cpsr_all
|
||||
orr r1, r3, #(I32_bit)
|
||||
msr cpsr_all, r1
|
||||
|
||||
/* Calculate interrupt mask */
|
||||
ldr r1, Lcurrent_mask /* All the enabled interrupts */
|
||||
#ifdef LDRH
|
||||
ldrh r1, [r1] /* get hardware bits of mask */
|
||||
#else
|
||||
.word 0xe0d110b0 /* hand-assembled ldrh r1, [r1] */
|
||||
#endif
|
||||
ldr r2, Lspl_mask /* Block due to current spl level */
|
||||
ldr r2, [r2]
|
||||
and r1, r1, r2
|
||||
ldr r2, Ldisabled_mask /* Block due to active interrupts */
|
||||
ldr r2, [r2]
|
||||
bic r1, r1, r2
|
||||
|
||||
/* since 8259's are so slow to access, this code does everything
|
||||
possible to avoid them */
|
||||
|
||||
/* get current mask: these are the bits */
|
||||
ldr r0, Li8259_mask
|
||||
ldr r2, [r0]
|
||||
/* r2 = 0000.0000.0000.0000.ZZZZ.ZZZZ.ZZZZ.ZZZZ */
|
||||
|
||||
/* see if there's anything enabled on 8259 #2 */
|
||||
tst r1, #0xff00
|
||||
|
||||
biceq r1, r1, #(1 << IRQ_SLAVE) /* no, so disable it */
|
||||
orrne r1, r1, #(1 << IRQ_SLAVE) /* yes, so enable it */
|
||||
/* eq => r1 = 0000.0000.0000.0000.0000.0000.MMMM.M0MM
|
||||
ne => r1 = 0000.0000.0000.0000.MMMM.MMMM.MMMM.M1MM */
|
||||
|
||||
/* 8259 bit high => disable */
|
||||
mvn r1, r1
|
||||
/* eq => r1 = 1111.1111.1111.1111.1111.1111.YYYY.Y1YY
|
||||
ne => r1 = 1111.1111.1111.1111.YYYY.YYYY.YYYY.Y0YY
|
||||
(for each bit position Y = !M) */
|
||||
|
||||
orreq r1, r2, r1, lsl #16
|
||||
/* eq => r1 = 1111.1111.YYYY.Y1YY.ZZZZ.ZZZZ.ZZZZ.ZZZZ
|
||||
ne => r1 = 1111.1111.1111.1111.YYYY.YYYY.YYYY.Y0YY */
|
||||
orreq r1, r1, #0x000000FF
|
||||
/* eq => r1 = 1111.1111.YYYY.Y1YY.ZZZZ.ZZZZ.1111.1111
|
||||
ne => r1 = 1111.1111.1111.1111.YYYY.YYYY.YYYY.Y0YY */
|
||||
and r1, r1, r1, lsr #16
|
||||
/* eq => r1 = 0000.0000.0000.0000.ZZZZ.ZZZZ.YYYY.Y1YY
|
||||
ne => r1 = 0000.0000.0000.0000.YYYY.YYYY.YYYY.Y0YY */
|
||||
|
||||
/* if old = new, don't bother to set again.
|
||||
fast path to exit, since 8259's are so slow anyway */
|
||||
eors r2, r1, r2 /* which bits are different? */
|
||||
msreq cpsr_all, r3 /* no bits are different, return */
|
||||
moveq pc, lr
|
||||
|
||||
/* have to set at least one of the 8259's, store new mask */
|
||||
str r1, [r0]
|
||||
ldr r0, Lvam_io_data
|
||||
ldr r0, [r0]
|
||||
|
||||
/* see if there's any change for 8259 #1 (master) */
|
||||
tst r2, #0x00FF /* bottom 8 bits different? */
|
||||
strneb r1, [r0, #(IO_ICU1 + 1)] /* icu1 / ocw1 */
|
||||
|
||||
/* anything for 8259 #2? */
|
||||
tst r2, #0xFF00
|
||||
mov r1, r1, lsr #8 /* next byte */
|
||||
strneb r1, [r0, #(IO_ICU2 + 1)] /* icu2 / ocw1 */
|
||||
|
||||
/* Restore old cpsr and exit */
|
||||
msr cpsr_all, r3
|
||||
mov pc, lr
|
||||
|
||||
|
||||
Lcnt:
|
||||
.word _cnt
|
||||
|
||||
Lintrcnt:
|
||||
.word _intrcnt
|
||||
|
||||
Li8259_mask:
|
||||
.word _i8259_mask
|
||||
|
||||
irqhandlers:
|
||||
.word _irqhandlers /* Pointer to array of irqhandlers */
|
||||
|
||||
Lastpending:
|
||||
.word _astpending
|
||||
|
||||
#ifdef IRQSTATS
|
||||
/* These symbols are used by vmstat */
|
||||
|
||||
.text
|
||||
.global __intrnames
|
||||
__intrnames:
|
||||
.word _intrnames
|
||||
|
||||
.data
|
||||
|
||||
/* XXX fix */
|
||||
.globl _intrnames, _eintrnames, _intrcnt, _eintrcnt
|
||||
_intrnames:
|
||||
.asciz "interrupt 0 "
|
||||
.asciz "softnet " /* reserved0 */
|
||||
.asciz "interrupt 2 "
|
||||
.asciz "interrupt 3 "
|
||||
.asciz "interrupt 4 "
|
||||
.asciz "interrupt 5 "
|
||||
.asciz "interrupt 6 "
|
||||
.asciz "softclock " /* reserved1 */
|
||||
.asciz "softplip " /* reserved2 */
|
||||
.asciz "interrupt 9 "
|
||||
.asciz "interrupt 10 "
|
||||
.asciz "interrupt 11 "
|
||||
.asciz "interrupt 12 "
|
||||
.asciz "interrupt 13 "
|
||||
.asciz "interrupt 14 "
|
||||
.asciz "interrupt 15 "
|
||||
.asciz "dma channel 0"
|
||||
.asciz "dma channel 1"
|
||||
.asciz "dma channel 2"
|
||||
.asciz "dma channel 3"
|
||||
.asciz "interrupt 20 "
|
||||
.asciz "interrupt 21 "
|
||||
.asciz "reserved 3 "
|
||||
.asciz "reserved 4 "
|
||||
.asciz "exp card 0 "
|
||||
.asciz "exp card 1 "
|
||||
.asciz "exp card 2 "
|
||||
.asciz "exp card 3 "
|
||||
.asciz "exp card 4 "
|
||||
.asciz "exp card 5 "
|
||||
.asciz "exp card 6 "
|
||||
.asciz "exp card 7 "
|
||||
_eintrnames:
|
||||
|
||||
.bss
|
||||
.align 0
|
||||
_intrcnt:
|
||||
.space 32*4 /* XXX Should be linked to number of interrupts */
|
||||
_eintrcnt:
|
||||
|
||||
#else /* IRQSTATS */
|
||||
/* Dummy entries to keep vmstat happy */
|
||||
|
||||
.text
|
||||
.globl _intrnames, _eintrnames, _intrcnt, _eintrcnt
|
||||
_intrnames:
|
||||
.long 0
|
||||
_eintrnames:
|
||||
|
||||
_intrcnt:
|
||||
.long 0
|
||||
_eintrcnt:
|
||||
#endif /* IRQSTATS */
|
||||
|
||||
/* FIQ code */
|
||||
|
||||
.text
|
||||
.align 0
|
||||
.global _fiq_setregs /* Sets up the FIQ handler */
|
||||
|
||||
_fiq_setregs:
|
||||
mrs r2, cpsr_all
|
||||
mov r3, r2
|
||||
bic r2, r2, #(PSR_MODE)
|
||||
orr r2, r2, #(PSR_FIQ32_MODE)
|
||||
orr r2, r2, #(I32_bit | F32_bit) /* IRQs/FIQs definitely off */
|
||||
msr cpsr_all, r2
|
||||
|
||||
ldr r8, [r0, #FH_R8] /* Update FIQ registers*/
|
||||
ldr r9, [r0, #FH_R9]
|
||||
ldr r10, [r0, #FH_R10]
|
||||
ldr r11, [r0, #FH_R11]
|
||||
ldr r12, [r0, #FH_R12]
|
||||
ldr r13, [r0, #FH_R13]
|
||||
|
||||
msr cpsr_all, r3 /* Back to old mode */
|
||||
|
||||
mov pc, lr /* Exit */
|
||||
|
||||
.global _fiq_getregs /* Gets the FIQ registers */
|
||||
|
||||
_fiq_getregs:
|
||||
mrs r2, cpsr_all
|
||||
mov r3, r2
|
||||
bic r2, r2, #(PSR_MODE)
|
||||
orr r2, r2, #(PSR_FIQ32_MODE)
|
||||
orr r2, r2, #(I32_bit | F32_bit) /* IRQs/FIQs definitely off */
|
||||
msr cpsr_all, r2
|
||||
|
||||
str r8, [r0, #FH_R8] /* Update FIQ registers*/
|
||||
str r9, [r0, #FH_R9]
|
||||
str r10, [r0, #FH_R10]
|
||||
str r11, [r0, #FH_R11]
|
||||
str r12, [r0, #FH_R12]
|
||||
str r13, [r0, #FH_R13]
|
||||
|
||||
msr cpsr_all, r3 /* Back to old mode */
|
||||
|
||||
mov pc, lr /* Exit */
|
||||
|
||||
/* End of irq.S */
|
|
@ -0,0 +1,591 @@
|
|||
/* $NetBSD: isa_irqhandler.c,v 1.1 1998/06/08 17:49:44 tv 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994-1996 Mark Brinicombe.
|
||||
* Copyright (c) 1994 Brini.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software written for Brini by Mark Brinicombe
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Brini.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI OR CONTRIBUTORS 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.
|
||||
*
|
||||
* RiscBSD kernel project
|
||||
*
|
||||
* irqhandler.c
|
||||
*
|
||||
* IRQ/FIQ initialisation, claim, release and handler routines
|
||||
*
|
||||
* Created : 30/09/94
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <vm/vm.h>
|
||||
#include <net/netisr.h>
|
||||
|
||||
#include <machine/irqhandler.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
irqhandler_t *irqhandlers[NIRQS];
|
||||
fiqhandler_t *fiqhandlers;
|
||||
|
||||
int current_intr_depth = 0;
|
||||
u_int irqmasks[IPL_LEVELS];
|
||||
u_int current_mask;
|
||||
u_int actual_mask;
|
||||
u_int disabled_mask = 0;
|
||||
u_int spl_mask;
|
||||
u_int soft_interrupts;
|
||||
extern u_int intrcnt[];
|
||||
|
||||
u_int irqblock[NIRQS];
|
||||
|
||||
typedef struct {
|
||||
vm_offset_t physical;
|
||||
vm_offset_t virtual;
|
||||
} pv_addr_t;
|
||||
|
||||
extern pv_addr_t systempage;
|
||||
extern char *_intrnames;
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
extern void zero_page_readonly __P((void));
|
||||
extern void zero_page_readwrite __P((void));
|
||||
extern int fiq_setregs __P((fiqhandler_t *));
|
||||
extern int fiq_getregs __P((fiqhandler_t *));
|
||||
extern void set_spl_masks __P((void));
|
||||
|
||||
extern void arpintr __P((void));
|
||||
extern void ipintr __P((void));
|
||||
extern void pppintr __P((void));
|
||||
extern void plipintr __P((void));
|
||||
|
||||
void irq_calculatemasks __P((void));
|
||||
|
||||
#define WriteWord(a, b) \
|
||||
*((volatile unsigned int *)(a)) = (b)
|
||||
|
||||
/*
|
||||
* void irq_init(void)
|
||||
*
|
||||
* Initialise the IRQ/FIQ sub system
|
||||
*/
|
||||
|
||||
void
|
||||
irq_init()
|
||||
{
|
||||
int loop;
|
||||
|
||||
/* Clear all the IRQ handlers and the irq block masks */
|
||||
|
||||
for (loop = 0; loop < NIRQS; ++loop) {
|
||||
irqhandlers[loop] = NULL;
|
||||
irqblock[loop] = 0;
|
||||
}
|
||||
|
||||
/* Clear the FIQ handler */
|
||||
|
||||
fiqhandlers = NULL;
|
||||
|
||||
/*
|
||||
* Setup the irqmasks for the different Interrupt Priority Levels
|
||||
* We will start with no bits set and these will be updated as handlers
|
||||
* are installed at different IPL's.
|
||||
*/
|
||||
|
||||
irqmasks[IPL_BIO] = 0x00000000;
|
||||
irqmasks[IPL_NET] = 0x00000000;
|
||||
irqmasks[IPL_TTY] = 0x00000000;
|
||||
irqmasks[IPL_CLOCK] = 0x00000000;
|
||||
irqmasks[IPL_IMP] = 0x00000000;
|
||||
irqmasks[IPL_NONE] = 0x00000000;
|
||||
|
||||
current_mask = 0x00000000;
|
||||
actual_mask = 0x00000000;
|
||||
spl_mask = 0x00000000;
|
||||
soft_interrupts = 0x00000000;
|
||||
|
||||
set_spl_masks();
|
||||
|
||||
/* Enable IRQ's and FIQ's */
|
||||
|
||||
enable_interrupts(I32_bit | F32_bit);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int irq_claim(int irq, irqhandler_t *handler)
|
||||
*
|
||||
* Enable an IRQ and install a handler for it.
|
||||
*/
|
||||
|
||||
int
|
||||
irq_claim(irq, handler)
|
||||
int irq;
|
||||
irqhandler_t *handler;
|
||||
{
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
/* Sanity check */
|
||||
if (handler == NULL)
|
||||
panic("NULL interrupt handler\n");
|
||||
if (handler->ih_func == NULL)
|
||||
panic("Interrupt handler does not have a function\n");
|
||||
#endif /* DIAGNOSTIC */
|
||||
|
||||
/*
|
||||
* IRQ_INSTRUCT indicates that we should get the irq number
|
||||
* from the irq structure
|
||||
*/
|
||||
|
||||
if (irq == IRQ_INSTRUCT)
|
||||
irq = handler->ih_num;
|
||||
|
||||
/* Make sure the irq number is valid */
|
||||
|
||||
if (irq < 0 || irq >= NIRQS)
|
||||
return(-1);
|
||||
|
||||
/* Make sure the level is valid */
|
||||
|
||||
if (handler->ih_level < 0 || handler->ih_level >= IPL_LEVELS)
|
||||
return(-1);
|
||||
|
||||
/* Attach handler at top of chain */
|
||||
|
||||
handler->ih_next = irqhandlers[irq];
|
||||
irqhandlers[irq] = handler;
|
||||
|
||||
/*
|
||||
* Reset the flags for this handler.
|
||||
* As the handler is now in the chain mark it as active.
|
||||
*/
|
||||
handler->ih_flags = 0 | IRQ_FLAG_ACTIVE;
|
||||
|
||||
/*
|
||||
* Record the interrupt number for accounting.
|
||||
* Done here as the accounting number may not be the same as the IRQ number
|
||||
* though for the moment they are
|
||||
*/
|
||||
|
||||
handler->ih_num = irq;
|
||||
|
||||
#ifdef IRQSTATS
|
||||
/* Get the interrupt name from the head of the list */
|
||||
|
||||
if (handler->ih_name) {
|
||||
char *ptr = _intrnames + (irq * 14);
|
||||
strcpy(ptr, " ");
|
||||
strncpy(ptr, handler->ih_name,
|
||||
min(strlen(handler->ih_name), 13));
|
||||
} else {
|
||||
char *ptr = _intrnames + (irq * 14);
|
||||
sprintf(ptr, "irq %2d ", irq);
|
||||
}
|
||||
#endif /* IRQSTATS */
|
||||
|
||||
irq_calculatemasks();
|
||||
|
||||
enable_irq(irq);
|
||||
set_spl_masks();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int irq_release(int irq, irqhandler_t *handler)
|
||||
*
|
||||
* Disable an IRQ and remove a handler for it.
|
||||
*/
|
||||
|
||||
int
|
||||
irq_release(irq, handler)
|
||||
int irq;
|
||||
irqhandler_t *handler;
|
||||
{
|
||||
irqhandler_t *irqhand;
|
||||
irqhandler_t **prehand;
|
||||
extern char *_intrnames;
|
||||
|
||||
/*
|
||||
* IRQ_INSTRUCT indicates that we should get the irq number
|
||||
* from the irq structure
|
||||
*/
|
||||
|
||||
if (irq == IRQ_INSTRUCT)
|
||||
irq = handler->ih_num;
|
||||
|
||||
/* Make sure the irq number is valid */
|
||||
|
||||
if (irq < 0 || irq >= NIRQS)
|
||||
return(-1);
|
||||
|
||||
|
||||
/* Locate the handler */
|
||||
|
||||
irqhand = irqhandlers[irq];
|
||||
prehand = &irqhandlers[irq];
|
||||
|
||||
while (irqhand && handler != irqhand) {
|
||||
prehand = &irqhand;
|
||||
irqhand = irqhand->ih_next;
|
||||
}
|
||||
|
||||
/* Remove the handler if located */
|
||||
|
||||
if (irqhand)
|
||||
*prehand = irqhand->ih_next;
|
||||
else
|
||||
return(-1);
|
||||
|
||||
|
||||
/* Now the handler has been removed from the chain mark is as inactive */
|
||||
|
||||
irqhand->ih_flags &= ~IRQ_FLAG_ACTIVE;
|
||||
|
||||
/* Make sure the head of the handler list is active */
|
||||
|
||||
if (irqhandlers[irq])
|
||||
irqhandlers[irq]->ih_flags |= IRQ_FLAG_ACTIVE;
|
||||
|
||||
#ifdef IRQSTATS
|
||||
/* Get the interrupt name from the head of the list */
|
||||
if (irqhandlers[irq] && irqhandlers[irq]->ih_name) {
|
||||
char *ptr = _intrnames + (irq * 14);
|
||||
strcpy(ptr, " ");
|
||||
strncpy(ptr, irqhandlers[irq]->ih_name,
|
||||
min(strlen(irqhandlers[irq]->ih_name), 13));
|
||||
} else {
|
||||
char *ptr = _intrnames + (irq * 14);
|
||||
sprintf(ptr, "irq %2d ", irq);
|
||||
}
|
||||
#endif /* IRQSTATS */
|
||||
|
||||
irq_calculatemasks();
|
||||
|
||||
/*
|
||||
* Disable the appropriate mask bit if there are no handlers left for
|
||||
* this IRQ.
|
||||
*/
|
||||
|
||||
if (irqhandlers[irq] == NULL)
|
||||
disable_irq(irq);
|
||||
|
||||
set_spl_masks();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* adapted from .../i386/isa/isa_machdep.c */
|
||||
/*
|
||||
* Recalculate the interrupt masks from scratch.
|
||||
* We could code special registry and deregistry versions of this function that
|
||||
* would be faster, but the code would be nastier, and we don't expect this to
|
||||
* happen very much anyway.
|
||||
*/
|
||||
void
|
||||
irq_calculatemasks()
|
||||
{
|
||||
int irq, level;
|
||||
irqhandler_t *ptr;
|
||||
int irqlevel[NIRQS];
|
||||
|
||||
/* First, figure out which levels each IRQ uses. */
|
||||
for (irq = 0; irq < NIRQS; irq++) {
|
||||
register int levels = 0;
|
||||
for (ptr = irqhandlers[irq]; ptr; ptr = ptr->ih_next)
|
||||
levels |= 1 << ptr->ih_level;
|
||||
irqlevel[irq] = levels;
|
||||
}
|
||||
|
||||
/* Then figure out which IRQs use each level. */
|
||||
for (level = 0; level < IPL_LEVELS; level++) {
|
||||
register int irqs = 0;
|
||||
for (irq = 0; irq < NIRQS; irq++)
|
||||
if (irqlevel[irq] & (1 << level))
|
||||
irqs |= 1 << irq;
|
||||
irqmasks[level] = ~(irqs | IRQMASK_ALLSOFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since run queues may be manipulated by both the statclock and tty,
|
||||
* network, and disk drivers, statclock > (tty | net | bio).
|
||||
*/
|
||||
irqmasks[IPL_CLOCK] &= (irqmasks[IPL_TTY] & irqmasks[IPL_NET] &
|
||||
irqmasks[IPL_BIO]);
|
||||
|
||||
/*
|
||||
* There are tty, network and disk drivers that use free() at interrupt
|
||||
* time, so imp > (tty | net | bio).
|
||||
*/
|
||||
irqmasks[IPL_IMP] &= (irqmasks[IPL_TTY] & irqmasks[IPL_NET] &
|
||||
irqmasks[IPL_BIO]);
|
||||
|
||||
/*
|
||||
* Enforce a hierarchy that gives slow devices a better chance at not
|
||||
* dropping data.
|
||||
*/
|
||||
irqmasks[IPL_TTY] &= irqmasks[IPL_NET] & irqmasks[IPL_BIO];
|
||||
irqmasks[IPL_NET] &= irqmasks[IPL_BIO];
|
||||
|
||||
#include "sl.h"
|
||||
#include "ppp.h"
|
||||
#if NSL > 0 || NPPP > 0
|
||||
/* In the presence of SLIP or PPP, splimp > spltty. */
|
||||
irqmasks[IPL_NET] &= irqmasks[IPL_TTY];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We now need to update the irqblock array. This array indicates
|
||||
* what other interrupts should be blocked when interrupt is asserted
|
||||
* This basically emulates hardware interrupt priorities e.g. by blocking
|
||||
* all other IPL_BIO interrupts with an IPL_BIO interrupt is asserted.
|
||||
* For each interrupt we find the highest IPL and set the block mask to
|
||||
* the interrupt mask for that level.
|
||||
*/
|
||||
|
||||
/* And eventually calculate the complete masks. */
|
||||
for (irq = 0; irq < NIRQS; irq++) {
|
||||
register int irqs = 1 << irq;
|
||||
for (ptr = irqhandlers[irq]; ptr; ptr = ptr->ih_next)
|
||||
irqs |= ~(irqmasks[ptr->ih_level]);
|
||||
irqblock[irq] = irqs | IRQMASK_ALLSOFT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
intr_claim(irq, level, name, ih_func, ih_arg)
|
||||
int irq;
|
||||
int level;
|
||||
const char *name;
|
||||
int (*ih_func) __P((void *));
|
||||
void *ih_arg;
|
||||
{
|
||||
irqhandler_t *ih;
|
||||
|
||||
ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
|
||||
if (!ih)
|
||||
panic("intr_claim(): Cannot malloc handler memory\n");
|
||||
|
||||
ih->ih_level = level;
|
||||
ih->ih_name = name;
|
||||
ih->ih_func = ih_func;
|
||||
ih->ih_arg = ih_arg;
|
||||
ih->ih_flags = 0;
|
||||
|
||||
if (irq_claim(irq, ih) != 0)
|
||||
return(NULL);
|
||||
return(ih);
|
||||
}
|
||||
|
||||
int
|
||||
intr_release(arg)
|
||||
void *arg;
|
||||
{
|
||||
irqhandler_t *ih = (irqhandler_t *)arg;
|
||||
|
||||
if (irq_release(ih->ih_num, ih) == 0) {
|
||||
free(ih, M_DEVBUF);
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* void disable_irq(int irq)
|
||||
*
|
||||
* Disables a specific irq. The irq is removed from the master irq mask
|
||||
*/
|
||||
|
||||
void
|
||||
disable_irq(irq)
|
||||
int irq;
|
||||
{
|
||||
register int oldirqstate;
|
||||
|
||||
oldirqstate = disable_interrupts(I32_bit);
|
||||
current_mask &= ~(1 << irq);
|
||||
irq_setmasks();
|
||||
restore_interrupts(oldirqstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* void enable_irq(int irq)
|
||||
*
|
||||
* Enables a specific irq. The irq is added to the master irq mask
|
||||
* This routine should be used with caution. A handler should already
|
||||
* be installed.
|
||||
*/
|
||||
|
||||
void
|
||||
enable_irq(irq)
|
||||
int irq;
|
||||
{
|
||||
register u_int oldirqstate;
|
||||
|
||||
oldirqstate = disable_interrupts(I32_bit);
|
||||
|
||||
current_mask |= (1 << irq);
|
||||
irq_setmasks();
|
||||
restore_interrupts(oldirqstate);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* void stray_irqhandler(u_int mask)
|
||||
*
|
||||
* Handler for stray interrupts. This gets called if a handler cannot be
|
||||
* found for an interrupt.
|
||||
*/
|
||||
|
||||
void
|
||||
stray_irqhandler(mask)
|
||||
u_int mask;
|
||||
{
|
||||
static u_int stray_irqs = 0;
|
||||
|
||||
if (++stray_irqs <= 8)
|
||||
log(LOG_ERR, "Stray interrupt %08x%s\n", mask,
|
||||
stray_irqs >= 8 ? ": stopped logging" : "");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int fiq_claim(fiqhandler_t *handler)
|
||||
*
|
||||
* Claim FIQ's and install a handler for them.
|
||||
*/
|
||||
|
||||
int
|
||||
fiq_claim(handler)
|
||||
fiqhandler_t *handler;
|
||||
{
|
||||
/* Fail if the FIQ's are already claimed */
|
||||
|
||||
if (fiqhandlers)
|
||||
return(-1);
|
||||
|
||||
if (handler->fh_size > 0xc0)
|
||||
return(-1);
|
||||
|
||||
/* Install the handler */
|
||||
|
||||
fiqhandlers = handler;
|
||||
|
||||
/* Now we have to actually install the FIQ handler */
|
||||
|
||||
/* Eventually we will copy this down but for the moment ... */
|
||||
|
||||
zero_page_readwrite();
|
||||
|
||||
WriteWord(0x0000003c, (u_int) handler->fh_func);
|
||||
|
||||
zero_page_readonly();
|
||||
cpu_cache_syncI();
|
||||
|
||||
/* We must now set up the FIQ registers */
|
||||
|
||||
fiq_setregs(handler);
|
||||
|
||||
/* Make sure that the FIQ's are enabled */
|
||||
|
||||
enable_interrupts(F32_bit);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* int fiq_release(fiqhandler_t *handler)
|
||||
*
|
||||
* Release FIQ's and remove a handler for them.
|
||||
*/
|
||||
|
||||
int
|
||||
fiq_release(handler)
|
||||
fiqhandler_t *handler;
|
||||
{
|
||||
/* Fail if the handler is wrong */
|
||||
|
||||
if (fiqhandlers != handler)
|
||||
return(-1);
|
||||
|
||||
/* Disable FIQ interrupts */
|
||||
|
||||
disable_interrupts(F32_bit);
|
||||
|
||||
/* Retrieve the FIQ registers */
|
||||
|
||||
fiq_getregs(handler);
|
||||
|
||||
/* Remove the handler */
|
||||
|
||||
fiqhandlers = NULL;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* End of irqhandler.c */
|
|
@ -0,0 +1,65 @@
|
|||
/* $NetBSD: isa_machdep.h,v 1.1 1998/06/08 17:49:44 tv Exp $ */
|
||||
|
||||
#ifndef _ARM32_ISA_MACHDEP_H_
|
||||
#define _ARM32_ISA_MACHDEP_H_
|
||||
|
||||
/*
|
||||
* Types provided to machine-independent ISA code.
|
||||
*/
|
||||
typedef void *isa_chipset_tag_t;
|
||||
|
||||
struct device; /* XXX */
|
||||
struct isabus_attach_args; /* XXX */
|
||||
|
||||
/*
|
||||
* ISA DMA bounce buffers.
|
||||
* XXX should be made partially machine- and bus-mapping-independent.
|
||||
*
|
||||
* DMA_BOUNCE is the number of pages of low-addressed physical memory
|
||||
* to acquire for ISA bounce buffers.
|
||||
*
|
||||
* isaphysmem is the location of those bounce buffers. (They are currently
|
||||
* assumed to be contiguous.
|
||||
*/
|
||||
|
||||
#ifndef DMA_BOUNCE
|
||||
#define DMA_BOUNCE 8 /* one buffer per channel */
|
||||
#endif
|
||||
|
||||
#define DMA_LARGE_BUFFER_SIZE 65536 /* 64K */
|
||||
|
||||
extern vm_offset_t isaphysmem;
|
||||
|
||||
/*
|
||||
* Functions provided to machine-independent ISA code.
|
||||
*/
|
||||
void isa_attach_hook __P((struct device *, struct device *,
|
||||
struct isabus_attach_args *));
|
||||
void *isa_intr_establish __P((isa_chipset_tag_t ic, int irq, int type,
|
||||
int level, int (*ih_fun)(void *), void *ih_arg));
|
||||
void isa_intr_disestablish __P((isa_chipset_tag_t ic, void *handler));
|
||||
|
||||
/*
|
||||
* ALL OF THE FOLLOWING ARE MACHINE-DEPENDENT, AND SHOULD NOT BE USED
|
||||
* BY PORTABLE CODE.
|
||||
*/
|
||||
|
||||
/* bus space tags */
|
||||
extern struct bus_space isa_io_bs_tag;
|
||||
extern struct bus_space isa_mem_bs_tag;
|
||||
|
||||
/* for pccons.c */
|
||||
#define MONO_BASE 0x3B4
|
||||
#define MONO_BUF 0x000B0000
|
||||
#define CGA_BASE 0x3D4
|
||||
#define CGA_BUF 0x000B8000
|
||||
#define VGA_BUF 0xA0000
|
||||
#define VGA_BUF_LEN (0xBFFFF - 0xA0000)
|
||||
|
||||
|
||||
void isa_init __P((vm_offset_t, vm_offset_t));
|
||||
void isa_io_init __P((vm_offset_t, vm_offset_t));
|
||||
vm_offset_t isa_io_data_vaddr __P((void));
|
||||
vm_offset_t isa_mem_data_vaddr __P((void));
|
||||
|
||||
#endif /* _ARM32_ISA_MACHDEP_H_ XXX */
|
|
@ -0,0 +1,432 @@
|
|||
/* $NetBSD: isadma.c,v 1.1 1998/06/08 17:49:44 tv 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/file.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
|
||||
#include <dev/isa/isareg.h>
|
||||
#include <dev/isa/isadmareg.h>
|
||||
#include <arm32/isa/isadmavar.h>
|
||||
|
||||
/* region of physical memory known to be contiguous */
|
||||
vm_offset_t isaphysmem;
|
||||
static caddr_t dma_bounce[8]; /* XXX */
|
||||
static char bounced[8]; /* XXX */
|
||||
#define MAXDMASZ 512 /* XXX */
|
||||
static u_int8_t dma_finished;
|
||||
static u_int8_t dma_buffer_used=0;
|
||||
|
||||
static unsigned isa_dma_masks = 0xFF;
|
||||
static int isa_dma_frozen = 0;
|
||||
#define ISA_DMA_MASK_SET(CHAN) isa_dma_masks |= (1 << (CHAN))
|
||||
#define ISA_DMA_MASK_CLR(CHAN) isa_dma_masks &= ~(1 << (CHAN))
|
||||
|
||||
/* high byte of address is stored in this port for i-th dma channel */
|
||||
static int dmapageport[2][4] = {
|
||||
{0x87, 0x83, 0x81, 0x82},
|
||||
{0x8f, 0x8b, 0x89, 0x8a}
|
||||
};
|
||||
|
||||
static u_int8_t dmamode[4] = {
|
||||
DMA37MD_READ | DMA37MD_SINGLE,
|
||||
DMA37MD_WRITE | DMA37MD_SINGLE,
|
||||
DMA37MD_READ | DMA37MD_LOOP,
|
||||
DMA37MD_WRITE | DMA37MD_LOOP
|
||||
};
|
||||
|
||||
int isa_dmarangecheck __P((vm_offset_t, u_long, int));
|
||||
caddr_t isa_allocphysmem __P((caddr_t, unsigned, void (*)(void)));
|
||||
void isa_freephysmem __P((caddr_t, unsigned));
|
||||
|
||||
#ifdef SHARK
|
||||
/* returns a pointer to the dma buffer if it is available,
|
||||
* otherwise will return null.
|
||||
*/
|
||||
caddr_t isa_dmabuffer_get()
|
||||
{
|
||||
caddr_t buffer;
|
||||
int x;
|
||||
|
||||
x = splhigh();
|
||||
|
||||
if (dma_buffer_used == 0)
|
||||
{
|
||||
dma_buffer_used = 1;
|
||||
buffer = (caddr_t) isaphysmem;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no-can-do, already in use */
|
||||
buffer = (caddr_t) NULL;
|
||||
}
|
||||
|
||||
splx(x);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* relinquishes the dma buffer, this does no checks
|
||||
*/
|
||||
void isa_dmabuffer_finish()
|
||||
{
|
||||
dma_buffer_used = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* isa_dmacascade(): program 8237 DMA controller channel to accept
|
||||
* external dma control by a board.
|
||||
*/
|
||||
void
|
||||
isa_dmacascade(chan)
|
||||
int chan;
|
||||
{
|
||||
|
||||
#ifdef ISADMA_DEBUG
|
||||
if (chan < 0 || chan > 7)
|
||||
panic("isa_dmacascade: impossible request");
|
||||
#endif
|
||||
|
||||
/* set dma channel mode, and set dma channel mode */
|
||||
if ((chan & 4) == 0) {
|
||||
outb(IO_DMA1 + DMA1_MODE, chan | DMA37MD_CASCADE);
|
||||
ISA_DMA_MASK_CLR(chan);
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA1 + DMA1_SMSK, chan);
|
||||
} else {
|
||||
outb(IO_DMA2 + DMA2_MODE, (chan & 3) | DMA37MD_CASCADE);
|
||||
ISA_DMA_MASK_CLR(chan);
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA2 + DMA2_SMSK, (chan & 3));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
|
||||
* problems by using a bounce buffer.
|
||||
*/
|
||||
void
|
||||
isa_dmastart(flags, addr, nbytes, chan)
|
||||
int flags;
|
||||
caddr_t addr;
|
||||
vm_size_t nbytes;
|
||||
int chan;
|
||||
{
|
||||
vm_offset_t phys;
|
||||
int waport;
|
||||
caddr_t newaddr;
|
||||
|
||||
#ifdef ISADMA_DEBUG
|
||||
if (chan < 0 || chan > 7 ||
|
||||
((chan & 4) ? (nbytes >= (1<<17) || nbytes & 1 || (u_int)addr & 1) :
|
||||
(nbytes >= (1<<16))))
|
||||
panic("isa_dmastart: impossible request");
|
||||
#endif
|
||||
|
||||
if (isa_dmarangecheck((vm_offset_t) addr, nbytes, chan)) {
|
||||
if (dma_bounce[chan] == 0)
|
||||
dma_bounce[chan] =
|
||||
/*(caddr_t)malloc(MAXDMASZ, M_TEMP, M_WAITOK);*/
|
||||
(caddr_t) isaphysmem + NBPG*chan;
|
||||
bounced[chan] = 1;
|
||||
newaddr = dma_bounce[chan];
|
||||
*(int *) newaddr = 0; /* XXX */
|
||||
/* copy bounce buffer on write */
|
||||
if ((flags & DMAMODE_READ) == 0)
|
||||
bcopy(addr, newaddr, nbytes);
|
||||
addr = newaddr;
|
||||
}
|
||||
|
||||
/* translate to physical */
|
||||
phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
|
||||
|
||||
dma_finished &= ~(1 << chan);
|
||||
|
||||
if ((chan & 4) == 0) {
|
||||
/*
|
||||
* Program one of DMA channels 0..3. These are
|
||||
* byte mode channels.
|
||||
*/
|
||||
/* set dma channel mode, and reset address ff */
|
||||
outb(IO_DMA1 + DMA1_MODE, chan | dmamode[flags]);
|
||||
outb(IO_DMA1 + DMA1_FFC, 0);
|
||||
|
||||
/* send start address */
|
||||
waport = IO_DMA1 + DMA1_CHN(chan);
|
||||
outb(dmapageport[0][chan], phys>>16);
|
||||
outb(waport, phys);
|
||||
outb(waport, phys>>8);
|
||||
|
||||
/* send count */
|
||||
outb(waport + 1, --nbytes);
|
||||
outb(waport + 1, nbytes>>8);
|
||||
|
||||
/* unmask channel */
|
||||
ISA_DMA_MASK_CLR(chan);
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA1 + DMA1_SMSK, chan | DMA37SM_CLEAR);
|
||||
} else {
|
||||
/*
|
||||
* Program one of DMA channels 4..7. These are
|
||||
* word mode channels.
|
||||
*/
|
||||
/* set dma channel mode, and reset address ff */
|
||||
outb(IO_DMA2 + DMA2_MODE, (chan & 3) | dmamode[flags]);
|
||||
outb(IO_DMA2 + DMA2_FFC, 0);
|
||||
|
||||
/* send start address */
|
||||
waport = IO_DMA2 + DMA2_CHN(chan & 3);
|
||||
outb(dmapageport[1][chan & 3], phys>>16);
|
||||
phys >>= 1;
|
||||
outb(waport, phys);
|
||||
outb(waport, phys>>8);
|
||||
|
||||
/* send count */
|
||||
nbytes >>= 1;
|
||||
outb(waport + 2, --nbytes);
|
||||
outb(waport + 2, nbytes>>8);
|
||||
|
||||
/* unmask channel */
|
||||
ISA_DMA_MASK_CLR(chan);
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA2 + DMA2_SMSK, (chan & 3) | DMA37SM_CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isa_dmaabort(chan)
|
||||
int chan;
|
||||
{
|
||||
|
||||
#ifdef ISADMA_DEBUG
|
||||
if (chan < 0 || chan > 7)
|
||||
panic("isa_dmaabort: impossible request");
|
||||
#endif
|
||||
|
||||
bounced[chan] = 0;
|
||||
|
||||
/* mask channel */
|
||||
ISA_DMA_MASK_SET(chan);
|
||||
if ((chan & 4) == 0)
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA1 + DMA1_SMSK, DMA37SM_SET | chan);
|
||||
else
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA2 + DMA2_SMSK, DMA37SM_SET | (chan & 3));
|
||||
}
|
||||
|
||||
int
|
||||
isa_dmafinished(chan)
|
||||
int chan;
|
||||
{
|
||||
|
||||
#ifdef ISADMA_DEBUG
|
||||
if (chan < 0 || chan > 7)
|
||||
panic("isa_dmafinished: impossible request");
|
||||
#endif
|
||||
|
||||
/* check that the terminal count was reached */
|
||||
if ((chan & 4) == 0)
|
||||
dma_finished |= inb(IO_DMA1 + DMA1_SR) & 0x0f;
|
||||
else
|
||||
dma_finished |= (inb(IO_DMA2 + DMA2_SR) & 0x0f) << 4;
|
||||
|
||||
return ((dma_finished & (1 << chan)) != 0);
|
||||
}
|
||||
|
||||
void
|
||||
isa_dmadone(flags, addr, nbytes, chan)
|
||||
int flags;
|
||||
caddr_t addr;
|
||||
vm_size_t nbytes;
|
||||
int chan;
|
||||
{
|
||||
|
||||
|
||||
#ifdef ISADMA_DEBUG
|
||||
if (chan < 0 || chan > 7)
|
||||
panic("isa_dmadone: impossible request");
|
||||
#endif
|
||||
|
||||
if (!isa_dmafinished(chan))
|
||||
printf("isa_dmadone: channel %d not finished\n", chan);
|
||||
|
||||
/* mask channel */
|
||||
ISA_DMA_MASK_SET(chan);
|
||||
if ((chan & 4) == 0)
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA1 + DMA1_SMSK, DMA37SM_SET | chan);
|
||||
else
|
||||
if (!isa_dma_frozen)
|
||||
outb(IO_DMA2 + DMA2_SMSK, DMA37SM_SET | (chan & 3));
|
||||
|
||||
/* copy bounce buffer on read */
|
||||
if (bounced[chan]) {
|
||||
bcopy(dma_bounce[chan], addr, nbytes);
|
||||
bounced[chan] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for problems with the address range of a DMA transfer
|
||||
* (non-contiguous physical pages, outside of bus address space,
|
||||
* crossing DMA page boundaries).
|
||||
* Return true if special handling needed.
|
||||
*/
|
||||
int
|
||||
isa_dmarangecheck(va, length, chan)
|
||||
vm_offset_t va;
|
||||
u_long length;
|
||||
int chan;
|
||||
{
|
||||
vm_offset_t phys, priorpage = 0, endva;
|
||||
u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1);
|
||||
|
||||
endva = round_page(va + length);
|
||||
for (; va < endva ; va += NBPG) {
|
||||
phys = trunc_page(pmap_extract(pmap_kernel(), va));
|
||||
if (phys == 0)
|
||||
panic("isa_dmacheck: no physical page present");
|
||||
#ifdef ISA_MACHDEP_DMARANGECHECK
|
||||
if (isa_machdep_dmarangecheck(phys, NBPG))
|
||||
#else
|
||||
if (phys >= (1<<24))
|
||||
#endif
|
||||
return 1;
|
||||
if (priorpage) {
|
||||
if (priorpage + NBPG != phys)
|
||||
return 1;
|
||||
/* check if crossing a DMA page boundary */
|
||||
if ((priorpage ^ phys) & dma_pgmsk)
|
||||
return 1;
|
||||
}
|
||||
priorpage = phys;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* head of queue waiting for physmem to become available */
|
||||
struct buf isa_physmemq;
|
||||
|
||||
/* blocked waiting for resource to become free for exclusive use */
|
||||
static int isaphysmemflag;
|
||||
/* if waited for and call requested when free (B_CALL) */
|
||||
static void (*isaphysmemunblock) __P((void)); /* needs to be a list */
|
||||
|
||||
/*
|
||||
* Allocate contiguous physical memory for transfer, returning
|
||||
* a *virtual* address to region. May block waiting for resource.
|
||||
* (assumed to be called at splbio())
|
||||
*/
|
||||
caddr_t
|
||||
isa_allocphysmem(ca, length, func)
|
||||
caddr_t ca;
|
||||
unsigned length;
|
||||
void (*func) __P((void));
|
||||
{
|
||||
|
||||
isaphysmemunblock = func;
|
||||
while (isaphysmemflag & B_BUSY) {
|
||||
isaphysmemflag |= B_WANTED;
|
||||
sleep((caddr_t)&isaphysmemflag, PRIBIO);
|
||||
}
|
||||
isaphysmemflag |= B_BUSY;
|
||||
|
||||
return((caddr_t)isaphysmem);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free contiguous physical memory used for transfer.
|
||||
* (assumed to be called at splbio())
|
||||
*/
|
||||
void
|
||||
isa_freephysmem(va, length)
|
||||
caddr_t va;
|
||||
unsigned length;
|
||||
{
|
||||
|
||||
isaphysmemflag &= ~B_BUSY;
|
||||
if (isaphysmemflag & B_WANTED) {
|
||||
isaphysmemflag &= B_WANTED;
|
||||
wakeup((caddr_t)&isaphysmemflag);
|
||||
if (isaphysmemunblock)
|
||||
(*isaphysmemunblock)();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isa_dmafreeze()
|
||||
{
|
||||
int x;
|
||||
|
||||
x = splhigh();
|
||||
|
||||
if (!isa_dma_frozen) {
|
||||
outb(IO_DMA1 + DMA1_MASK, 0xF);
|
||||
outb(IO_DMA2 + DMA2_MASK, 0xF);
|
||||
/* blam! */
|
||||
}
|
||||
isa_dma_frozen++;
|
||||
|
||||
splx(x);
|
||||
}
|
||||
|
||||
void
|
||||
isa_dmathaw()
|
||||
{
|
||||
int x;
|
||||
|
||||
x = splhigh();
|
||||
|
||||
isa_dma_frozen--;
|
||||
|
||||
if (isa_dma_frozen == 0) {
|
||||
outb(IO_DMA1 + DMA1_MASK, isa_dma_masks & 0xF);
|
||||
outb(IO_DMA2 + DMA2_MASK, (isa_dma_masks >> 4) & 0xF);
|
||||
} else if (isa_dma_frozen < 0) {
|
||||
isa_dma_frozen = 0;
|
||||
}
|
||||
|
||||
splx(x);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* $NetBSD: isadmavar.h,v 1.1 1998/06/08 17:49:44 tv Exp $ */
|
||||
|
||||
#define DMAMODE_WRITE 0
|
||||
#define DMAMODE_READ 1
|
||||
#define DMAMODE_LOOP 2
|
||||
|
||||
void isa_dmacascade __P((int));
|
||||
void isa_dmastart __P((int, caddr_t, vm_size_t, int));
|
||||
void isa_dmaabort __P((int));
|
||||
int isa_dmafinished __P((int));
|
||||
void isa_dmadone __P((int, caddr_t, vm_size_t, int));
|
||||
|
||||
#ifdef SHARK
|
||||
caddr_t isa_dmabuffer_get __P(());
|
||||
void isa_dmabuffer_finish __P(());
|
||||
void isa_dmafreeze __P((void));
|
||||
void isa_dmathaw __P((void));
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/* $NetBSD: nvram.h,v 1.1 1998/06/08 17:49:44 tv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)rtc.h 8.1 (Berkeley) 6/11/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following information is found in the non-volatile RAM in the
|
||||
* MC146818A (or DS1287A or other compatible) RTC on AT-compatible PCs.
|
||||
*/
|
||||
|
||||
/* NVRAM byte 0: bios diagnostic */
|
||||
#define NVRAM_DIAG (MC_NVRAM_START + 0) /* RTC offset 0xe */
|
||||
|
||||
#define NVRAM_DIAG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time"
|
||||
|
||||
/* NVRAM byte 1: reset code */
|
||||
#define NVRAM_RESET (MC_NVRAM_START + 1) /* RTC offset 0xf */
|
||||
|
||||
#define NVRAM_RESET_RST 0x00 /* normal reset */
|
||||
#define NVRAM_RESET_LOAD 0x04 /* load system */
|
||||
|
||||
/* NVRAM byte 2: diskette drive type in upper/lower nibble */
|
||||
#define NVRAM_DISKETTE (MC_NVRAM_START + 2) /* RTC offset 0x10 */
|
||||
|
||||
#define NVRAM_DISKETTE_NONE 0 /* none present */
|
||||
#define NVRAM_DISKETTE_360K 0x10 /* 360K */
|
||||
#define NVRAM_DISKETTE_12M 0x20 /* 1.2M */
|
||||
#define NVRAM_DISKETTE_720K 0x30 /* 720K */
|
||||
#define NVRAM_DISKETTE_144M 0x40 /* 1.44M */
|
||||
#define NVRAM_DISKETTE_TYPE5 0x50 /* 2.88M, presumably */
|
||||
#define NVRAM_DISKETTE_TYPE6 0x60 /* 2.88M */
|
||||
|
||||
/* NVRAM byte 6: equipment type */
|
||||
#define NVRAM_EQUIPMENT (MC_NVRAM_START + 6)
|
||||
|
||||
#define NVRAM_EQUIPMENT_EGAVGA 0x00 /* EGA or VGA */
|
||||
#define NVRAM_EQUIPMENT_COLOR40 0x10 /* 40 column color */
|
||||
#define NVRAM_EQUIPMENT_COLOR80 0x20 /* 80 column color */
|
||||
#define NVRAM_EQUIPMENT_MONO80 0x30 /* 80 column mono */
|
||||
#define NVRAM_EQUIPMENT_MONITOR 0x30 /* mask for monitor type */
|
||||
|
||||
/* NVRAM bytes 7 & 8: base memory size */
|
||||
#define NVRAM_BASELO (MC_NVRAM_START + 7) /* low byte; RTC off. 0x15 */
|
||||
#define NVRAM_BASEHI (MC_NVRAM_START + 8) /* high byte; RTC off. 0x16 */
|
||||
|
||||
/* NVRAM bytes 9 & 10: extended memory size */
|
||||
#define NVRAM_EXTLO (MC_NVRAM_START + 9) /* low byte; RTC off. 0x17 */
|
||||
#define NVRAM_EXTHI (MC_NVRAM_START + 10) /* high byte; RTC off. 0x18 */
|
||||
|
||||
/* NVRAM byte 36: current century. (please increment in Dec99!) */
|
||||
#define NVRAM_CENTURY (MC_NVRAM_START + 36) /* RTC offset 0x32 */
|
|
@ -0,0 +1,11 @@
|
|||
/* $NetBSD: spkrreg.h,v 1.1 1998/06/08 17:49:44 tv Exp $ */
|
||||
|
||||
/*
|
||||
* PIT port addresses and speaker control values
|
||||
*/
|
||||
|
||||
#define PITAUX_PORT 0x61 /* port of Programmable Peripheral Interface */
|
||||
#define PIT_ENABLETMR2 0x01 /* Enable timer/counter 2 */
|
||||
#define PIT_SPKRDATA 0x02 /* Direct to speaker */
|
||||
|
||||
#define PIT_SPKR (PIT_ENABLETMR2|PIT_SPKRDATA)
|
|
@ -0,0 +1,100 @@
|
|||
/* $NetBSD: timerreg.h,v 1.1 1998/06/08 17:49:45 tv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993 The Regents of the University of California.
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register definitions for the Intel 8253 Programmable Interval Timer.
|
||||
*
|
||||
* This chip has three independent 16-bit down counters that can be
|
||||
* read on the fly. There are three mode registers and three countdown
|
||||
* registers. The countdown registers are addressed directly, via the
|
||||
* first three I/O ports. The three mode registers are accessed via
|
||||
* the fourth I/O port, with two bits in the mode byte indicating the
|
||||
* register. (Why are hardware interfaces always so braindead?).
|
||||
*
|
||||
* To write a value into the countdown register, the mode register
|
||||
* is first programmed with a command indicating the which byte of
|
||||
* the two byte register is to be modified. The three possibilities
|
||||
* are load msb (TMR_MR_MSB), load lsb (TMR_MR_LSB), or load lsb then
|
||||
* msb (TMR_MR_BOTH).
|
||||
*
|
||||
* To read the current value ("on the fly") from the countdown register,
|
||||
* you write a "latch" command into the mode register, then read the stable
|
||||
* value from the corresponding I/O port. For example, you write
|
||||
* TMR_MR_LATCH into the corresponding mode register. Presumably,
|
||||
* after doing this, a write operation to the I/O port would result
|
||||
* in undefined behavior (but hopefully not fry the chip).
|
||||
* Reading in this manner has no side effects.
|
||||
*
|
||||
* The outputs of the three timers are connected as follows:
|
||||
*
|
||||
* timer 0 -> irq 0
|
||||
* timer 1 -> dma chan 0 (for dram refresh)
|
||||
* timer 2 -> speaker (via keyboard controller)
|
||||
*
|
||||
* Timer 0 is used to call hardclock.
|
||||
* Timer 2 is used to generate console beeps.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Frequency of all three count-down timers; (TIMER_FREQ/freq) is the
|
||||
* appropriate count to generate a frequency of freq hz.
|
||||
*/
|
||||
#ifndef TIMER_FREQ
|
||||
#define TIMER_FREQ 1193182
|
||||
#endif
|
||||
#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
|
||||
|
||||
/*
|
||||
* Macros for specifying values to be written into a mode register.
|
||||
*/
|
||||
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
|
||||
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
|
||||
#define TIMER_SEL0 0x00 /* select counter 0 */
|
||||
#define TIMER_SEL1 0x40 /* select counter 1 */
|
||||
#define TIMER_SEL2 0x80 /* select counter 2 */
|
||||
#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
|
||||
#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
|
||||
#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
|
||||
#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
|
||||
#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
|
||||
#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
|
||||
#define TIMER_LATCH 0x00 /* latch counter for reading */
|
||||
#define TIMER_LSB 0x10 /* r/w counter LSB */
|
||||
#define TIMER_MSB 0x20 /* r/w counter MSB */
|
||||
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
|
||||
#define TIMER_BCD 0x01 /* count in BCD */
|
||||
|
Loading…
Reference in New Issue