Add AlphaServer 2000 (demi-sable), 2100 (sable), and 2100A (lynx) support.

Only PCI and on-board ISA peripherials are supported at this time.

This support has been only lightly tested due to a lack of response to my
call for testers on the freebsd-alpha mailing list.  It works quite well
on the one AS2100 on which it has been tested, but it may not work on
an AS2100A and should therefore be regarded as experimental.
This commit is contained in:
gallatin 2000-05-28 02:52:54 +00:00
parent 3e444e4eaa
commit 71fe923a27
9 changed files with 1086 additions and 2 deletions

View File

@ -116,6 +116,12 @@ extern void dec_1000a_init __P((int));
#define dec_1000a_init platform_not_configured
#endif
#ifdef DEC_2100_A500
extern void dec_2100_a500_init __P((int));
#else
#define dec_2100_a500_init platform_not_configured
#endif
struct cpuinit cpuinit[] = {
cpu_notsupp("???"), /* 0: ??? */
cpu_notsupp("ST_ADU"), /* 1: ST_ADU */
@ -126,7 +132,7 @@ struct cpuinit cpuinit[] = {
cpu_notsupp("ST_DEC_2000_300"), /* 6: ST_DEC_2000_300 */
cpu_init(dec_3000_300_init,"DEC_3000_300"), /* 7: ST_DEC_3000_300 */
cpu_init(avalon_a12_init,"ST_AVALON_A12"), /* 8: ST_AVALON_A12 */
cpu_notsupp("ST_DEC_2100_A500"), /* 9: ST_DEC_2100_A500 */
cpu_init(dec_2100_a500_init, "ST_DEC_2100_A500"), /* 9: ST_DEC_2100_A500 */
cpu_notsupp("ST_DEC_APXVME_64"), /* 10: ST_DEC_APXVME_64 */
cpu_init(dec_axppci_33_init,"DEC_AXPPCI_33"),/* 11: ST_DEC_AXPPCI_33 */
cpu_init(dec_kn8ae_init,"DEC_KN8AE"), /* 12: ST_DEC_21000 */
@ -141,7 +147,7 @@ struct cpuinit cpuinit[] = {
cpu_notsupp("ST_ALPHABOOK1"), /* 21: ST_ALPHABOOK1 */
cpu_init(dec_kn300_init,"DEC_KN300"), /* 22: ST_DEC_4100 */
cpu_notsupp("ST_DEC_EV45_PBP"), /* 23: ST_DEC_EV45_PBP */
cpu_notsupp("ST_DEC_2100A_A500"), /* 24: ST_DEC_2100A_A500 */
cpu_init(dec_2100_a500_init, "ST_DEC_2100A_A500"), /* 24: ST_DEC_2100A_A500 */
cpu_notsupp("???"), /* 25: ??? */
cpu_init(dec_eb164_init,"DEC_EB164"), /* 26: ST_EB164 */
cpu_init(dec_1000a_init,"ST_DEC_1000A"), /* 27: ST_DEC_1000A */

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2000 Andrew Gallatin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <machine/rpb.h>
#include <machine/cpuconf.h>
#include <machine/clock.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <alpha/pci/t2var.h>
#include <alpha/pci/t2reg.h>
#include "sio.h"
#include "sc.h"
#ifndef CONSPEED
#define CONSPEED TTYDEF_SPEED
#endif
static int comcnrate = CONSPEED;
void dec_2100_a500_init __P((int));
static void dec_2100_a500_cons_init __P((void));
static void dec_2100_a500_intr_map __P((void *));
static void dec_2100_a500_intr_init __P((void ));
extern int siocnattach __P((int, int));
extern int siogdbattach __P((int, int));
extern int sccnattach __P((void));
extern vm_offset_t t2_csr_base;
void
dec_2100_a500_init(cputype)
{
/*
* see if we're a Sable or a Lynx
*/
if (cputype == ST_DEC_2100_A500) {
t2_csr_base = SABLE_BASE;
platform.family = "DEC AlphaServer 2100";
} else if (cputype == ST_DEC_2100A_A500) {
t2_csr_base = LYNX_BASE;
platform.family = "DEC AlphaServer 2100A";
} else {
t2_csr_base = SABLE_BASE;
platform.family = "DEC AlphaServer 2100?????";
}
if ((platform.model = alpha_dsr_sysname()) == NULL) {
platform.model = alpha_unknown_sysname();
}
platform.iobus = "t2";
platform.cons_init = dec_2100_a500_cons_init;
platform.pci_intr_map = dec_2100_a500_intr_map;
platform.pci_intr_init = dec_2100_a500_intr_init;
t2_init();
}
extern int comconsole; /* XXX for forcing comconsole when srm serial console is used */
static void
dec_2100_a500_cons_init()
{
struct ctb *ctb;
t2_init();
#ifdef DDB
siogdbattach(0x2f8, 9600);
#endif
ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
switch (ctb->ctb_term_type) {
case 2:
/* serial console ... */
/* XXX */
/*
* Delay to allow PROM putchars to complete.
* FIFO depth * character time,
* character time = (1000000 / (defaultrate / 10))
*/
DELAY(160000000 / comcnrate);
/*
* force a comconsole on com1 if the SRM has a serial console
*/
comconsole = 0;
if (siocnattach(0x3f8, comcnrate))
panic("can't init serial console");
break;
case 3:
/* display console ... */
/* XXX */
#if NSC > 0
sccnattach();
#else
panic("not configured to use display && keyboard console");
#endif
break;
default:
printf("ctb->ctb_term_type = 0x%lx\n", ctb->ctb_term_type);
panic("consinit: unknown console type");
}
}
void
dec_2100_a500_intr_map(void *arg)
{
pcicfgregs *cfg = (pcicfgregs *)arg;
cfg->intline += 32;
}
void
dec_2100_a500_intr_init(void )
{
outb(SLAVE0_ICU, 0);
outb(SLAVE1_ICU, 0);
outb(SLAVE2_ICU, 0);
outb(MASTER_ICU, 0x44);
}

View File

@ -34,6 +34,7 @@ options DEC_AXPPCI_33 # UDB, Multia, AXPpci33, Noname
options DEC_EB164 # EB164, PC164, PC164LX, PC164SX
options DEC_EB64PLUS # EB64+, Aspen Alpine, etc
options DEC_2100_A50 # AlphaStation 200, 250, 255, 400
options DEC_2100_A500 # AlphaServer 2000, 2100, 2100A
options DEC_KN20AA # AlphaStation 500, 600
options DEC_ST550 # Personal Workstation 433, 500, 600
options DEC_ST6600 # xp1000, dp264, ds20, ds10, family

View File

@ -34,6 +34,7 @@ options DEC_AXPPCI_33 # UDB, Multia, AXPpci33, Noname
options DEC_EB164 # EB164, PC164, PC164LX, PC164SX
options DEC_EB64PLUS # EB64+, Aspen Alpine, etc
options DEC_2100_A50 # AlphaStation 200, 250, 255, 400
options DEC_2100_A500 # AlphaServer 2000, 2100, 2100A
options DEC_KN20AA # AlphaStation 500, 600
options DEC_ST550 # Personal Workstation 433, 500, 600
options DEC_ST6600 # xp1000, dp264, ds20, ds10, family

658
sys/alpha/pci/t2.c Normal file
View File

@ -0,0 +1,658 @@
/*
* Copyright (c) 2000 Andrew Gallatin & Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
/*
* T2 CBUS to PCI bridge
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <alpha/pci/t2reg.h>
#include <alpha/pci/t2var.h>
#include <alpha/pci/pcibus.h>
#include <alpha/isa/isavar.h>
#include <machine/intr.h>
#include <machine/resource.h>
#include <machine/intrcnt.h>
#include <machine/cpuconf.h>
#include <machine/swiz.h>
#include <machine/sgmap.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa + t2_csr_base)
vm_offset_t t2_csr_base = 0UL;
static devclass_t t2_devclass;
static device_t t2_0; /* XXX only one for now */
struct t2_softc {
int junk;
};
#define T2_SOFTC(dev) (struct t2_softc*) device_get_softc(dev)
static alpha_chipset_inb_t t2_inb;
static alpha_chipset_inw_t t2_inw;
static alpha_chipset_inl_t t2_inl;
static alpha_chipset_outb_t t2_outb;
static alpha_chipset_outw_t t2_outw;
static alpha_chipset_outl_t t2_outl;
static alpha_chipset_readb_t t2_readb;
static alpha_chipset_readw_t t2_readw;
static alpha_chipset_readl_t t2_readl;
static alpha_chipset_writeb_t t2_writeb;
static alpha_chipset_writew_t t2_writew;
static alpha_chipset_writel_t t2_writel;
static alpha_chipset_maxdevs_t t2_maxdevs;
static alpha_chipset_cfgreadb_t t2_cfgreadb;
static alpha_chipset_cfgreadw_t t2_cfgreadw;
static alpha_chipset_cfgreadl_t t2_cfgreadl;
static alpha_chipset_cfgwriteb_t t2_cfgwriteb;
static alpha_chipset_cfgwritew_t t2_cfgwritew;
static alpha_chipset_cfgwritel_t t2_cfgwritel;
static alpha_chipset_addrcvt_t t2_cvt_dense;
static alpha_chipset_read_hae_t t2_read_hae;
static alpha_chipset_write_hae_t t2_write_hae;
static alpha_chipset_t t2_chipset = {
t2_inb,
t2_inw,
t2_inl,
t2_outb,
t2_outw,
t2_outl,
t2_readb,
t2_readw,
t2_readl,
t2_writeb,
t2_writew,
t2_writel,
t2_maxdevs,
t2_cfgreadb,
t2_cfgreadw,
t2_cfgreadl,
t2_cfgwriteb,
t2_cfgwritew,
t2_cfgwritel,
t2_cvt_dense,
NULL,
t2_read_hae,
t2_write_hae,
};
static u_int8_t
t2_inb(u_int32_t port)
{
alpha_mb();
return SPARSE_READ_BYTE(KV(T2_PCI_SIO), port);
}
static u_int16_t
t2_inw(u_int32_t port)
{
alpha_mb();
return SPARSE_READ_WORD(KV(T2_PCI_SIO), port);
}
static u_int32_t
t2_inl(u_int32_t port)
{
alpha_mb();
return SPARSE_READ_LONG(KV(T2_PCI_SIO), port);
}
static void
t2_outb(u_int32_t port, u_int8_t data)
{
SPARSE_WRITE_BYTE(KV(T2_PCI_SIO), port, data);
alpha_wmb();
}
static void
t2_outw(u_int32_t port, u_int16_t data)
{
SPARSE_WRITE_WORD(KV(T2_PCI_SIO), port, data);
alpha_wmb();
}
static void
t2_outl(u_int32_t port, u_int32_t data)
{
SPARSE_WRITE_LONG(KV(T2_PCI_SIO), port, data);
alpha_wmb();
}
static u_int32_t t2_hae_mem;
#define REG1 (1UL << 24)
static __inline void
t2_set_hae_mem(u_int32_t *pa)
{
int s;
u_int32_t msb;
if(*pa >= REG1){
msb = *pa & 0xf8000000;
*pa -= msb;
msb >>= 27; /* t2 puts high bits in the bottom of the register */
s = splhigh();
if (msb != t2_hae_mem) {
t2_hae_mem = msb;
REGVAL(T2_HAE0_1) = t2_hae_mem;
alpha_mb();
t2_hae_mem = REGVAL(T2_HAE0_1);
}
splx(s);
}
}
static u_int8_t
t2_readb(u_int32_t pa)
{
alpha_mb();
t2_set_hae_mem(&pa);
return SPARSE_READ_BYTE(KV(T2_PCI_SPARSE), pa);
}
static u_int16_t
t2_readw(u_int32_t pa)
{
alpha_mb();
t2_set_hae_mem(&pa);
return SPARSE_READ_WORD(KV(T2_PCI_SPARSE), pa);
}
static u_int32_t
t2_readl(u_int32_t pa)
{
alpha_mb();
t2_set_hae_mem(&pa);
return SPARSE_READ_LONG(KV(T2_PCI_SPARSE), pa);
}
static void
t2_writeb(u_int32_t pa, u_int8_t data)
{
t2_set_hae_mem(&pa);
SPARSE_WRITE_BYTE(KV(T2_PCI_SPARSE), pa, data);
alpha_wmb();
}
static void
t2_writew(u_int32_t pa, u_int16_t data)
{
t2_set_hae_mem(&pa);
SPARSE_WRITE_WORD(KV(T2_PCI_SPARSE), pa, data);
alpha_wmb();
}
static void
t2_writel(u_int32_t pa, u_int32_t data)
{
t2_set_hae_mem(&pa);
SPARSE_WRITE_LONG(KV(T2_PCI_SPARSE), pa, data);
alpha_wmb();
}
static int
t2_maxdevs(u_int b)
{
return 12; /* XXX */
}
/* XXX config space access? */
static vm_offset_t
t2_cvt_dense(vm_offset_t addr)
{
addr &= 0xffffffffUL;
return (addr | T2_PCI_DENSE);
}
static u_int64_t
t2_read_hae(void)
{
return t2_hae_mem << 27;
}
static void
t2_write_hae(u_int64_t hae)
{
u_int32_t pa = hae;
t2_set_hae_mem(&pa);
}
#define T2_CFGOFF(b, s, f, r) \
((b) ? (((b) << 16) | ((s) << 11) | ((f) << 8) | (r)) \
: ((1 << ((s) + 11)) | ((f) << 8) | (r)))
#define T2_TYPE1_SETUP(b,s,old_hae3) if((b)) { \
do { \
(s) = splhigh(); \
(old_hae3) = REGVAL(T2_HAE0_3); \
alpha_mb(); \
REGVAL(T2_HAE0_3) = (old_hae3) | (1<<30); \
alpha_mb(); \
} while(0); \
}
#define T2_TYPE1_TEARDOWN(b,s,old_hae3) if((b)) { \
do { \
alpha_mb(); \
REGVAL(T2_HAE0_3) = (old_hae3); \
alpha_mb(); \
splx((s)); \
} while(0); \
}
#define SWIZ_CFGREAD(b, s, f, r, width, type) \
type val = ~0; \
int ipl = 0; \
u_int32_t old_hae3 = 0; \
vm_offset_t off = T2_CFGOFF(b, s, f, r); \
vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(T2_PCI_CONF), off); \
alpha_mb(); \
T2_TYPE1_SETUP(b,ipl,old_hae3); \
if (!badaddr((caddr_t)kv, sizeof(type))) { \
val = SPARSE_##width##_EXTRACT(off, SPARSE_READ(kv)); \
} \
T2_TYPE1_TEARDOWN(b,ipl,old_hae3); \
return val;
#define SWIZ_CFGWRITE(b, s, f, r, data, width, type) \
int ipl = 0; \
u_int32_t old_hae3 = 0; \
vm_offset_t off = T2_CFGOFF(b, s, f, r); \
vm_offset_t kv = SPARSE_##width##_ADDRESS(KV(T2_PCI_CONF), off); \
alpha_mb(); \
T2_TYPE1_SETUP(b,ipl,old_hae3); \
if (!badaddr((caddr_t)kv, sizeof(type))) { \
SPARSE_WRITE(kv, SPARSE_##width##_INSERT(off, data)); \
alpha_wmb(); \
} \
T2_TYPE1_TEARDOWN(b,ipl,old_hae3); \
return;
static u_int8_t
t2_cfgreadb(u_int h, u_int b, u_int s, u_int f, u_int r)
{
SWIZ_CFGREAD(b, s, f, r, BYTE, u_int8_t);
}
static u_int16_t
t2_cfgreadw(u_int h, u_int b, u_int s, u_int f, u_int r)
{
SWIZ_CFGREAD(b, s, f, r, WORD, u_int16_t);
}
static u_int32_t
t2_cfgreadl(u_int h, u_int b, u_int s, u_int f, u_int r)
{
SWIZ_CFGREAD(b, s, f, r, LONG, u_int32_t);
}
static void
t2_cfgwriteb(u_int h, u_int b, u_int s, u_int f, u_int r, u_int8_t data)
{
SWIZ_CFGWRITE(b, s, f, r, data, BYTE, u_int8_t);
}
static void
t2_cfgwritew(u_int h, u_int b, u_int s, u_int f, u_int r, u_int16_t data)
{
SWIZ_CFGWRITE(b, s, f, r, data, WORD, u_int16_t);
}
static void
t2_cfgwritel(u_int h, u_int b, u_int s, u_int f, u_int r, u_int32_t data)
{
SWIZ_CFGWRITE(b, s, f, r, data, LONG, u_int32_t);
}
static int t2_probe(device_t dev);
static int t2_attach(device_t dev);
static int t2_setup_intr(device_t dev, device_t child,
struct resource *irq, int flags,
void *intr, void *arg, void **cookiep);
static int t2_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie);
static void
t2_dispatch_intr(void *frame, unsigned long vector);
static void
t2_machine_check(unsigned long mces, struct trapframe *framep,
unsigned long vector, unsigned long param);
static device_method_t t2_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, t2_probe),
DEVMETHOD(device_attach, t2_attach),
/* Bus interface */
DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
DEVMETHOD(bus_release_resource, pci_release_resource),
DEVMETHOD(bus_activate_resource, pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
DEVMETHOD(bus_setup_intr, t2_setup_intr),
DEVMETHOD(bus_teardown_intr, t2_teardown_intr),
{ 0, 0 }
};
static driver_t t2_driver = {
"t2",
t2_methods,
sizeof(struct t2_softc),
};
#define T2_SGMAP_BASE (8*1024*1024)
#define T2_SGMAP_SIZE (8*1024*1024)
static void
t2_sgmap_invalidate(void)
{
u_int64_t val;
alpha_mb();
val = REGVAL64(T2_IOCSR);
val |= T2_IOCSRL_ITLB;
REGVAL64(T2_IOCSR) = val;
alpha_mb();
alpha_mb();
val = REGVAL64(T2_IOCSR);
val &= ~T2_IOCSRL_ITLB;
REGVAL64(T2_IOCSR) = val;
alpha_mb();
alpha_mb();
}
static void
t2_sgmap_map(void *arg, vm_offset_t ba, vm_offset_t pa)
{
u_int64_t *sgtable = arg;
int index = alpha_btop(ba - T2_SGMAP_BASE);
if (pa) {
if (pa > (1L<<32))
panic("t2_sgmap_map: can't map address 0x%lx", pa);
sgtable[index] = ((pa >> 13) << 1) | 1;
} else {
sgtable[index] = 0;
}
alpha_mb();
t2_sgmap_invalidate();
}
static void
t2_init_sgmap(void)
{
void *sgtable;
/*
* First setup Window 2 to map 8Mb to 16Mb with an
* sgmap. Allocate the map aligned to a 32 boundary.
*
* bits 31..20 of WBASE represent the pci start address
* (in units of 1Mb), and bits 11..0 represent the pci
* end address
*/
REGVAL(T2_WBASE2) = T2_WSIZE_8M|T2_WINDOW_ENABLE|T2_WINDOW_SG
| ((T2_SGMAP_BASE >> 20) << 20)
| ((T2_SGMAP_BASE + T2_SGMAP_SIZE) >> 20);
REGVAL(T2_WMASK2) = T2_WMASK_8M;
alpha_mb();
sgtable = contigmalloc(8192, M_DEVBUF, M_NOWAIT,
0, (1L<<34),
32*1024, (1L<<34));
if (!sgtable)
panic("t2_init_sgmap: can't allocate page table");
REGVAL(T2_TBASE2) =
(pmap_kextract((vm_offset_t) sgtable) >> T2_TBASE_SHIFT);
chipset.sgmap = sgmap_map_create(T2_SGMAP_BASE,
T2_SGMAP_BASE + T2_SGMAP_SIZE,
t2_sgmap_map, sgtable);
}
/*
* Perform basic chipset init/fixup. Called by various early
* consumers to ensure that the system will work before the
* bus methods are invoked.
*
*/
void
t2_init()
{
static int initted = 0;
if (initted) return;
initted = 1;
chipset = t2_chipset;
}
static int
t2_probe(device_t dev)
{
device_t child;
if (t2_0)
return ENXIO;
t2_0 = dev;
device_set_desc(dev, "T2 Core Logic chipset");
pci_init_resources();
/*
* initialize the DMA windows
*/
REGVAL(T2_WBASE1) = T2_WSIZE_1G|T2_WINDOW_ENABLE|T2_WINDOW_DIRECT|0x7ff;
REGVAL(T2_WMASK1) = T2_WMASK_1G;
REGVAL(T2_TBASE1) = 0;
REGVAL(T2_WBASE2) = 0x0;
/*
* enable the PCI "Hole" for ISA devices which use memory in
* the 512k - 1MB range
*/
REGVAL(T2_HBASE) = 1 << 13;
t2_init_sgmap();
/* initialize the HAEs */
REGVAL(T2_HAE0_1) = 0x0;
alpha_mb();
REGVAL(T2_HAE0_2) = 0x0;
alpha_mb();
REGVAL(T2_HAE0_3) = 0x0;
alpha_mb();
child = device_add_child(dev, "pcib", 0);
device_set_ivars(child, 0);
return 0;
}
static int
t2_attach(device_t dev)
{
t2_init();
platform.mcheck_handler = t2_machine_check;
set_iointr(t2_dispatch_intr);
platform.isa_setup_intr = t2_setup_intr;
platform.isa_teardown_intr = t2_teardown_intr;
snprintf(chipset_type, sizeof(chipset_type), "t2");
bus_generic_attach(dev);
return 0;
}
/*
* magical mystery table partly obtained from Linux
* at least some of their values for PCI masks
* were incorrect, and I've filled in my own extrapolations
* XXX this needs more testers
*/
unsigned long t2_shadow_mask = -1L;
static const char irq_to_mask[40] = {
-1, 6, -1, 8, 15, 12, 7, 9, /* ISA 0-7 */
-1, 16, 17, 18, 3, -1, 21, 22, /* ISA 8-15 */
-1, -1, -1, -1, -1, -1, -1, -1, /* ?? EISA XXX */
-1, -1, -1, -1, -1, -1, -1, -1, /* ?? EISA XXX */
0, 1, 2, 3, 4, 5, 6, 7 /* PCI 0-7 XXX */
};
static int
t2_setup_intr(device_t dev, device_t child,
struct resource *irq, int flags,
void *intr, void *arg, void **cookiep)
{
int error, mask, vector;
mask = irq_to_mask[irq->r_start];
vector = 0x800 + (mask << 4);
error = rman_activate_resource(irq);
if (error)
return error;
error = alpha_setup_intr(vector,
intr, arg, cookiep,
&intrcnt[irq->r_start]);
if (error)
return error;
/* Enable interrupt */
t2_shadow_mask &= ~(1UL << mask);
if (mask <= 7)
outb(SLAVE0_ICU, t2_shadow_mask);
else if (mask <= 15)
outb(SLAVE1_ICU, t2_shadow_mask >> 8);
else
outb(SLAVE2_ICU, t2_shadow_mask >> 16);
device_printf(child, "interrupting at T2 irq %d\n",
(int) irq->r_start);
return 0;
}
static int
t2_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie)
{
int mask;
mask = irq_to_mask[irq->r_start];
/* Disable interrupt */
t2_shadow_mask |= (1UL << mask);
if (mask <= 7)
outb(SLAVE0_ICU, t2_shadow_mask);
else if (mask <= 15)
outb(SLAVE1_ICU, t2_shadow_mask >> 8);
else
outb(SLAVE2_ICU, t2_shadow_mask >> 16);
alpha_teardown_intr(cookie);
return rman_deactivate_resource(irq);
}
static void
t2_ack_intr(unsigned long vector)
{
int mask = (vector - 0x800) >> 4;
switch (mask) {
case 0 ... 7:
outb(SLAVE0_ICU-1, (0xe0 | (mask)));
outb(MASTER_ICU-1, (0xe0 | 1));
break;
case 8 ... 15:
outb(SLAVE1_ICU-1, (0xe0 | (mask - 8)));
outb(MASTER_ICU-1, (0xe0 | 3));
break;
case 16 ... 24:
outb(SLAVE2_ICU-1, (0xe0 | (mask - 16)));
outb(MASTER_ICU-1, (0xe0 | 4));
break;
}
}
static void
t2_dispatch_intr(void *frame, unsigned long vector)
{
alpha_dispatch_intr(frame, vector);
t2_ack_intr(vector);
}
static void
t2_machine_check(unsigned long mces, struct trapframe *framep,
unsigned long vector, unsigned long param)
{
int expected;
expected = mc_expected;
machine_check(mces, framep, vector, param);
/* for some reason the alpha_pal_wrmces() doesn't clear all
pending machine checks & we may take another */
mc_expected = expected;
}
DRIVER_MODULE(t2, root, t2_driver, t2_devclass, 0, 0);

