Remove Avalon A12 support.
ok ross@
This commit is contained in:
parent
23bea5092d
commit
6cee2f02e2
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.14 2011/04/03 23:07:19 dyoung Exp $
|
||||
# $NetBSD: Makefile,v 1.15 2011/06/17 03:55:56 matt Exp $
|
||||
|
||||
# Makefile for alpha tags file and boot blocks
|
||||
|
||||
@ -13,7 +13,7 @@ SALPHA= ${SYSDIR}/arch/alpha/alpha/*.[ch] ${SYSDIR}/arch/alpha/common/*.[ch] \
|
||||
AALPHA= ${SYSDIR}/arch/alpha/alpha/*.s ${SYSDIR}/arch/alpha/pci/*.s
|
||||
|
||||
# Directories in which to place tags links
|
||||
DALPHA= a12 common eisa include isa jensenio mcbus pci sableio tc tlsb
|
||||
DALPHA= common eisa include isa jensenio mcbus pci sableio tc tlsb
|
||||
|
||||
.include "../../kern/Make.tags.inc"
|
||||
|
||||
|
@ -1,638 +0,0 @@
|
||||
/* $NetBSD: a12dc.c,v 1.26 2011/06/14 15:34:21 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.2]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 AVALON OR THE 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The A12 uses what DEC calls a "detached console", i.e., some of the console
|
||||
* implementation is on a dedicated processor with its own RAM.
|
||||
*
|
||||
* The A12 Detached Console interface uses two 16 bit registers (per CPU), one
|
||||
* going from the CPU to the a12ctrl processor and one going back the other
|
||||
* way. The first is polled, the second produces a GInt.
|
||||
*
|
||||
* In the very early days we loaded program images through this interface.
|
||||
*
|
||||
* Consequently, it developed an overly complicated (but sort of fast)
|
||||
* inverting sync/ack that isn't needed at all for its present application as
|
||||
* a text console device.
|
||||
*
|
||||
* One possible solution: most of the channels are undefined, so a console
|
||||
* channel using a stateless ack could be defined, with corresponding changes
|
||||
* to the backplane 68360 code.
|
||||
*
|
||||
* This file is complicated somewhat by its use in three different kernels:
|
||||
* NetBSD, the A12 CPU-resident console, and the a12ctrl backplane processor.
|
||||
* (The protocol is symmetrical.)
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include "opt_kgdb.h"
|
||||
|
||||
#ifndef BSIDE
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: a12dc.c,v 1.26 2011/06/14 15:34:21 matt Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <sys/tty.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kauth.h>
|
||||
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/cpuconf.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/rpb.h>
|
||||
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
#include <alpha/pci/pci_a12.h>
|
||||
|
||||
#include "a12dcreg.h"
|
||||
|
||||
#define A12DC() /* Generate ctags(1) key */
|
||||
|
||||
#define MAX_MODULES 1
|
||||
|
||||
int a12dcmatch(device_t, cfdata_t, void *);
|
||||
void a12dcattach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(a12dc, 0,
|
||||
a12dcmatch, a12dcattach, NULL, NULL);
|
||||
|
||||
extern struct cfdriver a12dc_cd;
|
||||
|
||||
dev_type_open(a12dcopen);
|
||||
dev_type_close(a12dcclose);
|
||||
dev_type_read(a12dcread);
|
||||
dev_type_write(a12dcwrite);
|
||||
dev_type_ioctl(a12dcioctl);
|
||||
dev_type_stop(a12dcstop);
|
||||
dev_type_tty(a12dctty);
|
||||
dev_type_poll(a12dcpoll);
|
||||
|
||||
const struct cdevsw a12dc_cdevsw = {
|
||||
a12dcopen, a12dcclose, a12dcread, a12dcwrite, a12dcioctl,
|
||||
a12dcstop, a12dctty, a12dcpoll, nommap, ttykqfilter, D_TTY
|
||||
};
|
||||
|
||||
int a12dcfound; /* There Can Be Only One. */
|
||||
|
||||
struct a12dc_config { int im_not_used; } a12dc_configuration;
|
||||
|
||||
static struct tty *a12dc_tty[1];
|
||||
|
||||
void a12dcstart(struct tty *);
|
||||
void a12dctimeout(void *);
|
||||
int a12dcparam(struct tty *, struct termios *);
|
||||
void a12dc_init(struct a12dc_config *, int);
|
||||
static void a12cdrputc(int);
|
||||
int a12dccngetc(dev_t);
|
||||
void a12dccnputc(dev_t, int);
|
||||
void a12dccnpollc(dev_t, int);
|
||||
/* static int get_bc_char(int mn, int chan); */
|
||||
/* static int get_bc_any(int,int *,int *); */
|
||||
int a12dcintr(void *);
|
||||
static void a12_worry(int worry_number);
|
||||
static void A12InitBackDriver(int);
|
||||
|
||||
int
|
||||
a12dcmatch(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct pcibus_attach_args *pba = aux;
|
||||
|
||||
return cputype == ST_AVALON_A12
|
||||
&& !a12dcfound;
|
||||
}
|
||||
|
||||
void
|
||||
a12dcattach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct tty *tp;
|
||||
struct a12dc_config *ccp;
|
||||
|
||||
/* note that we've attached the chipset; can't have 2 A12Cs. */
|
||||
a12dcfound = 1;
|
||||
|
||||
aprintf_normal(": driver %s\n", "$Revision: 1.26 $");
|
||||
|
||||
tp = a12dc_tty[0] = tty_alloc();
|
||||
tp->t_oproc = a12dcstart;
|
||||
tp->t_param = a12dcparam;
|
||||
tty_attach(tp);
|
||||
|
||||
ccp = &a12dc_configuration;
|
||||
a12dc_init(ccp, 1);
|
||||
}
|
||||
|
||||
void
|
||||
a12dc_init(struct a12dc_config *ccp, int sleepsafe)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX definitions specific to only one of the kernels will be moved into
|
||||
* kernel-local include files. (One of these days.)
|
||||
*/
|
||||
#define spla12dc() spltty()
|
||||
#define a12yield()
|
||||
#define CDRADDR(m) ((mmreg_t *)(REGADDR(A12_CDR))) /* ignore m */
|
||||
#define modenormal()
|
||||
#define mb() alpha_mb()
|
||||
#define wmb() alpha_wmb()
|
||||
|
||||
#else
|
||||
|
||||
#include "product.def"
|
||||
#include "ghs.h"
|
||||
#include "a12ctrl.h"
|
||||
|
||||
#define wmb()
|
||||
#define mb()
|
||||
#define swpipl(a) (a)
|
||||
#define splx(a) (a)
|
||||
#define spla12dc()
|
||||
#define hrhpanic(s,v) panic((s))
|
||||
#define CDRADDR(m) ((mmreg_t *)(A12_BACKPLANE+(m)))
|
||||
|
||||
#endif
|
||||
|
||||
static int msgetput(register mstate_type *, int, int);
|
||||
static void checkinit(void);
|
||||
|
||||
static void
|
||||
A12InitBackDriver(int m)
|
||||
{
|
||||
/*
|
||||
* XXX memset() would be good here, but there is a (temporary) reason
|
||||
* for all this right now
|
||||
*/
|
||||
a12_mstate[m].xcdr = CDRADDR(m);
|
||||
a12_mstate[m].txrdy_out = A12C_TXRDY;
|
||||
a12_mstate[m].txrdy_in = A12C_TXRDY;
|
||||
a12_mstate[m].txack_out = A12C_TXACK;
|
||||
a12_mstate[m].txack_in = A12C_TXACK;
|
||||
a12_mstate[m].txsv = tx_idle;
|
||||
a12_mstate[m].rxsv = rx_idle;
|
||||
a12_mstate[m].reset_scanner= 1;
|
||||
a12_mstate[m].reset_loader = 1;
|
||||
a12_mstate[m].up = 1;
|
||||
a12_mstate[m].lastr = 0; /* last char. received */
|
||||
a12_mstate[m].lastrc = 0; /* last received channel */
|
||||
a12_mstate[m].rx_busy_wait = 0; /* last received busy ticks */
|
||||
a12_mstate[m].rx_busy_cnt = 0; /* last received start clock */
|
||||
a12_mstate[m].lastt = 0; /* last char. trasmitted */
|
||||
a12_mstate[m].lasttc = 0; /* last transmit channel */
|
||||
a12_mstate[m].tx_busy_wait = 0; /* last transmitted busy ticks */
|
||||
a12_mstate[m].tx_busy_cnt = 0; /* last transmitted start clock */
|
||||
a12_mstate[m].tbytes = 0;
|
||||
a12_mstate[m].tblkbytes = 0;
|
||||
a12_mstate[m].tblks = 0;
|
||||
a12_mstate[m].blwobe = 0;
|
||||
a12_mstate[m].blwbe = 0;
|
||||
a12_mstate[m].max_blkretry = 0;
|
||||
a12_mstate[m].max_blktime = 0;
|
||||
a12_mstate[m].max_blktimesz = 0;
|
||||
a12_mstate[m].avg_blksz = 0;
|
||||
a12_mstate[m].avg_blktime = 0;
|
||||
a12_mstate[m].retry_time = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
checkinit(void)
|
||||
{
|
||||
static int did_init;
|
||||
|
||||
if (!did_init) {
|
||||
A12InitBackDriver(0);
|
||||
did_init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
a12dcopen(dev_t dev, int flag, int mode, struct lwp *l)
|
||||
{
|
||||
int unit = minor(dev);
|
||||
struct tty *tp;
|
||||
int s;
|
||||
|
||||
if (unit >= 1)
|
||||
return ENXIO;
|
||||
|
||||
#ifdef KGDB
|
||||
if (flags & COM_HW_KGDB)
|
||||
return EBUSY;
|
||||
#endif
|
||||
|
||||
if (!a12dc_tty[unit]) {
|
||||
tp = a12dc_tty[unit] = tty_alloc();
|
||||
tty_attach(tp);
|
||||
} else
|
||||
tp = a12dc_tty[unit];
|
||||
|
||||
if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
|
||||
return (EBUSY);
|
||||
|
||||
s = spltty();
|
||||
|
||||
tp->t_oproc = a12dcstart;
|
||||
tp->t_param = a12dcparam;
|
||||
tp->t_dev = dev;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
ttychars(tp);
|
||||
tp->t_iflag = TTYDEF_IFLAG;
|
||||
tp->t_oflag = TTYDEF_OFLAG;
|
||||
tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
|
||||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
tp->t_ispeed = tp->t_ospeed = 9600;
|
||||
ttsetwater(tp);
|
||||
/* XXX XXX XXX
|
||||
a12_intr_register_icw(a12dcintr);
|
||||
*/
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
||||
return (*tp->t_linesw->l_open)(dev, tp);
|
||||
}
|
||||
|
||||
int
|
||||
a12dcclose(dev_t dev, int flag, int mode, struct proc *p)
|
||||
{
|
||||
int unit = minor(dev);
|
||||
struct tty *tp = a12dc_tty[unit];
|
||||
|
||||
(*tp->t_linesw->l_close)(tp, flag);
|
||||
ttyclose(tp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
a12dcread(dev_t dev, struct uio *uio, int flag)
|
||||
{
|
||||
struct tty *tp = a12dc_tty[minor(dev)];
|
||||
|
||||
return ((*tp->t_linesw->l_read)(tp, uio, flag));
|
||||
}
|
||||
|
||||
int
|
||||
a12dcwrite(dev_t dev, struct uio *uio, int flag)
|
||||
{
|
||||
struct tty *tp = a12dc_tty[minor(dev)];
|
||||
|
||||
return ((*tp->t_linesw->l_write)(tp, uio, flag));
|
||||
}
|
||||
|
||||
int
|
||||
a12dcpoll(dev_t dev, int events, struct proc *p)
|
||||
{
|
||||
struct tty *tp = a12dc_tty[minor(dev)];
|
||||
|
||||
return ((*tp->t_linesw->l_poll)(tp, events, p));
|
||||
}
|
||||
|
||||
int
|
||||
a12dcioctl(dev_t dev, u_long cmd, void *data, int flag, struct proc *p)
|
||||
{
|
||||
int unit = minor(dev);
|
||||
struct tty *tp = a12dc_tty[unit];
|
||||
int error;
|
||||
|
||||
error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
|
||||
if (error != EPASSTHROUGH)
|
||||
return error;
|
||||
return ttioctl(tp, cmd, data, flag, p);
|
||||
}
|
||||
|
||||
int
|
||||
a12dcparam(struct tty *tp, struct termios *t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
a12dcstart(struct tty *tp)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_TTSTOP | TS_BUSY))
|
||||
goto out;
|
||||
ttypull(tp);
|
||||
tp->t_state |= TS_BUSY;
|
||||
while (tp->t_outq.c_cc != 0)
|
||||
a12dccnputc(tp->t_dev, getc(&tp->t_outq));
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
out:
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop output on a line.
|
||||
*/
|
||||
void
|
||||
a12dcstop(struct tty *tp, flag)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & TS_BUSY)
|
||||
if ((tp->t_state & TS_TTSTOP) == 0)
|
||||
tp->t_state |= TS_FLUSH;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
int
|
||||
a12dcintr(void *v)
|
||||
{
|
||||
#if 1
|
||||
DIE();
|
||||
#else
|
||||
struct tty *tp = v;
|
||||
u_char c;
|
||||
|
||||
while (a12dccnlookc(tp->t_dev, &c)) {
|
||||
if (tp->t_state & TS_ISOPEN)
|
||||
(*tp->t_linesw->l_rint)(c, tp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct tty *
|
||||
a12dctty(dev_t dev)
|
||||
{
|
||||
|
||||
if (minor(dev) != 0)
|
||||
panic("a12dctty: bogus");
|
||||
|
||||
return a12dc_tty[0];
|
||||
}
|
||||
|
||||
int
|
||||
a12dccnattach()
|
||||
{
|
||||
static struct consdev a12dccons = {
|
||||
NULL, NULL, a12dccngetc, a12dccnputc, a12dccnpollc, NULL,
|
||||
NODEV, CN_NORMAL
|
||||
};
|
||||
|
||||
a12dccons.cn_dev = makedev(cdevsw_lookup_major(&a12dc_cdevsw), 0);
|
||||
|
||||
cn_tab = &a12dccons;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
a12dccngetc(dev_t dev)
|
||||
{
|
||||
for(;;)
|
||||
continue;
|
||||
}
|
||||
|
||||
void
|
||||
a12dccnputc(dev_t dev, int c)
|
||||
{
|
||||
a12cdrputc(c);
|
||||
}
|
||||
|
||||
void
|
||||
a12dccnpollc(dev_t dev, int on)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
a12cdrputc(int c)
|
||||
{
|
||||
int s = spla12dc();
|
||||
|
||||
checkinit();
|
||||
while(msgetput(MSP(0),CHANNEL_MONITOR,c)) {
|
||||
/*if(check_cdr_ok)
|
||||
check_cdr();*/
|
||||
DELAY(100);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
check_cdr(void)
|
||||
{
|
||||
int bpchar,cnumber;
|
||||
static int srom_word_address,
|
||||
kmsg;
|
||||
int push_check_ok;
|
||||
int ipl;
|
||||
|
||||
if(!get_bc_any(0,&bpchar,&cnumber))
|
||||
return;
|
||||
switch(cnumber) {
|
||||
default:
|
||||
printf("Unknown cdr channel %d",cnumber);
|
||||
break;
|
||||
case CHANNEL_KDATA:
|
||||
if(!kmsg)
|
||||
printf("Ignoring new kernel\n");
|
||||
kmsg = 1;
|
||||
break;
|
||||
case CHANNEL_KMARK:
|
||||
kmsg = 0;
|
||||
break;
|
||||
#ifndef _KERNEL /* NetBSD kernel, that is. "if defined: rtmon kernel" */
|
||||
case CHANNEL_SROM_A:
|
||||
srom_word_address = bpchar;
|
||||
break;
|
||||
case CHANNEL_SROM_D:
|
||||
push_check_ok = check_cdr_ok;
|
||||
check_cdr_ok = 0;
|
||||
ipl = swpipl(7);
|
||||
write_ethernet_srom(srom_word_address,bpchar);
|
||||
++srom_word_address;
|
||||
(void)swpipl(ipl);
|
||||
check_cdr_ok = push_check_ok;
|
||||
break;
|
||||
|
||||
case CHANNEL_MULTI:
|
||||
logmchar(bpchar,"<");
|
||||
SerialByteReceived(bpchar);
|
||||
break;
|
||||
case CHANNEL_MONITOR:
|
||||
if (bpchar == CPX_PANIC)
|
||||
/* TJF - Could kill all processes and then panic? */
|
||||
hrhpanic("Panic in cooperating CPU.",0);
|
||||
else cpxchar(bpchar);
|
||||
break;
|
||||
#endif
|
||||
case CHANNEL_CONSOLE:
|
||||
#ifdef A12CON /* XXX this can be done much better */
|
||||
virtual_keyboard_byte(bpchar);
|
||||
#else
|
||||
ipl7putc(bpchar);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static int
|
||||
get_bc_any(int mn, int *c, int *chan) {
|
||||
mstate_type *ms = &a12_mstate[mn];
|
||||
|
||||
(void)mcgetput(mn, 0, -1);
|
||||
if(ms->rxsv==rx_busy) {
|
||||
*c = ms->c2b_char & 0xff;
|
||||
*chan = ms->c2b_channel;
|
||||
ms->rxsv = rx_idle;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_bc_char(int mn, int chan) {
|
||||
int newc,newchan;
|
||||
|
||||
if(get_bc_any(mn,&newc,&newchan)) {
|
||||
if(newchan!=chan)
|
||||
printf("receiver busy on dumb channel %d", newchan);
|
||||
return newc;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
msgetput(register mstate_type *ms, int channel, int c)
|
||||
{
|
||||
int i,t;
|
||||
int ipl;
|
||||
|
||||
if(c==-2 || ms->up==0) {
|
||||
if(c!=-2)
|
||||
a12_worry(10);
|
||||
ms->txsv = tx_idle;
|
||||
ms->rxsv = rx_idle;
|
||||
ms->cdr = 0;
|
||||
return 0;
|
||||
}
|
||||
if(!(0<=channel && channel<64)) {
|
||||
a12_worry(7);
|
||||
return 0;
|
||||
}
|
||||
ipl = spla12dc();
|
||||
for(i=0; i<20; ++i) {
|
||||
switch(ms->txsv) {
|
||||
case tx_idle:
|
||||
if(c!=-1) {
|
||||
ms->lastt = c;
|
||||
ms->lasttc = channel;
|
||||
ms->cdr = (ms->cdr & (A12C_TXACK | A12C_TXRDY))
|
||||
| channel<<8
|
||||
| c;
|
||||
*ms->xcdr = ms->cdr;
|
||||
wmb();
|
||||
ms->cdr = ((ms->cdr & A12C_TXACK) &~ A12C_TXRDY)
|
||||
| ms->txrdy_out
|
||||
| channel<<8
|
||||
| c;
|
||||
*ms->xcdr = ms->cdr;
|
||||
wmb();
|
||||
ms->txsv = tx_braaw;
|
||||
c = -1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case tx_braaw:
|
||||
mb();
|
||||
if((*ms->xcdr & A12C_TXACK)==ms->txack_in) {
|
||||
ms->txrdy_out ^= A12C_TXRDY;
|
||||
ms->txack_in ^= A12C_TXACK;
|
||||
ms->txsv = tx_idle;
|
||||
ms->tbytes++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(void)splx(ipl);
|
||||
a12_worry(5);
|
||||
return 0;
|
||||
}
|
||||
switch(ms->rxsv) {
|
||||
case rx_idle:
|
||||
mb();
|
||||
t = *ms->xcdr;
|
||||
if((t & A12C_TXRDY)==ms->txrdy_in) {
|
||||
ms->cdr = (ms->cdr & ~A12C_TXACK)
|
||||
| ms->txack_out;
|
||||
*ms->xcdr = ms->cdr;
|
||||
wmb();
|
||||
ms->c2b_char = t & 0xff;
|
||||
ms->lastr = ms->c2b_char;
|
||||
ms->c2b_channel = (t & CHMASK) >> 8;
|
||||
ms->lastrc = ms->c2b_channel;
|
||||
ms->txrdy_in ^= A12C_TXRDY;
|
||||
ms->txack_out^= A12C_TXACK;
|
||||
ms->rxsv = rx_busy;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case rx_busy:
|
||||
break;
|
||||
default:
|
||||
(void)splx(ipl);
|
||||
a12_worry(6);
|
||||
return 0;
|
||||
}
|
||||
if(c==-1)
|
||||
break;
|
||||
}
|
||||
(void)splx(ipl);
|
||||
return c!=-1;
|
||||
}
|
||||
|
||||
static void
|
||||
a12_worry(int worry_number)
|
||||
{
|
||||
a12console_last_unexpected_error = worry_number;
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
/* $NetBSD: a12dcreg.h,v 1.2 2009/03/14 14:45:52 dsl Exp $ */
|
||||
|
||||
/* [Notice revision 2.2]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 AVALON OR THE 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.
|
||||
*/
|
||||
|
||||
#define A12DCREG() /* Generate ctags(1) key */
|
||||
|
||||
/* Id: a12backdriver.h,v 1.1.1.1 1997/12/04 04:33:31 ross Exp */
|
||||
|
||||
#define A12C_TXRDY 0x8000
|
||||
#define A12C_TXACK 0x4000
|
||||
#define CHMASK 0x3f00
|
||||
|
||||
#define MCQ_SLOTNO 0x81
|
||||
|
||||
#define MSP(n) (a12_mstate+(n))
|
||||
|
||||
#define CHANNEL_KDATA 1
|
||||
#define CHANNEL_KMARK 2
|
||||
#define CHANNEL_MULTI 3
|
||||
#define CHANNEL_MONITOR 4
|
||||
#define CHANNEL_SROM_A 5
|
||||
#define CHANNEL_SROM_D 6
|
||||
#define CHANNEL_CONSOLE 7
|
||||
|
||||
/* detached console commands > to detached console */
|
||||
/* < to A12 CPU */
|
||||
#define CPX_GEO 129 /* >return geographical address (card #)*/
|
||||
#define CPX_LOGMC 130 /* >return multi channel log level */
|
||||
#define CPX_PANIC 131 /* >process has entered panic() */
|
||||
#define CPX_READY 132 /* >fw kernel can accept CPX_GO command */
|
||||
#define CPX_GO 133 /* <fw kernel should proceed with boot */
|
||||
|
||||
#define MAX_EVENTS 1000
|
||||
#ifndef MAX_MODULES
|
||||
#define MAX_MODULES 1
|
||||
#endif
|
||||
|
||||
#define mcgetput(mn,chan,byte) msgetput(&a12_mstate[mn],(chan),(byte))
|
||||
|
||||
typedef unsigned char a12uchar;
|
||||
|
||||
enum tx_state {
|
||||
tx_idle, /* transmitter idle */
|
||||
tx_braaw /* transmitter byte ready assert ack wait */
|
||||
};
|
||||
|
||||
enum rx_state {
|
||||
rx_idle, /* receiver idle */
|
||||
rx_busy /* receiver byte is ready */
|
||||
};
|
||||
|
||||
typedef volatile long mmreg_t;
|
||||
|
||||
typedef struct mstate_struct {
|
||||
mmreg_t *xcdr; /* address of CDR */
|
||||
unsigned short cbvsr, /* software copy */
|
||||
cdr; /* software copy */
|
||||
unsigned short txsv, rxsv; /* transmitter and receiver states */
|
||||
a12uchar b2c_char,
|
||||
b2c_channel,
|
||||
c2b_char,
|
||||
c2b_channel;
|
||||
char up,
|
||||
inuse,
|
||||
reset_scanner,
|
||||
reset_loader;
|
||||
int panicexit;
|
||||
int txrdy_out, txrdy_in, /* current polarity of interlocks */
|
||||
txack_out, txack_in;
|
||||
char lastr, lastrc, /* last received char. and channel */
|
||||
lastt, lasttc; /* last transmitted char. and channel */
|
||||
unsigned int rx_busy_wait, /* receive busy ticks */
|
||||
rx_busy_cnt, /* receive busy start count */
|
||||
tx_busy_wait, /* transmit busy ticks */
|
||||
tx_busy_cnt; /* transmit busy start count */
|
||||
unsigned int tbytes, /* bytes not in block send */
|
||||
tblkbytes, /* bytes in block send */
|
||||
tblks; /* total blocks */
|
||||
unsigned int blwobe, /* blocks sent without retry */
|
||||
blwbe; /* blocks sent with retry */
|
||||
unsigned int max_blkretry; /* max. retries to send block */
|
||||
unsigned int max_blktime, /* max. time to send block */
|
||||
max_blktimesz; /* size of max. time block */
|
||||
unsigned int avg_blksz, /* avg. size block */
|
||||
avg_blktime; /* avg. time to send block */
|
||||
unsigned int retry_time; /* time spent sending re-try blocks */
|
||||
} mstate_type;
|
||||
|
||||
/* EVENT TRACKING */
|
||||
|
||||
typedef enum {
|
||||
BS,BE,BL,READ0,READ1,WRITE0,WRITE1,R360,W360,CL1,CL2,IDL1,IDL2
|
||||
} ET;
|
||||
|
||||
typedef struct {
|
||||
ET type;
|
||||
int time;
|
||||
char m; /* module # */
|
||||
char chnl;
|
||||
char rsv1;
|
||||
char rsv2;
|
||||
int data;
|
||||
} ESTRUCT;
|
||||
|
||||
/* EVENT TRACKING END */
|
||||
|
||||
mstate_type a12_mstate[MAX_MODULES];
|
||||
|
||||
int a12console_last_unexpected_error;
|
||||
|
||||
int a12dccnattach(void);
|
@ -1,746 +0,0 @@
|
||||
/* $NetBSD: if_xb.c,v 1.27 2011/06/14 15:34:21 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.2]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 AVALON OR THE 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Notes.
|
||||
*
|
||||
* Since the NetBSD build rules force the use of function prototypes, even on
|
||||
* functions that are defined before they are called, I've taken advantage of
|
||||
* the opportunity and organized this module in top down fashion, with
|
||||
* functions generally calling down the page rather than up. It's different.
|
||||
* I think I'm getting to like it this way.
|
||||
*
|
||||
* The crossbar interface is not exactly a peripheral device, and it cannot
|
||||
* appear on anything other than an alpha-based Avalon A12. The crossbar
|
||||
* controller is built into the core logic.
|
||||
*
|
||||
* If this version of the driver supports MPS transport, it may have some
|
||||
* large static data declarations. Don't worry about it, as Avalon a12
|
||||
* support should not appear in a GENERIC or INSTALL kernel.
|
||||
*
|
||||
* (Every A12 ever shipped had 512 MB per CPU except one site, which had 256
|
||||
* MB. Partly has a result of this, it is unlikely that a kernel configured
|
||||
* for an A12 would be exactly the thing to use on most workstations, so we
|
||||
* don't really need to worry that we might be configured in a generic or
|
||||
* site-wide kernel image.)
|
||||
*
|
||||
* This preliminary crossbar driver supports IP transport using PIO. Although
|
||||
* it would be nice to have a DMA driver, do note that the crossbar register
|
||||
* port is 128 bits wide, so we have 128-bit PIO. (The 21164 write buffer
|
||||
* will combine two 64-bit stores before they get off-chip.) Also, the rtmon
|
||||
* driver wasn't DMA either, so at least the NetBSD driver is as good as any
|
||||
* other that exists now.
|
||||
*
|
||||
* We'll do DMA and specialized transport ops later. Given the high speed of
|
||||
* the PIO mode, no current applications require DMA bandwidth, but everyone
|
||||
* benefits from low latency. The PIO mode is actually lower in latency
|
||||
* anyway.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_xb.c,v 1.27 2011/06/14 15:34:21 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/rpb.h>
|
||||
|
||||
#include <dev/isa/isareg.h>
|
||||
#include <dev/isa/isavar.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
#include <alpha/pci/pci_a12.h>
|
||||
|
||||
#if 1
|
||||
#define XB_DEBUG xb_debug
|
||||
#else
|
||||
#define XB_DEBUG 0
|
||||
#endif
|
||||
|
||||
#undef Static
|
||||
#if 1
|
||||
#define Static
|
||||
#else
|
||||
#define Static static
|
||||
#endif
|
||||
|
||||
#define IF_XB() /* Generate ctags(1) key */
|
||||
|
||||
#define XBAR_MTU (9*1024) /* Quite an arbitrary number */
|
||||
#define XBAR_MAXFRAMEHDR 48 /* Used to compute if_mtu */
|
||||
|
||||
#define XB_DEFAULT_MTU() (XBAR_MTU - XBAR_MAXFRAMEHDR)
|
||||
|
||||
#define FIFO_WORDCOUNT 60
|
||||
|
||||
static int xb_put_blk(struct mbuf *);
|
||||
static int xb_put(struct mbuf *);
|
||||
static long xb_fifo_empty(void);
|
||||
|
||||
int xbmatch(device_t, cfdata_t, void *);
|
||||
void xbattach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(xb, 0,
|
||||
xbmatch, xbattach, NULL, NULL);
|
||||
|
||||
extern struct cfdriver xb_cd;
|
||||
|
||||
long *xb_incoming;
|
||||
int xb_incoming_max = XBAR_MTU;
|
||||
|
||||
typedef struct ccode_struct {
|
||||
int64_t lo64, /* magic channel address s-word, high part*/
|
||||
hi64; /* magic channel address s-word, low part */
|
||||
} ccode_type;
|
||||
/*
|
||||
* Switch channel codes. Prepending one of these words will get you through
|
||||
* the switch, which will eat the word, open the addressed channel, and
|
||||
* forward the rest of the switch frame. Obviously, this helps if the second
|
||||
* switch word in the frame is the address word for a cascaded switch. (This
|
||||
* can be repeated for an arbitrary depth of MSN.) The words aren't quite as
|
||||
* weird as they look: the switch is really lots of narrow switches in an
|
||||
* array, and they don't switch an even number of hex digits. Also, there is
|
||||
* a parity bit on most of the subunits.
|
||||
*/
|
||||
ccode_type channel[]={
|
||||
{ 0x0000000000000000, 0x0000000000000000 },
|
||||
{ 0x8882108421084210, 0x1104210842108421 },
|
||||
{ 0x4441084210842108, 0x2208421084210842 },
|
||||
{ 0xccc318c6318c6318, 0x330c6318c6318c63 },
|
||||
{ 0x2220842108421084, 0x4410842108421084 },
|
||||
{ 0xaaa294a5294a5294, 0x5514a5294a5294a5 },
|
||||
{ 0x66618c6318c6318c, 0x6618c6318c6318c6 },
|
||||
{ 0xeee39ce739ce739c, 0x771ce739ce739ce7 },
|
||||
{ 0x1110421084210842, 0x8821084210842108 },
|
||||
{ 0x99925294a5294a52, 0x9925294a5294a529 },
|
||||
{ 0x55514a5294a5294a, 0xaa294a5294a5294a },
|
||||
{ 0xddd35ad6b5ad6b5a, 0xbb2d6b5ad6b5ad6b },
|
||||
{ 0x3330c6318c6318c6, 0xcc318c6318c6318c },
|
||||
{ 0xbbb2d6b5ad6b5ad6, 0xdd35ad6b5ad6b5ad }
|
||||
};
|
||||
|
||||
Static enum xb_intr_rcv_state_t {
|
||||
XBIR_PKTHDR = 0, XBIR_TRANS
|
||||
} xb_intr_rcv_state;
|
||||
|
||||
struct xb_config { int am_i_used; } xb_configuration;
|
||||
|
||||
Static struct ifnet xbi;
|
||||
|
||||
Static int frame_len;
|
||||
static int xb_debug;
|
||||
|
||||
Static void xb_start(struct ifnet *);
|
||||
Static void xb_mcrp_write(long *, int, int);
|
||||
static inline void xb_onefree(void);
|
||||
static long set_interrupt_on_fifo_empty(void);
|
||||
static void xb_init(struct ifnet *);
|
||||
static int xb_intr(void *);
|
||||
static void xb_intr_rcv(void);
|
||||
Static void quickload(volatile long *, long *);
|
||||
static void xb_init_config(struct xb_config *, int);
|
||||
static int xb_output(struct ifnet *, struct mbuf *,
|
||||
const struct sockaddr *, struct rtentry *);
|
||||
static int xb_ioctl(struct ifnet *, u_long, void *);
|
||||
static void xb_stop(void);
|
||||
static void a12_xbar_setup(void);
|
||||
|
||||
/* There Can Be Only One */
|
||||
|
||||
int xbfound;
|
||||
|
||||
int
|
||||
xbmatch(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
|
||||
return cputype == ST_AVALON_A12
|
||||
&& !xbfound;
|
||||
}
|
||||
|
||||
void
|
||||
xbattach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct xb_config *ccp;
|
||||
|
||||
strcpy(xbi.if_xname, device_xname(self));
|
||||
xbfound = 1;
|
||||
ccp = &xb_configuration;
|
||||
xb_init_config(ccp, 1);
|
||||
printf(": driver %s mtu %lu\n", "$Revision: 1.27 $", xbi.if_mtu);
|
||||
}
|
||||
|
||||
static void
|
||||
xb_init_config(struct xb_config *ccp, int mallocsafe)
|
||||
{
|
||||
/*
|
||||
* The driver actually only needs about 64 bytes of buffer but with a
|
||||
* nice contiguous frame we can call m_devget()
|
||||
*/
|
||||
if (mallocsafe && xb_incoming == NULL) {
|
||||
xb_incoming = malloc(xb_incoming_max, M_DEVBUF, M_NOWAIT);
|
||||
if (xb_incoming == NULL)
|
||||
DIE();
|
||||
}
|
||||
a12_xbar_setup();
|
||||
a12_intr_register_xb(xb_intr);
|
||||
}
|
||||
|
||||
/*
|
||||
* From The A12 Theory of Operation. Used with permission.
|
||||
* --- --- ------ -- ---------
|
||||
*
|
||||
* Message Channel Status Register
|
||||
*
|
||||
* 31 0
|
||||
* | |
|
||||
* 10987654 32109876 54321098 76543210
|
||||
*
|
||||
* ........ ........ 0oiefaAr TR...... MCSR
|
||||
*
|
||||
* Field Type Name Function
|
||||
*
|
||||
* R R,W1C RBC Receive Block Complete
|
||||
* T R,W1C TBC Transmit Block Complete
|
||||
* r R IMP Incoming message pending
|
||||
* A R IMFAE Incoming message fifo almost empty
|
||||
* a R OMFAF Outgoing message fifo almost full
|
||||
* f R OMFF Outgoing message fifo full
|
||||
* e R OMFE Outgoing message fifo empty
|
||||
* i R DMAin Incoming DMA channel armed
|
||||
* o R DMAout Outgoing DMA channel armed
|
||||
*
|
||||
* Interrupts Generated from MCSR
|
||||
*
|
||||
* IMChInt <= (RBC or IMP) and not DMAin
|
||||
* OMChInt <= ((TBC and not OMFAF) or (OMFE and OMR.E(6))
|
||||
* ) and not DMAout
|
||||
*
|
||||
*/
|
||||
static int
|
||||
xb_intr(void *p)
|
||||
{
|
||||
int n;
|
||||
long mcsrval;
|
||||
/*
|
||||
* The actual conditions under which this interrupt is generated are
|
||||
* a bit complicated, and no status flag is available that reads out
|
||||
* the final values of the interrupt inputs. But, it doesn't really
|
||||
* matter. Simply check for receive data and transmitter IFF_OACTIVE.
|
||||
*/
|
||||
while ((mcsrval = REGVAL(A12_MCSR)) & A12_MCSR_IMP)
|
||||
for(n = mcsrval & A12_MCSR_IMFAE ? 1 : 5; n; --n)
|
||||
xb_intr_rcv();
|
||||
|
||||
if (xbi.if_flags & IFF_OACTIVE
|
||||
&& mcsrval & A12_MCSR_OMFE) {
|
||||
xbi.if_flags &= ~IFF_OACTIVE;
|
||||
REGVAL(A12_OMR) &= ~A12_OMR_OMF_ENABLE;
|
||||
alpha_wmb();
|
||||
xb_start(&xbi);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* The interface logic will shoot us down with MCE (Missing Close Error) or
|
||||
* ECE (Embedded Close Error) if we aren't in sync with the hardware w.r.t.
|
||||
* frame boundaries. As those are panic-level errors: Don't Get Them.
|
||||
*/
|
||||
static void
|
||||
xb_intr_rcv(void)
|
||||
{
|
||||
struct mbuf *m;
|
||||
long frameword[2];
|
||||
static long *xb_ibp;
|
||||
int s = 0; /* XXX gcc */
|
||||
|
||||
switch (xb_intr_rcv_state) {
|
||||
case XBIR_PKTHDR:
|
||||
xb_ibp = xb_incoming;
|
||||
quickload(REGADDR(A12_FIFO), frameword); /* frame_len >= 16 */
|
||||
frame_len = frameword[0];
|
||||
if (!(20 <= frame_len && frame_len+16 <= xb_incoming_max))
|
||||
DIE();
|
||||
/*
|
||||
* The extra word when frames are of an aligned size is due
|
||||
* to the way the output routines work. After the mbuf is
|
||||
* sent xb_put_blk(NULL) is called. If there is a leftover
|
||||
* 127-bit-or-less fragment then the close word rides on it,
|
||||
* otherwise it gets an entire 128 bits of zeroes.
|
||||
*/
|
||||
if (frame_len & 0xf)
|
||||
frame_len = (frame_len + 0xf) >> 4;
|
||||
else frame_len = (frame_len >> 4) + 1;
|
||||
--frame_len; /* we read the frame len + the first packet int64 */
|
||||
*xb_ibp++ = frameword[1];
|
||||
xb_intr_rcv_state = XBIR_TRANS;
|
||||
break;
|
||||
case XBIR_TRANS:
|
||||
if (frame_len > 1)
|
||||
quickload(REGADDR(A12_FIFO), frameword);
|
||||
else if (frame_len == 1) {
|
||||
quickload(REGADDR(A12_FIFO_LWE), frameword);
|
||||
xb_intr_rcv_state = XBIR_PKTHDR;
|
||||
} else if (XB_DEBUG)
|
||||
DIE();
|
||||
--frame_len;
|
||||
xb_ibp[0] = frameword[0];
|
||||
xb_ibp[1] = frameword[1];
|
||||
xb_ibp += 2;
|
||||
if (xb_intr_rcv_state == XBIR_PKTHDR) {
|
||||
if (XB_DEBUG) {
|
||||
s = splnet();
|
||||
if (s != splnet())
|
||||
DIE();
|
||||
}
|
||||
++xbi.if_ipackets;
|
||||
if (IF_QFULL(&ipintrq)) {
|
||||
IF_DROP(&ipintrq);
|
||||
++xbi.if_iqdrops;
|
||||
} else {
|
||||
m = m_devget((void *)xb_incoming,
|
||||
(char *)xb_ibp - (char *)xb_incoming,
|
||||
0, &xbi, 0L);
|
||||
if (m) {
|
||||
xbi.if_ibytes += m->m_pkthdr.len;
|
||||
IF_ENQUEUE(&ipintrq, m);
|
||||
} else
|
||||
++xbi.if_ierrors;
|
||||
}
|
||||
if (XB_DEBUG)
|
||||
splx(s);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DIE();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Make it easy for gcc to load a[0..1] without interlocking between
|
||||
* a[0] and a[1]. (If it did, that would be two external bus cycles.)
|
||||
*/
|
||||
Static void
|
||||
quickload(volatile long *a, long *b)
|
||||
{
|
||||
long t1,t2;
|
||||
|
||||
t1 = a[0];
|
||||
t2 = a[1];
|
||||
b[0] = t1;
|
||||
b[1] = t2;
|
||||
}
|
||||
/*
|
||||
* Verify during debugging that we have not overflowed the FIFO
|
||||
*/
|
||||
static inline void
|
||||
xb_onefree(void)
|
||||
{
|
||||
if (XB_DEBUG && REGVAL(A12_MCSR) & A12_MCSR_OMFF)
|
||||
DIE();
|
||||
}
|
||||
|
||||
static void
|
||||
xb_init(struct ifnet *ifp)
|
||||
{
|
||||
ifp->if_flags |= IFF_RUNNING;
|
||||
}
|
||||
|
||||
static void
|
||||
xb_stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
xb_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
|
||||
{
|
||||
struct ifaddr *ifa = (struct ifaddr *)data;
|
||||
int s, error = 0;
|
||||
|
||||
s = splnet();
|
||||
switch (cmd) {
|
||||
case SIOCINITIFADDR:
|
||||
xbi.if_flags |= IFF_UP;
|
||||
xb_init(ifp);
|
||||
break;
|
||||
case SIOCSIFFLAGS:
|
||||
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
|
||||
break;
|
||||
if ((ifp->if_flags & IFF_UP) == 0 &&
|
||||
(ifp->if_flags & IFF_RUNNING) != 0) {
|
||||
xb_stop();
|
||||
ifp->if_flags &= ~IFF_RUNNING;
|
||||
} else if ((ifp->if_flags & IFF_UP) != 0 &&
|
||||
(ifp->if_flags & IFF_RUNNING) == 0) {
|
||||
xb_start(ifp);
|
||||
} else
|
||||
xb_init(ifp);
|
||||
if (ifp->if_flags & IFF_DEBUG)
|
||||
xb_debug = 1;
|
||||
break;
|
||||
default:
|
||||
error = ifioctl_common(ifp, cmd, data);
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
/*
|
||||
* XXX - someday, keep a software copy of A12_OMR. We can execute up to
|
||||
* 200 or 300 instructions in the time it takes to do the read part of an
|
||||
* external bus cycle RMW op. (Or 10 - 20 cache cycles.)
|
||||
*/
|
||||
static inline long
|
||||
xb_fifo_empty(void)
|
||||
{
|
||||
return REGVAL(A12_MCSR) & A12_MCSR_OMFE;
|
||||
}
|
||||
/*
|
||||
* rtmon frames
|
||||
*
|
||||
* [ (... data) : commid : sourcepid : dstpid : ktype : length : frametype ]
|
||||
*
|
||||
* At the moment, NetBSD ip frames are not compatible with rtmon frames:
|
||||
*
|
||||
* [ ... data : length ]
|
||||
*/
|
||||
static int
|
||||
xb_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst, struct rtentry *rt0)
|
||||
{
|
||||
int i,s;
|
||||
struct mbuf *m = m0;
|
||||
const char *lladdr;
|
||||
char *xbh;
|
||||
long xbo_framesize;
|
||||
const struct sockaddr_dl *llsa;
|
||||
int xbaddr;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ifp != &xbi)
|
||||
DIE();
|
||||
#endif
|
||||
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
|
||||
m_freem(m);
|
||||
return ENETDOWN;
|
||||
}
|
||||
/*
|
||||
* We want an IP packet with a link level route, on a silver platter.
|
||||
*/
|
||||
if (rt0 == NULL
|
||||
|| (rt0->rt_flags & (RTF_GATEWAY | RTF_LLINFO))
|
||||
|| (llsa = satocsdl(rt0->rt_gateway)) == NULL
|
||||
|| llsa->sdl_family != AF_LINK
|
||||
|| llsa->sdl_slen != 0) {
|
||||
++ifp->if_oerrors;
|
||||
m_freem(m);
|
||||
return EHOSTUNREACH;
|
||||
}
|
||||
if (dst == NULL
|
||||
|| dst->sa_family != AF_INET) {
|
||||
/*
|
||||
* This is because we give all received packets to ipintrq
|
||||
* right now.
|
||||
*/
|
||||
What();
|
||||
m_freem(m);
|
||||
++ifp->if_noproto;
|
||||
return EAFNOSUPPORT;
|
||||
}
|
||||
/*
|
||||
* The a12MppSwitch is a wormhole routed MSN consisting of a number
|
||||
* (usually n==1) of 14 channel crossbar switches. Each route through
|
||||
* a switch requires a 128 bit address word that specifies the channel
|
||||
* to emerge on. The address word is eaten by the switch and the
|
||||
* rest of the packet is routed through.
|
||||
*/
|
||||
lladdr = CLLADDR(llsa);
|
||||
if (llsa->sdl_alen != 1) /* XXX */
|
||||
DIE(); /* OK someday, but totally unexpected right now */
|
||||
/*
|
||||
* Alternatively, we could lookup the address word and output
|
||||
* it with PIO when the mbuf is dequeued
|
||||
*/
|
||||
xbo_framesize = m->m_pkthdr.len + 8;
|
||||
M_PREPEND(m, 16 * llsa->sdl_alen + 8, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return ENOBUFS;
|
||||
xbh = mtod(m, char *);
|
||||
for (i=0; i<llsa->sdl_alen; ++i) {
|
||||
xbaddr = (lladdr[i] & 0xff) - 1;
|
||||
if (!(0 <= xbaddr && xbaddr <= 11)) /* XXX */
|
||||
DIE(); /* 12 or 13 will be OK later */
|
||||
memcpy(xbh, &channel[xbaddr].lo64, 16);
|
||||
xbh += 16;
|
||||
}
|
||||
memcpy(xbh, &xbo_framesize, 8);
|
||||
s = splnet();
|
||||
if (IF_QFULL(&ifp->if_snd)) {
|
||||
IF_DROP(&ifp->if_snd);
|
||||
++ifp->if_oerrors;
|
||||
splx(s);
|
||||
m_freem(m);
|
||||
return ENOBUFS;
|
||||
}
|
||||
ifp->if_obytes += m->m_pkthdr.len;
|
||||
++ifp->if_opackets;
|
||||
IF_ENQUEUE(&ifp->if_snd, m);
|
||||
if ((ifp->if_flags & IFF_OACTIVE) == 0)
|
||||
xb_start(ifp);
|
||||
splx(s);
|
||||
if (m->m_flags & M_MCAST)
|
||||
ifp->if_omcasts++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
xb_start(struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
if ((xbi.if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
|
||||
return;
|
||||
for (;;) {
|
||||
IF_DEQUEUE(&xbi.if_snd, m);
|
||||
if (m == 0)
|
||||
return;
|
||||
/*
|
||||
* XXX The variable-length switch address words cause problems
|
||||
* for bpf, for now, leave it out. XXX It's not too hard to
|
||||
* fix, though, as there are lots of techniques that will
|
||||
* identify the number of switch address words.
|
||||
*/
|
||||
if (!xb_put(m)) {
|
||||
xbi.if_flags |= IFF_OACTIVE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
xb_put(struct mbuf *m)
|
||||
{
|
||||
struct mbuf *n;
|
||||
int len;
|
||||
|
||||
if (XB_DEBUG && (alpha_pal_rdps() & 7) < 3)
|
||||
DIE(); /* this "cannot happen", of course */
|
||||
for (; m; m = n) {
|
||||
len = m->m_len;
|
||||
if (len == 0 || xb_put_blk(m))
|
||||
MFREE(m, n);
|
||||
else return 0;
|
||||
}
|
||||
xb_put_blk(NULL);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Write a single mbuf to the transmit channel fifo. We can only write 128-bit
|
||||
* words. Right now, we pad at the end. It is possible to pad at the
|
||||
* beginning, especially since lots of games can be played at the receiver
|
||||
* with the mbuf data pointer. Padding at the beginning requires a pad-count
|
||||
* field in a header, but it means you can always DMA the data, regardless of
|
||||
* alignment. Of course, we don't DMA at all, right now.
|
||||
*/
|
||||
static int
|
||||
xb_put_blk(struct mbuf *m)
|
||||
{
|
||||
static long leftover[2]; /* 0-15 bytes from last xb_put_blk() */
|
||||
static int leftover_len; /* non-aligned amount from last call */
|
||||
long xfertmp[8]; /* aligned switch word buffer */
|
||||
int frag_len, /* fifo stream unit */
|
||||
fifo_len, /* space left in fifo */
|
||||
fillin, /* amount needed to complete a switch word */
|
||||
full, /* remember to restart on fifo full */
|
||||
len; /* amount of mbuf left to do */
|
||||
char *blk; /* location we are at in mbuf */
|
||||
static int fifo_free; /* current # of switch words free in fifo */
|
||||
|
||||
#define XFERADJ() ((char *)xfertmp + leftover_len)
|
||||
|
||||
/* There is always room for the close word */
|
||||
|
||||
if (m == NULL) {
|
||||
if (leftover_len)
|
||||
leftover_len = 0;
|
||||
else leftover[0] = leftover[1] = 0;
|
||||
xb_mcrp_write(leftover, 1, 1);
|
||||
--fifo_free;
|
||||
return 1;
|
||||
}
|
||||
|
||||
restart:
|
||||
if (fifo_free < 2) {
|
||||
if (!xb_fifo_empty()) {
|
||||
if(!set_interrupt_on_fifo_empty()) {
|
||||
/* still empty */
|
||||
xbi.if_flags |= IFF_OACTIVE;
|
||||
IF_PREPEND(&xbi.if_snd, m);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fifo_free = FIFO_WORDCOUNT;
|
||||
}
|
||||
len = m->m_len;
|
||||
if (len == 0)
|
||||
return 1; /* clean finish, nothing left over */
|
||||
blk = mtod(m, char *);
|
||||
if (leftover_len) {
|
||||
/* See function intro comment regarding padding */
|
||||
if (leftover_len + len < sizeof leftover) {
|
||||
/* Heh, not even enough to write out */
|
||||
memcpy(XFERADJ(), blk, len);
|
||||
leftover_len += len;
|
||||
return 1;
|
||||
}
|
||||
xfertmp[0] = leftover[0];
|
||||
xfertmp[1] = leftover[1];
|
||||
fillin = sizeof leftover - leftover_len;
|
||||
memcpy(XFERADJ(), blk, fillin);
|
||||
blk += fillin;
|
||||
len -= fillin;
|
||||
xb_mcrp_write(xfertmp, 1, 0);
|
||||
leftover_len = 0;
|
||||
--fifo_free;
|
||||
}
|
||||
/* fifo_free is known to be >= 1 at this point */
|
||||
while (len >= 16) {
|
||||
full = 0;
|
||||
frag_len = sizeof xfertmp;
|
||||
if (frag_len > len)
|
||||
frag_len = len;
|
||||
fifo_len = fifo_free * 16;
|
||||
if (frag_len > fifo_len) {
|
||||
frag_len = fifo_len;
|
||||
full = 1;
|
||||
}
|
||||
frag_len &= ~0xf;
|
||||
memcpy(xfertmp, blk, frag_len);
|
||||
frag_len >>= 4; /* Round down to switch word size */
|
||||
xb_mcrp_write(xfertmp, frag_len, 0);
|
||||
fifo_free -= frag_len;
|
||||
frag_len <<= 4;
|
||||
len -= frag_len;
|
||||
blk += frag_len;
|
||||
if (full) {
|
||||
m_adj(m, blk - mtod(m, char *));
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
memcpy(leftover, blk, len);
|
||||
leftover_len = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static long
|
||||
set_interrupt_on_fifo_empty(void)
|
||||
{
|
||||
REGVAL(A12_OMR) |= A12_OMR_OMF_ENABLE;
|
||||
alpha_mb();
|
||||
if(xb_fifo_empty()) {
|
||||
REGVAL(A12_OMR) &= ~A12_OMR_OMF_ENABLE;
|
||||
alpha_mb();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Write an aligned block of switch words to the FIFO
|
||||
*/
|
||||
Static void
|
||||
xb_mcrp_write(long *d, int n, int islast)
|
||||
{
|
||||
volatile long *xb_fifo = islast ? REGADDR(A12_FIFO_LWE)
|
||||
: REGADDR(A12_FIFO);
|
||||
int i;
|
||||
|
||||
if (XB_DEBUG && islast && n != 1)
|
||||
DIE();
|
||||
n <<= 1;
|
||||
for (i = 0; i < n; i += 2) {
|
||||
xb_onefree();
|
||||
xb_fifo[0] = d[i];
|
||||
xb_fifo[1] = d[i+1];
|
||||
alpha_wmb();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
const
|
||||
int32_t xbar_bc_addr = XBAR_BROADCAST;
|
||||
*/
|
||||
|
||||
static void
|
||||
a12_xbar_setup()
|
||||
{
|
||||
xbi.if_softc = &xb_softc;
|
||||
xbi.if_start = xb_start;
|
||||
xbi.if_ioctl = xb_ioctl;
|
||||
xbi.if_flags = IFF_BROADCAST /* ha ha */
|
||||
| IFF_SIMPLEX;
|
||||
|
||||
xbi.if_type = IFT_A12MPPSWITCH;
|
||||
xbi.if_addrlen = 32;
|
||||
xbi.if_hdrlen = 32;
|
||||
xbi.if_mtu = XB_DEFAULT_MTU();
|
||||
xbi.if_output = xb_output;
|
||||
/* xbi.if_broadcastaddr = (u_int8_t)&xbar_bc_addr; */
|
||||
|
||||
if_attach(&xbi);
|
||||
if_alloc_sadl(&xbi);
|
||||
|
||||
bpf_attach(&xbi, DLT_NULL, 0);
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/* $NetBSD: if_xb.h,v 1.3 2011/06/14 15:34:21 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.2]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 AVALON OR THE 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.
|
||||
*/
|
||||
|
||||
#ifndef _ALPHA_PCI_A12CVAR_H_
|
||||
#define _ALPHA_PCI_A12CVAR_H_
|
||||
|
||||
#define A12CVAR() /* generate ctags(1) key */
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <alpha/pci/pci_sgmap_pte64.h>
|
||||
/*
|
||||
* A12 Core Logic -a12c- configuration.
|
||||
*/
|
||||
struct a12c_config {
|
||||
int ac_initted;
|
||||
|
||||
bus_space_tag_t ac_iot, ac_memt;
|
||||
struct alpha_pci_chipset ac_pc;
|
||||
|
||||
struct alpha_bus_dma_tag ac_dmat_direct;
|
||||
struct alpha_bus_dma_tag ac_dmat_sgmap;
|
||||
|
||||
struct alpha_sgmap ac_sgmap;
|
||||
|
||||
u_int32_t ac_hae_mem;
|
||||
u_int32_t ac_hae_io;
|
||||
|
||||
struct extent *ac_io_ex, *ac_d_mem_ex, *ac_s_mem_ex;
|
||||
int ac_mallocsafe;
|
||||
};
|
||||
|
||||
struct a12c_softc {
|
||||
device_t sc_dev;
|
||||
|
||||
struct a12c_config *sc_ccp;
|
||||
};
|
||||
|
||||
void a12c_init(struct a12c_config *, int);
|
||||
void a12c_pci_init(pci_chipset_tag_t, void *);
|
||||
void a12c_dma_init(struct a12c_config *);
|
||||
|
||||
bus_space_tag_t a12c_bus_io_init(void *);
|
||||
bus_space_tag_t a12c_bus_mem_init(void *);
|
||||
|
||||
void a12_xbar_intr(void);
|
||||
|
||||
#endif
|
@ -1,239 +0,0 @@
|
||||
/* $NetBSD: avalon_a12.c,v 1.16 2011/06/14 15:34:21 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.2]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 AVALON OR THE 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1997 Carnegie-Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Chris G. Demetriou
|
||||
*
|
||||
* 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 the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: avalon_a12.c,v 1.16 2011/06/14 15:34:21 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/conf.h>
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/rpb.h>
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/cpuconf.h>
|
||||
#include <machine/prom.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
|
||||
#include <dev/scsipi/scsi_all.h>
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsiconf.h>
|
||||
|
||||
#include "a12dc.h"
|
||||
|
||||
#if NA12DC
|
||||
#include "alpha/a12/a12dcreg.h"
|
||||
#endif
|
||||
|
||||
#ifdef __never
|
||||
#define AVALON_A12() /* Generate ctags(1) key */
|
||||
#endif
|
||||
|
||||
void avalon_a12_init(void);
|
||||
static void avalon_a12_cons_init(void);
|
||||
static void avalon_a12_device_register(device_t, void *);
|
||||
static int a12env(int);
|
||||
|
||||
void
|
||||
avalon_a12_init()
|
||||
{
|
||||
platform.family = platform.model =
|
||||
"Avalon A12 Scalable Parallel Processor";
|
||||
platform.iobus = "a12c";
|
||||
platform.cons_init = avalon_a12_cons_init;
|
||||
platform.device_register = avalon_a12_device_register;
|
||||
|
||||
a12_cpu_local = a12env(A12CONS_CPU_LOCAL); /* our switch port */
|
||||
a12_cpu_ether = a12env(A12CONS_CPU_ETHER); /* route to outside world */
|
||||
a12_cpu_global= a12env(A12CONS_CPU_GLOBAL);/* loc in the big picture */
|
||||
a12_intr_register_icw(NULL);
|
||||
}
|
||||
/*
|
||||
* We _could_ get these configuration parameters directly from the
|
||||
* detached console, and thereby nuke yet another deprecated prom
|
||||
* call.
|
||||
*/
|
||||
static int
|
||||
a12env(int code)
|
||||
{
|
||||
int q;
|
||||
char string[16];
|
||||
|
||||
prom_getenv(code, string, sizeof(string));
|
||||
string[sizeof(string)-1] = '\0';
|
||||
q = string[0] - '0';
|
||||
if (string[0] && string[1] >= '0')
|
||||
q = q*10 + string[1] - '0';
|
||||
return q;
|
||||
}
|
||||
|
||||
void
|
||||
avalon_a12_cons_init()
|
||||
{
|
||||
#if NA12DC
|
||||
a12dccnattach();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
avalon_a12_device_register(device_t dev, void *aux)
|
||||
{
|
||||
static int found, initted, diskboot, netboot;
|
||||
static device_t pcidev, *ctrlrdev;
|
||||
struct bootdev_data *b = bootdev_data;
|
||||
device_t parent = device_parent(dev);
|
||||
|
||||
if (found)
|
||||
return;
|
||||
|
||||
if (!initted) {
|
||||
diskboot = (strcasecmp(b->protocol, "SCSI") == 0);
|
||||
netboot = (strcasecmp(b->protocol, "BOOTP") == 0) ||
|
||||
(strcasecmp(b->protocol, "MOP") == 0);
|
||||
#if 0
|
||||
printf("diskboot = %d, netboot = %d\n", diskboot, netboot);
|
||||
#endif
|
||||
initted =1;
|
||||
}
|
||||
|
||||
if (pcidev == NULL) {
|
||||
if (!device_is_a(dev, "pci"))
|
||||
return;
|
||||
else {
|
||||
struct pcibus_attach_args *pba = aux;
|
||||
|
||||
if ((b->slot / 1000) != pba->pba_bus)
|
||||
return;
|
||||
|
||||
pcidev = dev;
|
||||
#if 0
|
||||
printf("\npcidev = %s\n", device_xname(dev));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrlrdev == NULL) {
|
||||
if (parent != pcidev)
|
||||
return;
|
||||
else {
|
||||
struct pci_attach_args *pa = aux;
|
||||
int slot;
|
||||
|
||||
slot = pa->pa_bus * 1000 + pa->pa_function * 100 +
|
||||
pa->pa_device;
|
||||
if (b->slot != slot)
|
||||
return;
|
||||
|
||||
if (netboot) {
|
||||
booted_device = dev;
|
||||
#if 0
|
||||
printf("\nbooted_device = %s\n", device_xname(dev));
|
||||
#endif
|
||||
found = 1;
|
||||
} else {
|
||||
ctrlrdev = dev;
|
||||
#if 0
|
||||
printf("\nctrlrdev = %s\n", device_xname(dev));
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!diskboot)
|
||||
return;
|
||||
|
||||
if (device_is_a(dev, "sd") ||
|
||||
device_is_a(dev, "st") ||
|
||||
device_is_a(dev, "cd")) {
|
||||
struct scsipibus_attach_args *sa = aux;
|
||||
struct scsipi_periph *periph = sa->sa_periph;
|
||||
int unit;
|
||||
|
||||
if (device_parent(parent) != ctrlrdev)
|
||||
return;
|
||||
|
||||
unit = periph->periph_target * 100 + periph->periph_lun;
|
||||
if (b->unit != unit)
|
||||
return;
|
||||
if (b->channel != periph->periph_channel->chan_channel)
|
||||
return;
|
||||
|
||||
/* we've found it! */
|
||||
booted_device = dev;
|
||||
#if 0
|
||||
printf("\nbooted_device = %s\n", device_xname(dev));
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cpuconf.c,v 1.33 2009/03/18 10:22:22 cegger Exp $ */
|
||||
/* $NetBSD: cpuconf.c,v 1.34 2011/06/17 03:55:57 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
@ -60,7 +60,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpuconf.c,v 1.33 2009/03/18 10:22:22 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cpuconf.c,v 1.34 2011/06/17 03:55:57 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
@ -124,13 +124,6 @@ extern void dec_eb164_init(void);
|
||||
#define dec_eb164_init platform_not_configured
|
||||
#endif
|
||||
|
||||
#include "opt_avalon_a12.h"
|
||||
#ifdef AVALON_A12
|
||||
extern void avalon_a12_init(void);
|
||||
#else
|
||||
#define avalon_a12_init platform_not_configured
|
||||
#endif
|
||||
|
||||
#include "opt_dec_kn300.h"
|
||||
#ifdef DEC_KN300
|
||||
extern void dec_kn300_init(void);
|
||||
@ -219,7 +212,6 @@ static const struct cpuinit cpuinit[] = {
|
||||
cpu_init(ST_DEC_3000_500, dec_3000_500_init, "DEC_3000_500"),
|
||||
cpu_init(ST_DEC_2000_300, dec_2000_300_init, "DEC_2000_300"),
|
||||
cpu_init(ST_DEC_3000_300, dec_3000_300_init, "DEC_3000_300"),
|
||||
cpu_init(ST_AVALON_A12, avalon_a12_init, "AVALON_A12"),
|
||||
cpu_init(ST_DEC_2100_A500, dec_2100_a500_init, "DEC_2100_A500"),
|
||||
cpu_notsupp(ST_DEC_APXVME_64, "AXPvme 64"),
|
||||
cpu_init(ST_DEC_AXPPCI_33, dec_axppci_33_init, "DEC_AXPPCI_33"),
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.alpha,v 1.183 2011/06/12 03:35:37 rmind Exp $
|
||||
# $NetBSD: files.alpha,v 1.184 2011/06/17 03:55:57 matt Exp $
|
||||
#
|
||||
# alpha-specific configuration info
|
||||
|
||||
@ -21,7 +21,6 @@ defflag DEC_EB64PLUS # EB64+: AlphaPC 64, etc.
|
||||
defflag DEC_KN20AA # KN20AA: AlphaStation 500 and 600
|
||||
defflag DEC_KN8AE # KN8AE: AlphaServer 8200 and 8400
|
||||
defflag DEC_KN300 # KN300: AlphaServer 4X00
|
||||
defflag AVALON_A12 # Avalon: A12T1, A12M Parallel Supercomputer
|
||||
defflag DEC_1000 # Mikasa etc: AlphaServer 1000
|
||||
defflag DEC_1000A # Corelle etc: AlphaServer 800 and 1000A
|
||||
defflag DEC_ALPHABOOK1 # AlphaBook1: Tadpole/DEC AlphaBook
|
||||
@ -233,16 +232,6 @@ file arch/alpha/pci/cia_bwx_bus_mem.c cia
|
||||
file arch/alpha/pci/cia_swiz_bus_io.c cia
|
||||
file arch/alpha/pci/cia_swiz_bus_mem.c cia
|
||||
|
||||
define a12c_xb {}
|
||||
define a12c_a12dc {}
|
||||
|
||||
device a12c { }: pcibus, a12c_xb, a12c_a12dc
|
||||
attach a12c at mainbus
|
||||
file arch/alpha/pci/a12c.c a12c
|
||||
file arch/alpha/pci/a12c_bus_mem.c a12c
|
||||
file arch/alpha/pci/a12c_dma.c a12c
|
||||
file arch/alpha/pci/a12c_pci.c a12c
|
||||
|
||||
device dwlpx: pcibus, alpha_sgmap, alpha_pci_sgmap_pte32
|
||||
attach dwlpx at kft
|
||||
file arch/alpha/pci/dwlpx.c dwlpx
|
||||
@ -322,7 +311,6 @@ file arch/alpha/alpha/dec_2000_300.c dec_2000_300
|
||||
file arch/alpha/pci/pci_2100_a50.c dec_2100_a50
|
||||
file arch/alpha/pci/pci_2100_a500.c dec_2100_a500 | dec_2100a_a500
|
||||
file arch/alpha/pci/pci_up1000.c api_up1000
|
||||
file arch/alpha/pci/pci_a12.c avalon_a12
|
||||
file arch/alpha/pci/pci_alphabook1.c dec_alphabook1
|
||||
file arch/alpha/pci/pci_axppci_33.c dec_axppci_33
|
||||
file arch/alpha/pci/pci_eb164.c dec_eb164
|
||||
@ -354,22 +342,6 @@ attach pceb at pci
|
||||
file arch/alpha/pci/sio.c sio | pceb needs-flag
|
||||
file arch/alpha/pci/sio_pic.c sio | pceb
|
||||
|
||||
#
|
||||
# alpha/a12 platform-specific drivers
|
||||
#
|
||||
|
||||
# Switch
|
||||
|
||||
device xb
|
||||
attach xb at a12c_xb
|
||||
file arch/alpha/a12/if_xb.c xb
|
||||
|
||||
# Console
|
||||
|
||||
device a12dc
|
||||
attach a12dc at a12c_a12dc
|
||||
file arch/alpha/a12/a12dc.c a12dc needs-flag
|
||||
|
||||
#
|
||||
# Devices that can live on multiple busses
|
||||
#
|
||||
@ -434,7 +406,6 @@ file arch/alpha/alpha/dec_kn20aa.c dec_kn20aa
|
||||
file arch/alpha/alpha/dec_kn8ae.c dec_kn8ae
|
||||
file arch/alpha/alpha/dec_kn300.c dec_kn300
|
||||
file arch/alpha/alpha/api_up1000.c api_up1000
|
||||
file arch/alpha/alpha/avalon_a12.c avalon_a12
|
||||
file arch/alpha/alpha/dec_1000a.c dec_1000 | dec_1000a
|
||||
file arch/alpha/alpha/dec_6600.c dec_6600
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: majors.alpha,v 1.25 2010/03/06 23:45:39 plunky Exp $
|
||||
# $NetBSD: majors.alpha,v 1.26 2011/06/17 03:55:57 matt Exp $
|
||||
#
|
||||
# Device majors for alpha
|
||||
#
|
||||
@ -37,7 +37,7 @@ device-major wd char 36 block 4 wd
|
||||
device-major se char 37 se
|
||||
device-major satlink char 38 satlink
|
||||
device-major rnd char 39 rnd
|
||||
device-major a12dc char 40 a12dc
|
||||
#device-major obsolete char 40 obsolete
|
||||
device-major spkr char 41 spkr
|
||||
device-major scsibus char 42 scsibus
|
||||
device-major raid char 43 block 16 raid
|
||||
|
@ -1,166 +0,0 @@
|
||||
/* $NetBSD: a12c.c,v 1.24 2011/06/14 15:34:22 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.2]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 AVALON OR THE 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.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: a12c.c,v 1.24 2011/06/14 15:34:22 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/rpb.h>
|
||||
|
||||
#include <dev/isa/isareg.h>
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <alpha/alpha/clockvar.h>
|
||||
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
#include <alpha/pci/pci_a12.h>
|
||||
|
||||
#define A12C() /* Generate ctags(1) key */
|
||||
|
||||
int a12cmatch(device_t, cfdata_t, void *);
|
||||
void a12cattach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(a12c, sizeof(struct a12c_softc),
|
||||
a12cmatch, a12cattach, NULL, NULL);
|
||||
|
||||
extern struct cfdriver a12c_cd;
|
||||
|
||||
static const struct clocktime zeroct;
|
||||
|
||||
static void noclock_init(device_t);
|
||||
static void noclock_get(device_t, time_t, struct clocktime *);
|
||||
static void noclock_set(device_t, struct clocktime *);
|
||||
|
||||
static const struct clockfns noclock_fns = {
|
||||
noclock_init, noclock_get, noclock_set
|
||||
};
|
||||
|
||||
/* There can be only one. */
|
||||
|
||||
int a12cfound;
|
||||
struct a12c_config a12c_configuration;
|
||||
|
||||
int
|
||||
a12cmatch(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct mainbus_attach_args *ma = aux;
|
||||
|
||||
return cputype == ST_AVALON_A12
|
||||
&& strcmp(ma->ma_name, a12c_cd.cd_name) == 0
|
||||
&& !a12cfound;
|
||||
}
|
||||
|
||||
void
|
||||
a12c_init(struct a12c_config *ccp, int mallocsafe)
|
||||
{
|
||||
if (!ccp->ac_initted) {
|
||||
/* someday these may allocate memory, do once only */
|
||||
|
||||
ccp->ac_iot = 0;
|
||||
ccp->ac_memt = a12c_bus_mem_init(ccp);
|
||||
}
|
||||
ccp->ac_mallocsafe = mallocsafe;
|
||||
|
||||
a12c_pci_init(&ccp->ac_pc, ccp);
|
||||
|
||||
a12c_dma_init(ccp);
|
||||
|
||||
ccp->ac_initted = 1;
|
||||
}
|
||||
|
||||
void
|
||||
a12cattach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct a12c_softc *sc = device_private(self);
|
||||
struct a12c_config *ccp;
|
||||
struct pcibus_attach_args pba;
|
||||
|
||||
/* note that we've attached the chipset; can't have 2 A12Cs. */
|
||||
a12cfound = 1;
|
||||
sc->sc_dev = self;
|
||||
|
||||
/*
|
||||
* set up the chipset's info; done once at console init time
|
||||
* (maybe), but we must do it here as well to take care of things
|
||||
* that need to use memory allocation.
|
||||
*/
|
||||
ccp = sc->sc_ccp = &a12c_configuration;
|
||||
a12c_init(ccp, 1);
|
||||
|
||||
/* XXX print chipset information */
|
||||
aprint_normal(": driver %s over logic %x\n", "$Revision: 1.24 $",
|
||||
A12_ALL_EXTRACT(REGVAL(A12_VERS)));
|
||||
|
||||
pci_a12_pickintr(ccp);
|
||||
clockattach(noclock_init, NULL); /* XXX? */
|
||||
|
||||
memset(&pba, 0, sizeof(pba));
|
||||
pba.pba_iot = 0;
|
||||
pba.pba_memt = ccp->ac_memt;
|
||||
pba.pba_dmat = &ccp->ac_dmat_direct;
|
||||
pba.pba_dmat64 = NULL;
|
||||
pba.pba_pc = &ccp->ac_pc;
|
||||
pba.pba_bus = 0;
|
||||
pba.pba_bridgetag = NULL;
|
||||
pba.pba_flags = PCI_FLAGS_MEM_OKAY |
|
||||
PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
|
||||
|
||||
config_found_ia(self, "pcibus", &pba, pcibusprint);
|
||||
|
||||
pba.pba_bus = 1;
|
||||
config_found_ia(self, "a12c_xb", &pba, NULL);
|
||||
|
||||
pba.pba_bus = 2;
|
||||
config_found_ia(self, "a12c_a12dc", &pba, NULL);
|
||||
}
|
||||
|
||||
static void noclock_init(void (*)(void *), void *)
|
||||
{
|
||||
|
||||
/* nothing */
|
||||
}
|
@ -1,516 +0,0 @@
|
||||
/* $NetBSD: a12c_bus_mem.c,v 1.7 2009/03/14 21:04:02 dsl Exp $ */
|
||||
|
||||
/* [Notice revision 2.0]
|
||||
* Copyright (c) 1997 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <machine/bus.h>
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
|
||||
#define A12C_BUS_MEM() /* Generate ctags(1) key */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: a12c_bus_mem.c,v 1.7 2009/03/14 21:04:02 dsl Exp $");
|
||||
|
||||
/* Memory barrier */
|
||||
void pci_a12c_mem_barrier(void *, bus_space_handle_t,
|
||||
bus_size_t, bus_size_t, int);
|
||||
|
||||
/* Memory read (single) */
|
||||
u_int8_t pci_a12c_mem_read_1(void *, bus_space_handle_t,
|
||||
bus_size_t);
|
||||
u_int16_t pci_a12c_mem_read_2(void *, bus_space_handle_t,
|
||||
bus_size_t);
|
||||
u_int32_t pci_a12c_mem_read_4(void *, bus_space_handle_t,
|
||||
bus_size_t);
|
||||
u_int64_t pci_a12c_mem_read_8(void *, bus_space_handle_t,
|
||||
bus_size_t);
|
||||
|
||||
/* Memory read multiple */
|
||||
void pci_a12c_mem_read_multi_1(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int8_t *, bus_size_t);
|
||||
void pci_a12c_mem_read_multi_2(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int16_t *, bus_size_t);
|
||||
void pci_a12c_mem_read_multi_4(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int32_t *, bus_size_t);
|
||||
void pci_a12c_mem_read_multi_8(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int64_t *, bus_size_t);
|
||||
|
||||
/* Memory read region */
|
||||
void pci_a12c_mem_read_region_1(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int8_t *, bus_size_t);
|
||||
void pci_a12c_mem_read_region_2(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int16_t *, bus_size_t);
|
||||
void pci_a12c_mem_read_region_4(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int32_t *, bus_size_t);
|
||||
void pci_a12c_mem_read_region_8(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int64_t *, bus_size_t);
|
||||
|
||||
/* Memory write (single) */
|
||||
void pci_a12c_mem_write_1(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int8_t);
|
||||
void pci_a12c_mem_write_2(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int16_t);
|
||||
void pci_a12c_mem_write_4(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int32_t);
|
||||
void pci_a12c_mem_write_8(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int64_t);
|
||||
|
||||
/* Memory write multiple */
|
||||
void pci_a12c_mem_write_multi_1(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int8_t *, bus_size_t);
|
||||
void pci_a12c_mem_write_multi_2(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int16_t *, bus_size_t);
|
||||
void pci_a12c_mem_write_multi_4(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int32_t *, bus_size_t);
|
||||
void pci_a12c_mem_write_multi_8(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int64_t *, bus_size_t);
|
||||
|
||||
/* Memory write region */
|
||||
void pci_a12c_mem_write_region_1(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int8_t *, bus_size_t);
|
||||
void pci_a12c_mem_write_region_2(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int16_t *, bus_size_t);
|
||||
void pci_a12c_mem_write_region_4(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int32_t *, bus_size_t);
|
||||
void pci_a12c_mem_write_region_8(void *, bus_space_handle_t,
|
||||
bus_size_t, const u_int64_t *, bus_size_t);
|
||||
|
||||
/* Memory set multiple */
|
||||
void pci_a12c_mem_set_multi_1(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int8_t, bus_size_t);
|
||||
void pci_a12c_mem_set_multi_2(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int16_t, bus_size_t);
|
||||
void pci_a12c_mem_set_multi_4(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int32_t, bus_size_t);
|
||||
void pci_a12c_mem_set_multi_8(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int64_t, bus_size_t);
|
||||
|
||||
/* Memory set region */
|
||||
void pci_a12c_mem_set_region_1(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int8_t, bus_size_t);
|
||||
void pci_a12c_mem_set_region_2(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int16_t, bus_size_t);
|
||||
void pci_a12c_mem_set_region_4(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int32_t, bus_size_t);
|
||||
void pci_a12c_mem_set_region_8(void *, bus_space_handle_t,
|
||||
bus_size_t, u_int64_t, bus_size_t);
|
||||
|
||||
/* Memory copy */
|
||||
void pci_a12c_mem_copy_region_1(void *, bus_space_handle_t,
|
||||
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
|
||||
void pci_a12c_mem_copy_region_2(void *, bus_space_handle_t,
|
||||
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
|
||||
void pci_a12c_mem_copy_region_4(void *, bus_space_handle_t,
|
||||
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
|
||||
void pci_a12c_mem_copy_region_8(void *, bus_space_handle_t,
|
||||
bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t);
|
||||
|
||||
#define __S(S) __STRING(S)
|
||||
|
||||
/* mapping/unmapping */
|
||||
int pci_a12c_mem_map(void *, bus_addr_t, bus_size_t, int,
|
||||
bus_space_handle_t *, int);
|
||||
void pci_a12c_mem_unmap(void *, bus_space_handle_t,
|
||||
bus_size_t, int);
|
||||
int pci_a12c_mem_subregion(void *, bus_space_handle_t,
|
||||
bus_size_t, bus_size_t, bus_space_handle_t *);
|
||||
|
||||
/* allocation/deallocation */
|
||||
int pci_a12c_mem_alloc(void *, bus_addr_t, bus_addr_t,
|
||||
bus_size_t, bus_size_t, bus_addr_t, int, bus_addr_t *,
|
||||
bus_space_handle_t *);
|
||||
void pci_a12c_mem_free(void *, bus_space_handle_t,
|
||||
bus_size_t);
|
||||
|
||||
/* get kernel virtual address*/
|
||||
void *pci_a12c_mem_vaddr(void *, bus_space_handle_t);
|
||||
|
||||
static struct alpha_bus_space pci_a12c_mem_space = {
|
||||
/* cookie */
|
||||
NULL,
|
||||
|
||||
/* mapping/unmapping */
|
||||
pci_a12c_mem_map,
|
||||
pci_a12c_mem_unmap,
|
||||
pci_a12c_mem_subregion,
|
||||
|
||||
/* allocation/deallocation */
|
||||
pci_a12c_mem_alloc,
|
||||
pci_a12c_mem_free,
|
||||
|
||||
/* get kernel virtual address */
|
||||
pci_a12c_mem_vaddr,
|
||||
|
||||
/* barrier */
|
||||
pci_a12c_mem_barrier,
|
||||
|
||||
/* read (single) */
|
||||
pci_a12c_mem_read_1,
|
||||
pci_a12c_mem_read_2,
|
||||
pci_a12c_mem_read_4,
|
||||
pci_a12c_mem_read_8,
|
||||
|
||||
/* read multiple */
|
||||
pci_a12c_mem_read_multi_1,
|
||||
pci_a12c_mem_read_multi_2,
|
||||
pci_a12c_mem_read_multi_4,
|
||||
pci_a12c_mem_read_multi_8,
|
||||
|
||||
/* read region */
|
||||
pci_a12c_mem_read_region_1,
|
||||
pci_a12c_mem_read_region_2,
|
||||
pci_a12c_mem_read_region_4,
|
||||
pci_a12c_mem_read_region_8,
|
||||
|
||||
/* write (single) */
|
||||
pci_a12c_mem_write_1,
|
||||
pci_a12c_mem_write_2,
|
||||
pci_a12c_mem_write_4,
|
||||
pci_a12c_mem_write_8,
|
||||
|
||||
/* write multiple */
|
||||
pci_a12c_mem_write_multi_1,
|
||||
pci_a12c_mem_write_multi_2,
|
||||
pci_a12c_mem_write_multi_4,
|
||||
pci_a12c_mem_write_multi_8,
|
||||
|
||||
/* write region */
|
||||
pci_a12c_mem_write_region_1,
|
||||
pci_a12c_mem_write_region_2,
|
||||
pci_a12c_mem_write_region_4,
|
||||
pci_a12c_mem_write_region_8,
|
||||
|
||||
/* set multiple */
|
||||
pci_a12c_mem_set_multi_1,
|
||||
pci_a12c_mem_set_multi_2,
|
||||
pci_a12c_mem_set_multi_4,
|
||||
pci_a12c_mem_set_multi_8,
|
||||
|
||||
/* set region */
|
||||
pci_a12c_mem_set_region_1,
|
||||
pci_a12c_mem_set_region_2,
|
||||
pci_a12c_mem_set_region_4,
|
||||
pci_a12c_mem_set_region_8,
|
||||
|
||||
/* copy */
|
||||
pci_a12c_mem_copy_region_1,
|
||||
pci_a12c_mem_copy_region_2,
|
||||
pci_a12c_mem_copy_region_4,
|
||||
pci_a12c_mem_copy_region_8,
|
||||
};
|
||||
|
||||
bus_space_tag_t
|
||||
a12c_bus_mem_init(void *v)
|
||||
{
|
||||
bus_space_tag_t t;
|
||||
|
||||
t = &pci_a12c_mem_space;
|
||||
t->abs_cookie = v;
|
||||
return (t);
|
||||
}
|
||||
|
||||
int
|
||||
pci_a12c_mem_map(void *v, bus_addr_t memaddr, bus_size_t memsize, int flags, bus_space_handle_t *memhp, int acct)
|
||||
{
|
||||
if(flags & BUS_SPACE_MAP_LINEAR)
|
||||
printf("warning, linear a12 pci map requested\n");
|
||||
if(memaddr >= 1L<<28 || memaddr<0)
|
||||
return -1;
|
||||
*memhp = memaddr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pci_a12c_mem_unmap(void *v, bus_space_handle_t memh, bus_size_t memsize, int acct)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
pci_a12c_mem_subregion(void *v, bus_space_handle_t memh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nmemh)
|
||||
{
|
||||
*nmemh = memh + offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pci_a12c_mem_alloc(v, rstart, rend, size, align, boundary, flags,
|
||||
addrp, bshp)
|
||||
void *v;
|
||||
bus_addr_t rstart, rend, *addrp;
|
||||
bus_size_t size, align, boundary;
|
||||
int flags;
|
||||
bus_space_handle_t *bshp;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
pci_a12c_mem_free(void *v, bus_space_handle_t bsh, bus_size_t size)
|
||||
{
|
||||
}
|
||||
|
||||
void *
|
||||
pci_a12c_mem_vaddr(void *v, bus_space_handle_t bsh)
|
||||
{
|
||||
/* not supported (could panic() if pci_a12c_mem_map() caught it) */
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pci_a12c_mem_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int f)
|
||||
{
|
||||
/* optimize for wmb-only case but fall back to the more general mb */
|
||||
|
||||
if (f == BUS_SPACE_BARRIER_WRITE)
|
||||
alpha_wmb();
|
||||
else alpha_mb();
|
||||
}
|
||||
/*
|
||||
* Don't worry about calling small subroutines on the alpha. In the
|
||||
* time it takes to do a PCI bus target transfer, the 21164-400 can execute
|
||||
* 160 cycles, and up to 320 integer instructions.
|
||||
*/
|
||||
static void *
|
||||
setup_target_transfer(bus_space_handle_t memh, bus_size_t off)
|
||||
{
|
||||
register u_int64_t addr,t;
|
||||
|
||||
alpha_mb();
|
||||
addr = memh + off;
|
||||
t = REGVAL(A12_OMR) & ~A12_OMR_PCIAddr2;
|
||||
if (addr & 4)
|
||||
t |= A12_OMR_PCIAddr2;
|
||||
REGVAL(A12_OMR) = t;
|
||||
alpha_mb();
|
||||
return (void *)ALPHA_PHYS_TO_K0SEG(A12_PCITarget | (addr & ~4L));
|
||||
}
|
||||
|
||||
#define TARGET_EA(t,memh,off) ((t *)setup_target_transfer((memh),(off)))
|
||||
|
||||
#define TARGET_READ(n,t) \
|
||||
\
|
||||
t \
|
||||
__CONCAT(pci_a12c_mem_read_,n)(void *v, \
|
||||
bus_space_handle_t memh, \
|
||||
bus_size_t off) \
|
||||
{ \
|
||||
return *TARGET_EA(t,memh,off); \
|
||||
}
|
||||
|
||||
TARGET_READ(1, u_int8_t)
|
||||
TARGET_READ(2, u_int16_t)
|
||||
TARGET_READ(4, u_int32_t)
|
||||
TARGET_READ(8, u_int64_t)
|
||||
|
||||
#define pci_a12c_mem_read_multi_N(BYTES,TYPE) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_read_multi_,BYTES)(v, h, o, a, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h; \
|
||||
bus_size_t o, c; \
|
||||
TYPE *a; \
|
||||
{ \
|
||||
\
|
||||
while (c-- > 0) { \
|
||||
alpha_mb(); \
|
||||
*a++ = __CONCAT(pci_a12c_mem_read_,BYTES)(v, h, o); \
|
||||
} \
|
||||
}
|
||||
|
||||
pci_a12c_mem_read_multi_N(1,u_int8_t)
|
||||
pci_a12c_mem_read_multi_N(2,u_int16_t)
|
||||
pci_a12c_mem_read_multi_N(4,u_int32_t)
|
||||
pci_a12c_mem_read_multi_N(8,u_int64_t)
|
||||
/*
|
||||
|
||||
* In this case, we _really_ don't want all those barriers that the
|
||||
* bus_space_read's once did, and that we have carried over into
|
||||
* the A12 version. Perhaps we need a gratuitous barrier-on mode.
|
||||
* The only reason to have the bus_space_r/w functions do barriers is
|
||||
* to make up for call sites that incorrectly omit the bus_space_barrier
|
||||
* calls.
|
||||
*/
|
||||
|
||||
#define pci_a12c_mem_read_region_N(BYTES,TYPE) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_read_region_,BYTES)(v, h, o, a, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h; \
|
||||
bus_size_t o, c; \
|
||||
TYPE *a; \
|
||||
{ \
|
||||
\
|
||||
while (c-- > 0) { \
|
||||
*a++ = __CONCAT(pci_a12c_mem_read_,BYTES)(v, h, o); \
|
||||
o += sizeof *a; \
|
||||
} \
|
||||
}
|
||||
pci_a12c_mem_read_region_N(1,u_int8_t)
|
||||
pci_a12c_mem_read_region_N(2,u_int16_t)
|
||||
pci_a12c_mem_read_region_N(4,u_int32_t)
|
||||
pci_a12c_mem_read_region_N(8,u_int64_t)
|
||||
|
||||
#define TARGET_WRITE(n,t) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_write_,n)(v, memh, off, val) \
|
||||
void *v; \
|
||||
bus_space_handle_t memh; \
|
||||
bus_size_t off; \
|
||||
t val; \
|
||||
{ \
|
||||
alpha_wmb(); \
|
||||
*TARGET_EA(t,memh,off) = val; \
|
||||
alpha_wmb(); \
|
||||
}
|
||||
|
||||
TARGET_WRITE(1,u_int8_t)
|
||||
TARGET_WRITE(2,u_int16_t)
|
||||
TARGET_WRITE(4,u_int32_t)
|
||||
TARGET_WRITE(8,u_int64_t)
|
||||
|
||||
#define pci_a12c_mem_write_multi_N(BYTES,TYPE) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_write_multi_,BYTES)(v, h, o, a, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h; \
|
||||
bus_size_t o, c; \
|
||||
const TYPE *a; \
|
||||
{ \
|
||||
\
|
||||
while (c-- > 0) { \
|
||||
__CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, *a++); \
|
||||
alpha_wmb(); \
|
||||
} \
|
||||
}
|
||||
|
||||
pci_a12c_mem_write_multi_N(1,u_int8_t)
|
||||
pci_a12c_mem_write_multi_N(2,u_int16_t)
|
||||
pci_a12c_mem_write_multi_N(4,u_int32_t)
|
||||
pci_a12c_mem_write_multi_N(8,u_int64_t)
|
||||
|
||||
#define pci_a12c_mem_write_region_N(BYTES,TYPE) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_write_region_,BYTES)(v, h, o, a, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h; \
|
||||
bus_size_t o, c; \
|
||||
const TYPE *a; \
|
||||
{ \
|
||||
\
|
||||
while (c-- > 0) { \
|
||||
__CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, *a++); \
|
||||
o += sizeof *a; \
|
||||
} \
|
||||
}
|
||||
|
||||
pci_a12c_mem_write_region_N(1,u_int8_t)
|
||||
pci_a12c_mem_write_region_N(2,u_int16_t)
|
||||
pci_a12c_mem_write_region_N(4,u_int32_t)
|
||||
pci_a12c_mem_write_region_N(8,u_int64_t)
|
||||
|
||||
#define pci_a12c_mem_set_multi_N(BYTES,TYPE) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_set_multi_,BYTES)(v, h, o, val, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h; \
|
||||
bus_size_t o, c; \
|
||||
TYPE val; \
|
||||
{ \
|
||||
\
|
||||
while (c-- > 0) { \
|
||||
__CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, val); \
|
||||
alpha_wmb(); \
|
||||
} \
|
||||
}
|
||||
|
||||
pci_a12c_mem_set_multi_N(1,u_int8_t)
|
||||
pci_a12c_mem_set_multi_N(2,u_int16_t)
|
||||
pci_a12c_mem_set_multi_N(4,u_int32_t)
|
||||
pci_a12c_mem_set_multi_N(8,u_int64_t)
|
||||
|
||||
#define pci_a12c_mem_set_region_N(BYTES,TYPE) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_set_region_,BYTES)(v, h, o, val, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h; \
|
||||
bus_size_t o, c; \
|
||||
TYPE val; \
|
||||
{ \
|
||||
\
|
||||
while (c-- > 0) { \
|
||||
__CONCAT(pci_a12c_mem_write_,BYTES)(v, h, o, val); \
|
||||
o += sizeof val; \
|
||||
} \
|
||||
}
|
||||
|
||||
pci_a12c_mem_set_region_N(1,u_int8_t)
|
||||
pci_a12c_mem_set_region_N(2,u_int16_t)
|
||||
pci_a12c_mem_set_region_N(4,u_int32_t)
|
||||
pci_a12c_mem_set_region_N(8,u_int64_t)
|
||||
|
||||
#define pci_a12c_mem_copy_region_N(BYTES) \
|
||||
void \
|
||||
__CONCAT(pci_a12c_mem_copy_region_,BYTES)(v, h1, o1, h2, o2, c) \
|
||||
void *v; \
|
||||
bus_space_handle_t h1, h2; \
|
||||
bus_size_t o1, o2, c; \
|
||||
{ \
|
||||
bus_size_t o; \
|
||||
\
|
||||
if ((h1 >> 63) != 0 && (h2 >> 63) != 0) { \
|
||||
memmove((void *)(h2 + o2), (void *)(h1 + o1), c * BYTES); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
if (h1 + o1 >= h2 + o2) \
|
||||
/* src after dest: copy forward */ \
|
||||
for (o = 0; c > 0; c--, o += BYTES) \
|
||||
__CONCAT(pci_a12c_mem_write_,BYTES)(v, h2, o2 + o, \
|
||||
__CONCAT(pci_a12c_mem_read_,BYTES)(v, h1, o1 + o)); \
|
||||
else \
|
||||
/* dest after src: copy backwards */ \
|
||||
for (o = (c - 1) * BYTES; c > 0; c--, o -= BYTES) \
|
||||
__CONCAT(pci_a12c_mem_write_,BYTES)(v, h2, o2 + o, \
|
||||
__CONCAT(pci_a12c_mem_read_,BYTES)(v, h1, o1 + o)); \
|
||||
}
|
||||
pci_a12c_mem_copy_region_N(1)
|
||||
pci_a12c_mem_copy_region_N(2)
|
||||
pci_a12c_mem_copy_region_N(4)
|
||||
pci_a12c_mem_copy_region_N(8)
|
@ -1,145 +0,0 @@
|
||||
/* $NetBSD: a12c_dma.c,v 1.7 2010/12/15 01:27:18 matt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Stub version -- drivers used on the A12 (primarily ade) were adapted
|
||||
* for NetBSD prior to the availability of bus_dma.
|
||||
* They employ ad-hoc support for the required sram
|
||||
* bounce buffers and are not in the NetBSD source
|
||||
* tree. When a bus_dma if_de is available, this
|
||||
* module will need to be completed! I certainly
|
||||
* would not mind committing if_ade, but it doesn't
|
||||
* have any lasting value.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: a12c_dma.c,v 1.7 2010/12/15 01:27:18 matt Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#define _ALPHA_BUS_DMA_PRIVATE
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
|
||||
#define A12C_DMA() /* Generate ctags(1) key */
|
||||
|
||||
bus_dma_tag_t a12c_dma_get_tag(bus_dma_tag_t, alpha_bus_t);
|
||||
|
||||
|
||||
int a12c_bus_dmamap_load_direct(bus_dma_tag_t, bus_dmamap_t, void *,
|
||||
bus_size_t, struct proc *, int);
|
||||
|
||||
int a12c_bus_dmamap_load_mbuf_direct(bus_dma_tag_t, bus_dmamap_t,
|
||||
struct mbuf *, int);
|
||||
|
||||
int a12c_bus_dmamap_load_uio_direct(bus_dma_tag_t, bus_dmamap_t,
|
||||
struct uio *, int);
|
||||
|
||||
int a12c_bus_dmamap_load_raw_direct(bus_dma_tag_t, bus_dmamap_t,
|
||||
bus_dma_segment_t *, int, bus_size_t, int);
|
||||
|
||||
void
|
||||
a12c_dma_init(struct a12c_config *ccp)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the bus dma tag to be used for the specified bus type.
|
||||
* INTERNAL USE ONLY!
|
||||
*/
|
||||
bus_dma_tag_t
|
||||
a12c_dma_get_tag(bus_dma_tag_t t, alpha_bus_t bustype)
|
||||
{
|
||||
DIE();
|
||||
}
|
||||
/*
|
||||
* Load a A12C direct-mapped DMA map with a linear buffer.
|
||||
*/
|
||||
int
|
||||
a12c_bus_dmamap_load_direct(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags)
|
||||
{
|
||||
DIE();
|
||||
#if 0
|
||||
|
||||
return (_bus_dmamap_load_direct_common(t, map, buf, buflen, p,
|
||||
flags, A12C_DIRECT_MAPPED_BASE));
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Load a A12C direct-mapped DMA map with an mbuf chain.
|
||||
*/
|
||||
int
|
||||
a12c_bus_dmamap_load_mbuf_direct(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m, int flags)
|
||||
{
|
||||
DIE();
|
||||
#if 0
|
||||
|
||||
return (_bus_dmamap_load_mbuf_direct_common(t, map, m,
|
||||
flags, A12C_DIRECT_MAPPED_BASE));
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Load a A12C direct-mapped DMA map with a uio.
|
||||
*/
|
||||
int
|
||||
a12c_bus_dmamap_load_uio_direct(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, int flags)
|
||||
{
|
||||
DIE();
|
||||
#if 0
|
||||
|
||||
return (_bus_dmamap_load_uio_direct_common(t, map, uio,
|
||||
flags, A12C_DIRECT_MAPPED_BASE));
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Load a A12C direct-mapped DMA map with raw memory.
|
||||
*/
|
||||
int
|
||||
a12c_bus_dmamap_load_raw_direct(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags)
|
||||
{
|
||||
DIE();
|
||||
#if 0
|
||||
|
||||
return (_bus_dmamap_load_raw_direct_common(t, map, segs, nsegs,
|
||||
size, flags, A12C_DIRECT_MAPPED_BASE));
|
||||
#endif
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
/* $NetBSD: a12c_pci.c,v 1.8 2011/06/14 15:34:22 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.0]
|
||||
* Copyright (c) 1997 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: a12c_pci.c,v 1.8 2011/06/14 15:34:22 matt Exp $");
|
||||
__KERNEL_COPYRIGHT(0,
|
||||
"Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
|
||||
#include <machine/rpb.h> /* XXX for eb164 CIA firmware workarounds. */
|
||||
|
||||
#define A12C_PCI() /* Generate ctags(1) key */
|
||||
|
||||
void a12c_attach_hook(device_t, device_t,
|
||||
struct pcibus_attach_args *);
|
||||
int a12c_bus_maxdevs(void *, int);
|
||||
pcitag_t a12c_make_tag(void *, int, int, int);
|
||||
void a12c_decompose_tag(void *, pcitag_t, int *, int *,
|
||||
int *);
|
||||
pcireg_t a12c_conf_read(void *, pcitag_t, int);
|
||||
void a12c_conf_write(void *, pcitag_t, int, pcireg_t);
|
||||
|
||||
void
|
||||
a12c_pci_init(pci_chipset_tag_t pc, void *v)
|
||||
{
|
||||
|
||||
pc->pc_conf_v = v;
|
||||
pc->pc_attach_hook = a12c_attach_hook;
|
||||
pc->pc_bus_maxdevs = a12c_bus_maxdevs;
|
||||
pc->pc_make_tag = a12c_make_tag;
|
||||
pc->pc_decompose_tag = a12c_decompose_tag;
|
||||
pc->pc_conf_read = a12c_conf_read;
|
||||
pc->pc_conf_write = a12c_conf_write;
|
||||
}
|
||||
|
||||
void
|
||||
a12c_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
a12c_bus_maxdevs(void *cpv, int busno)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
pcitag_t
|
||||
a12c_make_tag(void *cpv, int b, int d, int f)
|
||||
{
|
||||
|
||||
return (b << 16) | (d << 11) | (f << 8);
|
||||
}
|
||||
|
||||
void
|
||||
a12c_decompose_tag(void *cpv, pcitag_t tag, int *bp, int *dp, int *fp)
|
||||
{
|
||||
|
||||
if (bp != NULL)
|
||||
*bp = (tag >> 16) & 0xff;
|
||||
if (dp != NULL)
|
||||
*dp = (tag >> 11) & 0x1f;
|
||||
if (fp != NULL)
|
||||
*fp = (tag >> 8) & 0x7;
|
||||
}
|
||||
|
||||
static void
|
||||
a12_clear_master_abort(void)
|
||||
{
|
||||
alpha_pal_draina();
|
||||
alpha_mb();
|
||||
REGVAL(A12_GSR) = REGVAL(A12_GSR) | A12_PCIMasterAbort;
|
||||
alpha_mb();
|
||||
}
|
||||
|
||||
static int
|
||||
a12_check_for_master_abort(void)
|
||||
{
|
||||
alpha_pal_draina();
|
||||
alpha_mb();
|
||||
return (REGVAL(A12_GSR) & A12_PCIMasterAbort)!=0;
|
||||
}
|
||||
|
||||
static int
|
||||
a12_set_pci_config_cycle(int offset)
|
||||
{
|
||||
alpha_pal_draina();
|
||||
alpha_mb();
|
||||
REGVAL(A12_OMR) = REGVAL(A12_OMR)
|
||||
| A12_OMR_PCIConfigCycle
|
||||
| (offset & 4 ? A12_OMR_PCIAddr2 : 0);
|
||||
alpha_mb();
|
||||
return offset & ~4;
|
||||
}
|
||||
|
||||
static void
|
||||
a12_reset_pci_config_cycle(void)
|
||||
{
|
||||
alpha_pal_draina();
|
||||
alpha_mb();
|
||||
REGVAL(A12_OMR) = REGVAL(A12_OMR)
|
||||
& ~(A12_OMR_PCIConfigCycle | A12_OMR_PCIAddr2);
|
||||
alpha_mb();
|
||||
}
|
||||
|
||||
pcireg_t
|
||||
a12c_conf_read(void *cpv, pcitag_t tag, int offset)
|
||||
{
|
||||
pcireg_t *datap, data;
|
||||
int s, ba;
|
||||
int32_t old_haxr2; /* XXX */
|
||||
|
||||
s = 0; /* XXX gcc -Wuninitialized */
|
||||
old_haxr2 = 0; /* XXX gcc -Wuninitialized */
|
||||
|
||||
if(tag)
|
||||
return ~0;
|
||||
|
||||
s = splhigh();
|
||||
a12_clear_master_abort();
|
||||
offset = a12_set_pci_config_cycle(offset);
|
||||
|
||||
datap = (pcireg_t *)(ALPHA_PHYS_TO_K0SEG(A12_PCITarget+offset));
|
||||
data = ~0L;
|
||||
if(!(ba = badaddr(datap, sizeof *datap)))
|
||||
data = *datap;
|
||||
|
||||
a12_reset_pci_config_cycle();
|
||||
if(a12_check_for_master_abort())
|
||||
data = ~0L;
|
||||
|
||||
splx(s);
|
||||
#if 0
|
||||
printf("a12c_conf_read: tag 0x%lx, reg 0x%lx -> %x @ %p%s\n", tag, offset,
|
||||
data, datap, ba ? " (badaddr)" : "");
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
a12c_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data)
|
||||
{
|
||||
pcireg_t *datap;
|
||||
int s;
|
||||
|
||||
s = 0; /* XXX gcc -Wuninitialized */
|
||||
|
||||
if(tag) {
|
||||
What();
|
||||
return;
|
||||
}
|
||||
|
||||
s = splhigh();
|
||||
offset = a12_set_pci_config_cycle(offset);
|
||||
datap = (pcireg_t *)(ALPHA_PHYS_TO_K0SEG(A12_PCITarget+offset));
|
||||
*datap = data;
|
||||
a12_reset_pci_config_cycle();
|
||||
splx(s);
|
||||
#if 0
|
||||
printf("a12c_conf_write: tag 0x%lx, reg 0x%lx -> 0x%x @ %p\n", tag,
|
||||
offset, data, datap);
|
||||
#endif
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
/* $NetBSD: a12creg.h,v 1.2 1998/03/02 06:56:16 ross Exp $ */
|
||||
|
||||
/* [Notice revision 2.0]
|
||||
* Copyright (c) 1997 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef _ALPHA_PCI_A12CREG_H_
|
||||
#define _ALPHA_PCI_A12CREG_H_
|
||||
|
||||
#define A12CREG() /* generate ctags(1) key */
|
||||
|
||||
#define REGADDR(r) ((volatile long *)ALPHA_PHYS_TO_K0SEG(r))
|
||||
#define REGVAL(r) (*REGADDR(r))
|
||||
/*
|
||||
* -- A d d r e s s L i n e --
|
||||
*
|
||||
* 39 36 29 28 27-13 12 .11 10 9 8-6 5 4 3
|
||||
*
|
||||
* IMALR 1 1 a a a-a a . a a a a-a 0 0
|
||||
* IMALR_LB 1 1 a a a-a a . a a a a-a 0 1
|
||||
* OMALR 1 1 a a a-a a . a a a a-a 1 0
|
||||
* OMALR_LB 1 1 a a a-a a . a a a a-a 1 1
|
||||
* MCRP 1 0 0 0 . 0 0 0 a-a a a a
|
||||
* MCRP_LWE 1 0 0 0 . 0 0 1 0 1
|
||||
* MCRP_LWO 1 0 0 0 . 0 1 0 1 1
|
||||
* MCSR 1 0 0 1 . 0 0 1 1
|
||||
* OMR 1 0 0 1 . 0 1 0 1
|
||||
* GSR 1 0 0 1 . 0 1 1 1
|
||||
* IETCR 1 0 0 1 . 1 0 0 1
|
||||
* CDR 1 0 0 1 . 1 0 1 1
|
||||
* PMEM 1 0 0 1 . 1 1 0 1
|
||||
* SOR 1 0 0 1 . 1 1 1 1
|
||||
* PCI Buffer 1 0 1 0 a-a a . a a a a a a
|
||||
* PCI Target 1 0 1 1 a-a a . a a a a a a
|
||||
* Main Memory 0 0 a a a-a a . a a a a a a
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#define _A12_IO 0x8000000000L
|
||||
|
||||
#define A12_OFFS_FIFO 0x0000
|
||||
#define A12_OFFS_FIFO_LWE 0x0200
|
||||
#define A12_OFFS_FIFO_LWO 0x0400
|
||||
#define A12_OFFS_VERS 0x1010
|
||||
#define A12_OFFS_MCSR 0x1210
|
||||
#define A12_OFFS_OMR 0x1410
|
||||
#define A12_OFFS_GSR 0x1610
|
||||
#define A12_OFFS_IETCR 0x1810
|
||||
#define A12_OFFS_CDR 0x1a10
|
||||
#define A12_OFFS_PMEM 0x1c10
|
||||
#define A12_OFFS_SOR 0x1e10
|
||||
|
||||
#define A12_FIFO (_A12_IO|A12_OFFS_FIFO)
|
||||
#define A12_FIFO_LWE (_A12_IO|A12_OFFS_FIFO_LWE)
|
||||
#define A12_FIFO_LWO (_A12_IO|A12_OFFS_FIFO_LWO)
|
||||
#define A12_VERS (_A12_IO|A12_OFFS_VERS)
|
||||
#define A12_MCSR (_A12_IO|A12_OFFS_MCSR)
|
||||
#define A12_OMR (_A12_IO|A12_OFFS_OMR)
|
||||
#define A12_GSR (_A12_IO|A12_OFFS_GSR)
|
||||
#define A12_IETCR (_A12_IO|A12_OFFS_IETCR)
|
||||
#define A12_CDR (_A12_IO|A12_OFFS_CDR)
|
||||
#define A12_PMEM (_A12_IO|A12_OFFS_PMEM)
|
||||
#define A12_SOR (_A12_IO|A12_OFFS_SOR)
|
||||
|
||||
#define A12_PCIBuffer 0x8020000000L
|
||||
#define A12_PCITarget 0x8030000000L
|
||||
|
||||
#define A12_PCIMasterAbort 0x8000 /* GSR */
|
||||
|
||||
#define A12_OMR_PCIAddr2 0x1000L /* OMR */
|
||||
#define A12_OMR_PCIConfigCycle 0x0800L /* OMR */
|
||||
#define A12_OMR_ICW_ENABLE 0x0400L /* OMR */
|
||||
#define A12_OMR_IEI_ENABLE 0x0200L /* OMR */
|
||||
#define A12_OMR_TEI_ENABLE 0x0100L /* OMR */
|
||||
#define A12_OMR_PCI_ENABLE 0x0080L /* OMR */
|
||||
#define A12_OMR_OMF_ENABLE 0x0040L /* OMR */
|
||||
|
||||
#define A12_MCSR_DMAOUT 0x4000 /* Outgoing DMA channel armed */
|
||||
#define A12_MCSR_DMAIN 0x2000 /* Incoming DMA channel armed */
|
||||
#define A12_MCSR_OMFE 0x1000 /* Outgoing message fifo empty */
|
||||
#define A12_MCSR_OMFF 0x0800 /* Outgoing message fifo full */
|
||||
#define A12_MCSR_OMFAF 0x0400 /* Outgoing message fifo almost full */
|
||||
#define A12_MCSR_IMFAE 0x0200 /* Incoming message fifo almost empty */
|
||||
#define A12_MCSR_IMP 0x0100 /* Incoming message pending */
|
||||
#define A12_MCSR_TBC 0x0080 /* Transmit Block Complete */
|
||||
#define A12_MCSR_RBC 0x0040 /* Receive Block Complete */
|
||||
|
||||
#define A12_GSR_PDI 0x0040 /* PCI device interrupt asserted */
|
||||
#define A12_GSR_PEI 0x0080 /* PCI SERR# pulse received */
|
||||
#define A12_GSR_MCE 0x0100 /* Missing Close Error Flag */
|
||||
#define A12_GSR_ECE 0x0200 /* Embedded Close Error Flag */
|
||||
#define A12_GSR_TEI 0x0400 /* Timer event interrupt pending */
|
||||
#define A12_GSR_IEI 0x0800 /* Interval event interrupt pending */
|
||||
#define A12_GSR_FORUN 0x1000 /* FIFO Overrun Error */
|
||||
#define A12_GSR_FURUN 0x2000 /* FIFO Underrun Error */
|
||||
#define A12_GSR_ICW 0x4000 /* Incoming Control Word */
|
||||
#define A12_GSR_ABORT 0x8000 /* PCI Master or Target Abort */
|
||||
|
||||
#define A12_ALL_WIRED 0xffc0 /* Core logic wires these bits */
|
||||
#define A12_ALL_FIRST 6 /* ...starting at this one */
|
||||
#define A12_ALL_EXTRACT(r) (((r) & A12_ALL_WIRED) >> A12_ALL_FIRST)
|
||||
|
||||
#define A12_CBMAOFFSET 0x0100
|
||||
|
||||
#define A12_XBAR_CHANNEL_MAX 14
|
||||
#define A12_TMP_PID_COUNT 12
|
||||
|
||||
#define A12CONS_CPU_LOCAL 0x40 /* our switch channel */
|
||||
#define A12CONS_CPU_ETHER 0x41 /* route to outside world */
|
||||
#define A12CONS_CPU_GLOBAL 0x42 /* location in the big picture */
|
||||
|
||||
#define DIE() NICETRY()
|
||||
#define NICETRY() panic("Nice try @ %s:%d\n", __FILE__, __LINE__)
|
||||
#define What() printf("%s:%d. What?\n", __FILE__, __LINE__)
|
||||
|
||||
#endif
|
@ -1,93 +0,0 @@
|
||||
/* $NetBSD: a12cvar.h,v 1.6 2011/06/14 15:34:22 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.0]
|
||||
* Copyright (c) 1997 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef _ALPHA_PCI_A12CVAR_H_
|
||||
#define _ALPHA_PCI_A12CVAR_H_
|
||||
|
||||
#define A12CVAR() /* generate ctags(1) key */
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <alpha/pci/pci_sgmap_pte64.h>
|
||||
/*
|
||||
* A12 Core Logic -a12c- configuration.
|
||||
*/
|
||||
struct a12c_config {
|
||||
int ac_initted;
|
||||
|
||||
bus_space_tag_t ac_iot, ac_memt;
|
||||
struct alpha_pci_chipset ac_pc;
|
||||
|
||||
struct alpha_bus_dma_tag ac_dmat_direct;
|
||||
struct alpha_bus_dma_tag ac_dmat_sgmap;
|
||||
|
||||
struct alpha_sgmap ac_sgmap;
|
||||
|
||||
u_int32_t ac_hae_mem;
|
||||
u_int32_t ac_hae_io;
|
||||
|
||||
struct extent *ac_io_ex, *ac_d_mem_ex, *ac_s_mem_ex;
|
||||
int ac_mallocsafe;
|
||||
};
|
||||
|
||||
struct a12c_softc {
|
||||
device_t sc_dev;
|
||||
|
||||
struct a12c_config *sc_ccp;
|
||||
};
|
||||
|
||||
void a12c_init(struct a12c_config *, int);
|
||||
void a12c_pci_init(pci_chipset_tag_t, void *);
|
||||
void a12c_dma_init(struct a12c_config *);
|
||||
|
||||
bus_space_tag_t a12c_bus_io_init(void *);
|
||||
bus_space_tag_t a12c_bus_mem_init(void *);
|
||||
/*
|
||||
* The following two CPU numbers are relative to the local switch;
|
||||
* in a multistage system these numbers will not be unique. a12_ethercpu
|
||||
* is used to route bootp packets and to mount the root FS.
|
||||
*/
|
||||
int a12_cpu_local; /* our CPU number relative to the local switch */
|
||||
int a12_cpu_ether; /* relative CPU number with outside world access */
|
||||
int a12_cpu_global; /* XXX used to construct MSN routing tables XXX */
|
||||
|
||||
void a12_intr_register_xb(int (*)(void *));
|
||||
void a12_intr_register_icw(int (*)(void *));
|
||||
void configure_xb(void);
|
||||
void configure_a12dc(void);
|
||||
|
||||
#endif
|
@ -1,290 +0,0 @@
|
||||
/* $NetBSD: pci_a12.c,v 1.12 2010/12/15 01:27:19 matt Exp $ */
|
||||
|
||||
/* [Notice revision 2.0]
|
||||
* Copyright (c) 1997, 1998 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#include "opt_avalon_a12.h" /* Config options headers */
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: pci_a12.c,v 1.12 2010/12/15 01:27:19 matt Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <alpha/pci/a12creg.h>
|
||||
#include <alpha/pci/a12cvar.h>
|
||||
|
||||
#include <alpha/pci/pci_a12.h>
|
||||
|
||||
#define PCI_A12() /* Generate ctags(1) key */
|
||||
|
||||
#define LOADGSR() (REGVAL(A12_GSR) & 0x7fc0)
|
||||
|
||||
static int pci_serr(void *);
|
||||
static int a12_xbar_flag(void *);
|
||||
|
||||
struct a12_intr_vect_t {
|
||||
int on;
|
||||
int (*f)(void *);
|
||||
void *a;
|
||||
} a12_intr_pci = { 0 },
|
||||
a12_intr_serr = { 1, pci_serr },
|
||||
a12_intr_flag = { 1, a12_xbar_flag },
|
||||
a12_intr_iei = { 0 },
|
||||
a12_intr_dc = { 0 },
|
||||
|
||||
a12_intr_xb = { 0 };
|
||||
|
||||
static struct gintcall {
|
||||
char flag;
|
||||
char needsclear;
|
||||
char intr_index; /* XXX implicit crossref */
|
||||
struct a12_intr_vect_t *f;
|
||||
char *msg;
|
||||
} gintcall[] = {
|
||||
{ 6, 0, 2, &a12_intr_pci, "PCI Device" },
|
||||
{ 7, 1, 3, &a12_intr_serr, "PCI SERR#" },
|
||||
{ 8, 1, 4, &a12_intr_flag, "XB Frame MCE" },
|
||||
{ 9, 1, 5, &a12_intr_flag, "XB Frame ECE" },
|
||||
/* skip 10, gsr.TEI */
|
||||
{ 11, 1, 6, &a12_intr_iei, "Interval Timer"},
|
||||
{ 12, 1, 7, &a12_intr_flag, "XB FIFO Overrun"},
|
||||
{ 13, 1, 8, &a12_intr_flag, "XB FIFO Underrun"},
|
||||
{ 14, 1, 9, &a12_intr_dc, "DC Control Word"},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct evcnt a12_intr_evcnt;
|
||||
|
||||
int avalon_a12_intr_map(void *, pcitag_t, int, int,
|
||||
pci_intr_handle_t *);
|
||||
const char *avalon_a12_intr_string(void *, pci_intr_handle_t);
|
||||
const struct evcnt *avalon_a12_intr_evcnt(void *, pci_intr_handle_t);
|
||||
void *avalon_a12_intr_establish(void *, pci_intr_handle_t,
|
||||
int, int (*func)(void *), void *);
|
||||
void avalon_a12_intr_disestablish(void *, void *);
|
||||
|
||||
static void clear_gsr_interrupt(long);
|
||||
static void a12_GInt(void);
|
||||
|
||||
void a12_iointr(void *framep, unsigned long vec);
|
||||
|
||||
void
|
||||
pci_a12_pickintr(struct a12c_config *ccp)
|
||||
{
|
||||
pci_chipset_tag_t pc = &ccp->ac_pc;
|
||||
|
||||
pc->pc_intr_v = ccp;
|
||||
pc->pc_intr_map = avalon_a12_intr_map;
|
||||
pc->pc_intr_string = avalon_a12_intr_string;
|
||||
pc->pc_intr_evcnt = avalon_a12_intr_evcnt;
|
||||
pc->pc_intr_establish = avalon_a12_intr_establish;
|
||||
pc->pc_intr_disestablish = avalon_a12_intr_disestablish;
|
||||
|
||||
/* Not supported on A12. */
|
||||
pc->pc_pciide_compat_intr_establish = NULL;
|
||||
|
||||
evcnt_attach_dynamic(&a12_intr_evcnt, EVCNT_TYPE_INTR, NULL,
|
||||
"a12", "pci irq");
|
||||
|
||||
set_iointr(a12_iointr);
|
||||
}
|
||||
|
||||
int
|
||||
avalon_a12_intr_map(ccv, bustag, buspin, line, ihp)
|
||||
void *ccv;
|
||||
pcitag_t bustag;
|
||||
int buspin, line;
|
||||
pci_intr_handle_t *ihp;
|
||||
{
|
||||
/* only one PCI slot (per CPU, that is, but there are 12 CPU's!) */
|
||||
*ihp = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
avalon_a12_intr_string(void *ccv, pci_intr_handle_t ih)
|
||||
{
|
||||
return "a12 pci irq"; /* see "only one" note above */
|
||||
}
|
||||
|
||||
const struct evcnt *
|
||||
avalon_a12_intr_evcnt(void *ccv, pci_intr_handle_t ih)
|
||||
{
|
||||
|
||||
return (&a12_intr_evcnt);
|
||||
}
|
||||
|
||||
void *
|
||||
avalon_a12_intr_establish(void *ccv, pci_intr_handle_t ih, int level, int (*func)(void *), void *arg)
|
||||
{
|
||||
a12_intr_pci.f = func;
|
||||
a12_intr_pci.a = arg;
|
||||
a12_intr_pci.on= 1;
|
||||
alpha_wmb();
|
||||
REGVAL(A12_OMR) |= A12_OMR_PCI_ENABLE;
|
||||
alpha_mb();
|
||||
return (void *)func;
|
||||
}
|
||||
|
||||
void
|
||||
avalon_a12_intr_disestablish(void *ccv, void *cookie)
|
||||
{
|
||||
if(cookie == a12_intr_pci.f) {
|
||||
alpha_wmb();
|
||||
REGVAL(A12_OMR) &= ~A12_OMR_PCI_ENABLE;
|
||||
alpha_mb();
|
||||
a12_intr_pci.f = 0;
|
||||
a12_intr_pci.on= 0;
|
||||
} else What();
|
||||
}
|
||||
|
||||
void a12_intr_register_xb(f)
|
||||
int (*f)(void *);
|
||||
{
|
||||
a12_intr_xb.f = f;
|
||||
a12_intr_xb.on = 1;
|
||||
}
|
||||
|
||||
void a12_intr_register_icw(f)
|
||||
int (*f)(void *);
|
||||
{
|
||||
long t;
|
||||
|
||||
t = REGVAL(A12_OMR) & ~A12_OMR_ICW_ENABLE;
|
||||
if ((a12_intr_dc.on = (f != NULL)) != 0)
|
||||
t |= A12_OMR_ICW_ENABLE;
|
||||
a12_intr_dc.f = f;
|
||||
alpha_wmb();
|
||||
REGVAL(A12_OMR) = t;
|
||||
alpha_mb();
|
||||
}
|
||||
|
||||
long a12_nothing;
|
||||
|
||||
static void
|
||||
clear_gsr_interrupt(long write_1_to_clear)
|
||||
{
|
||||
REGVAL(A12_GSR) = write_1_to_clear;
|
||||
alpha_mb();
|
||||
a12_nothing = REGVAL(A12_GSR);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_serr(void *p)
|
||||
{
|
||||
panic("pci_serr");
|
||||
}
|
||||
|
||||
static int
|
||||
a12_xbar_flag(void *p)
|
||||
{
|
||||
panic("a12_xbar_flag: %s", p);
|
||||
}
|
||||
|
||||
static void
|
||||
a12_GInt(void)
|
||||
{
|
||||
struct gintcall *gic;
|
||||
long gsrsource,
|
||||
gsrvalue = LOADGSR();
|
||||
void *s;
|
||||
|
||||
/*
|
||||
* Switch interrupts do not go through this function
|
||||
*/
|
||||
for(gic=gintcall; gic->f; ++gic) {
|
||||
gsrsource = gsrvalue & 1L<<gic->flag;
|
||||
if (gsrsource && gic->f->on) {
|
||||
if(gic->needsclear)
|
||||
clear_gsr_interrupt(1L<<gic->flag);
|
||||
|
||||
s = gic->f->a;
|
||||
if (s == NULL)
|
||||
s = gic->msg;
|
||||
if (gic->f->f == NULL)
|
||||
printf("Stray interrupt: %s OMR=%lx\n",
|
||||
gic->msg, REGVAL(A12_OMR) & 0xffc0);
|
||||
else gic->f->f(s);
|
||||
alpha_wmb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IRQ_H 3 2 1 0
|
||||
* EV5(10) 23 22 21 20
|
||||
* EV5(16) 17 16 15 14
|
||||
* OSF IPL 6 5 4 3
|
||||
* VECTOR(16) 940 930 920 900 note: no 910 or 940
|
||||
* f(VECTOR) 4 3 2 0 note: no 1 or 4
|
||||
* EVENT Never Clk Misc Xbar
|
||||
*/
|
||||
|
||||
void
|
||||
a12_iointr(void *framep, unsigned long vec)
|
||||
{
|
||||
unsigned irq = (vec-0x900) >> 4; /* this is the f(vector) above */
|
||||
|
||||
/*
|
||||
* Xbar device is in the A12 CPU core logic, so its interrupts
|
||||
* might as well be hardwired.
|
||||
*/
|
||||
a12_intr_evcnt.ev_count++;
|
||||
|
||||
switch(irq) {
|
||||
case 0:
|
||||
if (a12_intr_xb.f == NULL)
|
||||
panic("no switch interrupt registered");
|
||||
else a12_intr_xb.f(NULL);
|
||||
return;
|
||||
case 2:
|
||||
a12_GInt();
|
||||
return;
|
||||
default:
|
||||
panic("a12_iointr");
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/* $NetBSD: pci_a12.h,v 1.4 2009/03/14 14:45:53 dsl Exp $ */
|
||||
|
||||
/* [Notice revision 2.0]
|
||||
* Copyright (c) 1997 Avalon Computer Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Ross Harvey
|
||||
*
|
||||
* 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 and
|
||||
* author 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. Neither the name of Avalon Computer Systems, Inc. nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. This copyright will be assigned to The NetBSD Foundation on
|
||||
* 1/1/2000 unless these terms (including possibly the assignment
|
||||
* date) are updated in writing by Avalon prior to the latest specified
|
||||
* assignment date.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AVALON COMPUTER SYSTEMS, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef _ALPHA_PCI_PCI_A12_H_
|
||||
|
||||
#define PCI_A12_H() /* Generate ctags(1) key */
|
||||
|
||||
void pci_a12_pickintr(struct a12c_config *);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user