87
sys/alpha/pci/t2_pci.c Normal file
View File

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2000 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPELCAL, 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.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <pci/pcivar.h>
static devclass_t pcib_devclass;
static int
t2_pcib_probe(device_t dev)
{
device_t child;
device_set_desc(dev, "T2 PCI host bus adapter");
child = device_add_child(dev, "pci", 0);
device_set_ivars(child, 0);
return 0;
}
static int
t2_pcib_read_ivar(device_t dev, device_t child, int which, u_long *result)
{
if (which == PCIB_IVAR_HOSE) {
*result = 0;
return 0;
}
return ENOENT;
}
static device_method_t t2_pcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, t2_pcib_probe),
DEVMETHOD(device_attach, bus_generic_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, t2_pcib_read_ivar),
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
{ 0, 0 }
};
static driver_t t2_pcib_driver = {
"pcib",
t2_pcib_methods,
1,
};
DRIVER_MODULE(pcib, t2, t2_pcib_driver, pcib_devclass, 0, 0);

172
sys/alpha/pci/t2reg.h Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 2000 Doug Rabson & Andrew Gallatin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
/*
* Registers in the T2 CBUS-to-PCI bridge as used in the SABLE
* systems.
*/
#define REGVAL(r) (*(volatile int32_t *) \
ALPHA_PHYS_TO_K0SEG(r + t2_csr_base))
#define REGVAL64(r) (*(volatile int64_t *) \
ALPHA_PHYS_TO_K0SEG(r + t2_csr_base))
#define SABLE_BASE 0x0UL /* offset of SABLE CSRs */
#define LYNX_BASE 0x8000000000UL /* offset of LYNX CSRs */
#define CBUS_BASE 0x380000000 /* CBUS CSRs */
#define T2_PCI_SIO 0x3a0000000 /* PCI sparse I/O space */
#define T2_PCI_CONF 0x390000000 /* PCI configuration space */
#define T2_PCI_SPARSE 0x200000000 /* PCI sparse memory space */
#define T2_PCI_DENSE 0x3c0000000 /* PCI dense memory space */
#define T2_IOCSR (CBUS_BASE + 0xe000000)
/* Low word */
#define T2_IOCSRL_EL 0x00000002UL /* loopback enable */
#define T2_IOCSRL_ESMV 0x00000004UL /* enable state machine visibility */
#define T2_IOCSRL_PDBP 0x00000008UL /* PCI drive bad parity */
#define T2_IOCSRL_SLOT0 0x00000030UL /* PCI slot 0 present bits */
#define T2_IOCSRL_PINT 0x00000040UL /* PCI interrupt */
#define T2_IOCSRL_ENTLBEC 0x00000080UL /* enable TLB error check */
#define T2_IOCSRL_ENCCDMA 0x00000100UL /* enable CXACK for DMA */
#define T2_IOCSRL_ENXXCHG 0x00000400UL /* enable exclusive exchange for EV5 */
#define T2_IOCSRL_CAWWP0 0x00001000UL /* CBUS command/address write wrong parity 0 */
#define T2_IOCSRL_CAWWP2 0x00002000UL /* CBUS command/address write wrong parity 2 */
#define T2_IOCSRL_CDWWPE 0x00004000UL /* CBUS data write wrong parity even */
#define T2_IOCSRL_SLOT2 0x00008000UL /* PCI slot 2 present bit */
#define T2_IOCSRL_PSERR 0x00010000UL /* power supply error */
#define T2_IOCSRL_MBA7 0x00020000UL /* MBA7 asserted */
#define T2_IOCSRL_SLOT1 0x000c0000UL /* PCI slot 1 present bits */
#define T2_IOCSRL_PDWWP1 0x00100000UL /* PCI DMA write wrong parity HW1 */
#define T2_IOCSRL_PDWWP0 0x00200000UL /* PCI DMA write wrong parity HW0 */
#define T2_IOCSRL_PBR 0x00400000UL /* PCI bus reset */
#define T2_IOCSRL_PIR 0x00800000UL /* PCI interface reset */
#define T2_IOCSRL_ENCOI 0x01000000UL /* enable NOACK, CUCERR and out-of-sync int */
#define T2_IOCSRL_EPMS 0x02000000UL /* enable PCI memory space */
#define T2_IOCSRL_ETLB 0x04000000UL /* enable TLB */
#define T2_IOCSRL_EACC 0x08000000UL /* enable atomic CBUS cycles */
#define T2_IOCSRL_ITLB 0x10000000UL /* flush TLB */
#define T2_IOCSRL_ECPC 0x20000000UL /* enable CBUS parity check */
#define T2_IOCSRL_CIR 0x40000000UL /* CBUS interface reset */
#define T2_IOCSRL_EPL 0x80000000UL /* enable PCI lock */
/* High word */
#define T2_IOCSRH_CBBCE 0x00000001UL /* CBUS back-to-back cycle enable */
#define T2_IOCSRH_TM 0x0000000eUL /* T2 revision number */
#define T2_IOCSRH_SMVL 0x00000070UL /* state machine visibility select */
#define T2_IOCSRH_SLOT2 0x00000080UL /* PCI slot 2 present bit */
#define T2_IOCSRH_EPR 0x00000100UL /* enable passive release */
#define T2_IOCSRH_CAWWP1 0x00001000UL /* cbus command/address write wrong parity 1 */
#define T2_IOCSRH_CAWWP3 0x00002000UL /* cbus command/address write wrong parity 3 */
#define T2_IOCSRH_DWWPO 0x00004000UL /* CBUS data write wrong parity odd */
#define T2_IOCSRH_PRM 0x00100000UL /* PCI read multiple */
#define T2_IOCSRH_PWM 0x00200000UL /* PCI write multiple */
#define T2_IOCSRH_FPRDPED 0x00400000UL /* force PCI RDPE detect */
#define T2_IOCSRH_PFAPED 0x00800000UL /* force PCI APE detect */
#define T2_IOCSRH_FPWDPED 0x01000000UL /* force PCI WDPE detect */
#define T2_IOCSRH_EPNMI 0x02000000UL /* enable PCI NMI */
#define T2_IOCSRH_EPDTI 0x04000000UL /* enable PCI DTI */
#define T2_IOCSRH_EPSEI 0x08000000UL /* enable PCI SERR interrupt */
#define T2_IOCSRH_EPPEI 0x10000000UL /* enable PCI PERR interrupt */
#define T2_IOCSRH_ERDPC 0x20000000UL /* enable PCI RDP interrupt */
#define T2_IOCSRH_EADPC 0x40000000UL /* enable PCI AP interrupt */
#define T2_IOCSRH_EWDPC 0x80000000UL /* enable PCI WDP interrupt */
#define T2_CERR1 (CBUS_BASE + 0xe000020)
#define T2_CERR2 (CBUS_BASE + 0xe000040)
#define T2_CERR3 (CBUS_BASE + 0xe000060)
#define T2_PERR1 (CBUS_BASE + 0xe000080)
#define T2_PERR1_PWDPE 0x00000001 /* PCI write data parity error */
#define T2_PERR1_PAPE 0x00000002 /* PCI address parity error */
#define T2_PERR1_PRDPE 0x00000004 /* PCI read data parity error */
#define T2_PERR1_PPE 0x00000008 /* PCI parity error */
#define T2_PERR1_PSE 0x00000010 /* PCI system error */
#define T2_PERR1_PDTE 0x00000020 /* PCI device timeout error */
#define T2_PERR1_NMI 0x00000040 /* PCI NMI */
#define T2_PERR2 (CBUS_BASE + 0xe0000a0)
#define T2_PSCR (CBUS_BASE + 0xe0000c0)
#define T2_HAE0_1 (CBUS_BASE + 0xe0000e0)
#define T2_HAE0_2 (CBUS_BASE + 0xe000100)
#define T2_HBASE (CBUS_BASE + 0xe000120)
#define T2_WBASE1 (CBUS_BASE + 0xe000140)
#define T2_WMASK1 (CBUS_BASE + 0xe000160)
#define T2_TBASE1 (CBUS_BASE + 0xe000180)
#define T2_WBASE2 (CBUS_BASE + 0xe0001a0)
#define T2_WMASK2 (CBUS_BASE + 0xe0001c0)
#define T2_TBASE2 (CBUS_BASE + 0xe0001e0)
#define T2_TLBBR (CBUS_BASE + 0xe000200)
#define T2_HAE0_3 (CBUS_BASE + 0xe000240)
#define T2_HAE0_4 (CBUS_BASE + 0xe000280)
/*
* DMA window constants, section 5.2.1.1.1 of the
* Sable I/O Specification
*/
#define T2_WINDOW_ENABLE 0x00080000
#define T2_WINDOW_DISABLE 0x00000000
#define T2_WINDOW_SG 0x00040000
#define T2_WINDOW_DIRECT 0x00000000
#define T2_WMASK_2G 0x7ff00000
#define T2_WMASK_1G 0x3ff00000
#define T2_WMASK_512M 0x1ff00000
#define T2_WMASK_256M 0x0ff00000
#define T2_WMASK_128M 0x07f00000
#define T2_WMASK_64M 0x03f00000
#define T2_WMASK_32M 0x01f00000
#define T2_WMASK_16M 0x00f00000
#define T2_WMASK_8M 0x00700000
#define T2_WMASK_4M 0x00300000
#define T2_WMASK_2M 0x00100000
#define T2_WMASK_1M 0x00000000
#define T2_WSIZE_2G 0x80000000
#define T2_WSIZE_1G 0x40000000
#define T2_WSIZE_512M 0x20000000
#define T2_WSIZE_256M 0x10000000
#define T2_WSIZE_128M 0x08000000
#define T2_WSIZE_64M 0x04000000
#define T2_WSIZE_32M 0x02000000
#define T2_WSIZE_16M 0x01000000
#define T2_WSIZE_8M 0x00800000
#define T2_WSIZE_4M 0x00400000
#define T2_WSIZE_2M 0x00200000
#define T2_WSIZE_1M 0x00100000
#define T2_WSIZE_0M 0x00000000
#define T2_TBASE_SHIFT 1
#define MASTER_ICU 0x535
#define SLAVE0_ICU 0x537
#define SLAVE1_ICU 0x53b
#define SLAVE2_ICU 0x53d
#define SLAVE3_ICU 0x53f

View File

@ -33,6 +33,7 @@ alpha/alpha/dec_kn20aa.c optional dec_kn20aa
alpha/alpha/dec_1000a.c optional dec_1000a
alpha/alpha/dec_1000a.c optional dec_1000a
alpha/alpha/dec_2100_a50.c optional dec_2100_a50
alpha/alpha/dec_2100_a500.c optional dec_2100_a500
alpha/alpha/dec_st550.c optional dec_st550
alpha/alpha/dec_st6600.c optional dec_st6600
alpha/alpha/dec_axppci_33.c optional dec_axppci_33
@ -136,6 +137,8 @@ alpha/pci/pci_eb164_intr.s optional dec_st550
alpha/pci/pci_eb64plus_intr.s optional dec_2100_a50
alpha/pci/pci_eb64plus_intr.s optional dec_eb64plus
alpha/pci/pcibus.c optional pci
alpha/pci/t2.c optional dec_2100_a500
alpha/pci/t2_pci.c optional dec_2100_a500
alpha/pci/tsunami.c optional dec_st6600
alpha/pci/tsunami_pci.c optional dec_st6600
dev/advansys/adv_isa.c optional adv isa

View File

@ -8,6 +8,7 @@ DEC_EB164 opt_cpu.h
DEC_EB64PLUS opt_cpu.h
DEC_KN20AA opt_cpu.h
DEC_2100_A50 opt_cpu.h
DEC_2100_A500 opt_cpu.h
DEC_ST550 opt_cpu.h
DEC_ST6600 opt_cpu.h
DEC_AXPPCI_33 opt_cpu.h