diff options
author | Per Fogelstrom <pefo@cvs.openbsd.org> | 1998-03-16 09:38:53 +0000 |
---|---|---|
committer | Per Fogelstrom <pefo@cvs.openbsd.org> | 1998-03-16 09:38:53 +0000 |
commit | a963ca51673d0d081904efce31dd28f05d83e730 (patch) | |
tree | f51de935de8777cae9204bbaa29b11aa7007425d /sys/arch/arc/pci | |
parent | c1aa08ed9b8f4b392adef8685e4f55ff3b189dbb (diff) |
DDB.
Support for Algorithmics R5000/R10000 evaluation board. So far only the
RM5260 is supported. RM5270 - RM7000 later. R5000 and R10000 depending
on access to cpu modules.
vm_machdep.c moved to arch/mips/mips.
Diffstat (limited to 'sys/arch/arc/pci')
-rw-r--r-- | sys/arch/arc/pci/pbcpcibus.c | 189 | ||||
-rw-r--r-- | sys/arch/arc/pci/pci_machdep.h | 9 | ||||
-rw-r--r-- | sys/arch/arc/pci/v962pcbreg.h | 27 |
3 files changed, 184 insertions, 41 deletions
diff --git a/sys/arch/arc/pci/pbcpcibus.c b/sys/arch/arc/pci/pbcpcibus.c index d3055a1dae2..d084dc427bc 100644 --- a/sys/arch/arc/pci/pbcpcibus.c +++ b/sys/arch/arc/pci/pbcpcibus.c @@ -1,7 +1,7 @@ -/* $OpenBSD: pbcpcibus.c,v 1.5 1998/01/29 14:54:55 pefo Exp $ */ +/* $OpenBSD: pbcpcibus.c,v 1.6 1998/03/16 09:38:48 pefo Exp $ */ /* - * Copyright (c) 1997 Per Fogelstrom + * Copyright (c) 1997, 1998 Per Fogelstrom, Opsycon AB * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -14,7 +14,7 @@ * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed under OpenBSD by - * Per Fogelstrom. + * Per Fogelstrom, Opsycon AB. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * @@ -51,7 +51,7 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> -#include <arc/arc/arctype.h> +#include <mips/archtype.h> #include <arc/algor/algor.h> #include <arc/pci/pcibrvar.h> #include <arc/pci/v962pcbreg.h> @@ -85,9 +85,27 @@ struct cfdriver pbcpcibr_cd = { NULL, "pbcpcibr", DV_DULL, }; +/* + * Code from "pci/if_de.c" used to calculate crc32 of ether rom data. + * Another example can be found in document EC-QPQWA-TE from DEC. + */ +#define TULIP_CRC32_POLY 0xEDB88320UL +static __inline__ unsigned +srom_crc32( + const unsigned char *databuf, + size_t datalen) +{ + u_int idx, bit, data, crc = 0xFFFFFFFFUL; + + for (idx = 0; idx < datalen; idx++) + for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0); + return crc; +} static int pbcpcibrprint __P((void *, const char *pnp)); struct pcibr_config pbc_config; +static int pbc_version; int pbcpcibrmatch(parent, match, aux) @@ -114,6 +132,7 @@ pbcpcibrattach(parent, self, aux) switch(system_type) { case ALGOR_P4032: + case ALGOR_P5064: V96X_PCI_BASE0 = V96X_PCI_BASE0 & 0xffff0000; lcp = sc->sc_pcibr = &pbc_config; @@ -132,6 +151,7 @@ pbcpcibrattach(parent, self, aux) lcp->lc_pc.pc_conf_read = pbc_conf_read; lcp->lc_pc.pc_conf_write = pbc_conf_write; lcp->lc_pc.pc_ether_hw_addr = pbc_ether_hw_addr; + lcp->lc_pc.pc_flush_cache = R4K_HitFlushDCache; lcp->lc_pc.pc_intr_v = lcp; lcp->lc_pc.pc_intr_map = pbc_intr_map; @@ -139,7 +159,8 @@ pbcpcibrattach(parent, self, aux) lcp->lc_pc.pc_intr_establish = pbc_intr_establish; lcp->lc_pc.pc_intr_disestablish = pbc_intr_disestablish; - printf(": V3 V962, Revision %x.\n", V96X_PCI_CC_REV); + pbc_version = V96X_PCI_CC_REV; + printf(": V3 V962, Revision %x.\n", pbc_version); break; } @@ -170,13 +191,14 @@ pbcpcibrprint(aux, pnp) */ vm_offset_t -vtophys(p) - void *p; +vtophysaddr(dp, p) + struct device *dp; + vm_offset_t p; { vm_offset_t pa; vm_offset_t va; - va = (vm_offset_t)p; + va = p; if(va >= UADDR) { /* Stupid driver have buf on stack!! */ va = (vm_offset_t)curproc->p_addr + (va & ~UADDR); } @@ -186,6 +208,10 @@ vtophys(p) else { pa = pmap_extract(vm_map_pmap(phys_map), va); } + if(dp->dv_class == DV_IFNET && pbc_version < V96X_VREV_C0) { + /* BUG in early V962PBC's */ + pa |= 0xc0000000; /* Use aparture II */ + } return(pa); } @@ -219,7 +245,7 @@ pbc_decompose_tag(cpv, tag, busp, devp, fncp) int *busp, *devp, *fncp; { if (busp != NULL) - *busp = (tag >> 16) & 0xff; + *busp = (tag >> 16) & 0x7; if (devp != NULL) *devp = (tag >> 11) & 0x1f; if (fncp != NULL) @@ -234,26 +260,50 @@ pbc_conf_read(cpv, tag, offset) { pcireg_t data; u_int32_t addr; - int device; + int bus, device, func, ad_low; int s; - if((tag >> 16) != 0) - return(~0); if(offset & 3 || offset < 0 || offset >= 0x100) { printf ("pci_conf_read: bad reg %x\n", offset); return(~0); } + pbc_decompose_tag(cpv, tag, &bus, &device, &func); + ad_low = 0; - device = (tag >> 11) & 0x1f; - addr = (0x800 << device) | (tag & 0x380) | offset; + if(system_type == ALGOR_P4032) { + if(bus != 0 || device > 5 || func > 7) { + return(~0); + } + addr = (0x800 << device) | (func << 8) | offset; + ad_low = 0; + } + else { /* P5064 */ + if(bus == 0) { + if(device > 5 || func > 7) { + return(~0); + } + addr = (1L << (device + 24)) | (func << 8) | offset; + ad_low = 0; + } + else if(pbc_version >= V96X_VREV_C0) { + if(bus > 255 || device > 15 || func > 7) { + return(~0); + } + addr = (bus << 16) | (device << 11) | (func << 8); + ad_low = V96X_LB_MAPx_AD_LOW_EN; + } + else { + return(~0); + } + } s = splhigh(); + /* high 12 bits of address go in map register, and set for conf space */ + V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR) | ad_low | V96X_LB_TYPE_CONF; /* clear aborts */ V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT | V96X_PCI_STAT_T_ABORT; - /* high 12 bits of address go in map register, and set for conf space */ - V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR) | V96X_LB_TYPE_CONF; wbflush(); /* low 20 bits of address are in the actual address */ @@ -261,14 +311,13 @@ pbc_conf_read(cpv, tag, offset) if (V96X_PCI_STAT & V96X_PCI_STAT_M_ABORT) { V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT; - printf ("device %d: master abort\n", device); - return(~0); + return(~0); /* Nothing there */ } if (V96X_PCI_STAT & V96X_PCI_STAT_T_ABORT) { V96X_PCI_STAT |= V96X_PCI_STAT_T_ABORT; printf ("PCI slot %d: target abort!\n", device); - return(~0); + return(~0); /* Ooops! */ } splx(s); @@ -283,19 +332,46 @@ pbc_conf_write(cpv, tag, offset, data) pcireg_t data; { u_int32_t addr; - int device; + int bus, device, func, ad_low; int s; - device = (tag >> 11) & 0x1f; - addr = (0x800 << device) | (tag & 0x380) | offset; + pbc_decompose_tag(cpv, tag, &bus, &device, &func); + ad_low = 0; + + if(system_type == ALGOR_P4032) { + if(bus != 0 || device > 5 || func > 7) { + return; + } + addr = (0x800 << device) | (func << 8) | offset; + ad_low = 0; + } + else { /* P5064 */ + if(bus == 0) { + if(device > 5 || func > 7) { + return; + } + addr = (1L << (device + 24)) | (func << 8) | offset; + ad_low = 0; + } + else if(pbc_version >= V96X_VREV_C0) { + if(bus > 255 || device > 15 || func > 7) { + return; + } + addr = (bus << 16) | (device << 11) | (func << 8); + ad_low = V96X_LB_MAPx_AD_LOW_EN; + } + else { + return; + } + } s = splhigh(); + /* high 12 bits of address go in map register, and set for conf space */ + V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR) | ad_low | V96X_LB_TYPE_CONF; /* clear aborts */ V96X_PCI_STAT |= V96X_PCI_STAT_M_ABORT | V96X_PCI_STAT_T_ABORT; - /* high 12 bits of address go in map register, and set for conf space */ - V96X_LB_MAP0 = ((addr >> 16) & V96X_LB_MAPx_MAP_ADR) | V96X_LB_TYPE_CONF; wbflush(); /* low 20 bits of address are in the actual address */ @@ -319,17 +395,60 @@ pbc_conf_write(cpv, tag, offset, data) } /* - * Hook to get ethernet hardware address when not in dev rom + * Build the serial rom info normaly stored in an EEROM on + * PCI DEC21x4x boards. Cheapo designs skips the rom so + * we do the job here. The setup is not 100% correct but + * close enough to make the driver happy! */ int -pbc_ether_hw_addr(cp) - u_int8_t *cp; +pbc_ether_hw_addr(p) + u_int8_t *p; { - if(system_type == ALGOR_P4032) { - bcopy(eth_hw_addr, cp, 6); - return(0); + int i; + + for(i = 0; i < 128; i++) + p[i] = 0x00; + p[18] = 0x03; /* Srom version. */ + p[19] = 0x01; /* One chip. */ + /* Next six, ethernet address. */ + bcopy(eth_hw_addr, &p[20], 6); + + p[26] = 0x00; /* Chip 0 device number */ + p[27] = 30; /* Descriptor offset */ + p[28] = 00; + p[29] = 00; /* MBZ */ + /* Descriptor */ + p[30] = 0x00; /* Autosense. */ + p[31] = 0x08; + if(system_type == ALGOR_P4032 || + system_type == ALGOR_P5064) { + p[32] = 0x01; /* Block cnt */ + p[33] = 0x02; /* Medium type is AUI */ + } + else { + p[32] = 0xff; /* GP cntrl */ + p[33] = 0x01; /* Block cnt */ +#define GPR_LEN 0 +#define RES_LEN 0 + p[34] = 0x80 + 12 + GPR_LEN + RES_LEN; + p[35] = 0x01; /* MII PHY type */ + p[36] = 0x00; /* PHY number 0 */ + p[37] = 0x00; /* GPR Length */ + p[38] = 0x00; /* Reset Length */ + p[39] = 0x00; /* Media capabilities */ + p[40] = 0x78; /* Media capabilities */ + p[41] = 0x00; /* Autoneg advertisment */ + p[42] = 0x78; /* Autoneg advertisment */ + p[43] = 0x00; /* Full duplex map */ + p[44] = 0x50; /* Full duplex map */ + p[45] = 0x00; /* Treshold map */ + p[46] = 0x18; /* Treshold map */ } - return(-1); + + i = (srom_crc32(p, 126) & 0xFFFF) ^ 0xFFFF; + p[126] = i; + p[127] = i >> 8; + return(1); /* Got it! */ } int @@ -358,11 +477,11 @@ pbc_intr_map(lcv, bustag, buspin, line, ihp) pirq = buspin - 1; switch(device) { - case 5: /* DC21041 */ - pirq = 1; + case 0: /* DC21041 */ + pirq = 9; break; - case 8: /* NCR SCSI */ - pirq = 0; + case 1: /* NCR SCSI */ + pirq = 10; break; default: switch (buspin) { diff --git a/sys/arch/arc/pci/pci_machdep.h b/sys/arch/arc/pci/pci_machdep.h index 5543d2c1f7e..dfeb5995c67 100644 --- a/sys/arch/arc/pci/pci_machdep.h +++ b/sys/arch/arc/pci/pci_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.h,v 1.2 1997/04/19 17:20:02 pefo Exp $ */ +/* $OpenBSD: pci_machdep.h,v 1.3 1998/03/16 09:38:49 pefo Exp $ */ /* * Copyright (c) 1996 Carnegie-Mellon University. @@ -61,6 +61,7 @@ struct arc_pci_chipset { int, int (*)(void *), void *, char *)); void (*pc_intr_disestablish) __P((void *, void *)); int (*pc_ether_hw_addr) __P((u_int8_t *)); + void (*pc_flush_cache) __P((vm_offset_t, int)); }; /* @@ -88,6 +89,10 @@ struct arc_pci_chipset { (*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv)) #define pci_ether_hw_addr(c, p) \ (*(c)->pc_ether_hw_addr)((p)) +#define pci_flush_cache(p, s) \ + (*(c)->pc_flush_cache)((p, s)) -vm_offset_t vtophys __P((void *)); +vm_offset_t vtophysaddr __P((struct device *, vm_offset_t)); +#define TULIP_KVATOPHYS(sc, va) vtophysaddr(&sc->tulip_dev, (vm_offset_t)va) +#define NCR_KVATOPHYS(sc, va) vtophysaddr(&sc->sc_dev, (vm_offset_t)va) diff --git a/sys/arch/arc/pci/v962pcbreg.h b/sys/arch/arc/pci/v962pcbreg.h index e0e4865213b..9320bafee6b 100644 --- a/sys/arch/arc/pci/v962pcbreg.h +++ b/sys/arch/arc/pci/v962pcbreg.h @@ -11,7 +11,7 @@ /* offsets from base pointer, this construct allows optimisation */ static char * const _v96xp = (char *)P4032_V96x; -#if #endian(little) +#if BYTE_ORDER == LITTLE_ENDIAN #define V96XW(x) *(volatile unsigned long *)(_v96xp + (x)) #define V96XH(x) *(volatile unsigned short *)(_v96xp + (x)) #define V96XB(x) *(volatile unsigned char *)(_v96xp + (x)) @@ -26,10 +26,11 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_PCI_CMD V96XH(0x04) #define V96X_PCI_STAT V96XH(0x06) #define V96X_PCI_CC_REV V96XW(0x08) +#define V96X_PCI_I20_BASE V96XW(0x10) /* B.2 only */ #define V96X_PCI_HDR_CFG V96XW(0x0c) #define V96X_PCI_IO_BASE V96XW(0x10) #define V96X_PCI_BASE0 V96XW(0x14) -#define V96X_PCI_BASE1 V96XW(0x1c) +#define V96X_PCI_BASE1 V96XW(0x18) #define V96X_PCI_BPARAM V96XW(0x3c) #define V96X_PCI_MAP0 V96XW(0x40) #define V96X_PCI_MAP1 V96XW(0x44) @@ -39,6 +40,9 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_LB_BASE1 V96XW(0x58) #define V96X_LB_MAP0 V96XH(0x5e) #define V96X_LB_MAP1 V96XH(0x62) +#define V96X_LB_BASE2 V96XH(0x64) /* B.2 only */ +#define V96X_LB_MAP2 V96XH(0x66) /* B.2 only */ +#define V96X_LB_SIZE V96XW(0x68) /* B.2 only */ #define V96X_LB_IO_BASE V96XW(0x6c) #define V96X_FIFO_CFG V96XH(0x70) #define V96X_FIFO_PRIORITY V96XH(0x72) @@ -46,7 +50,9 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_LB_ISTAT V96XB(0x76) #define V96X_LB_IMASK V96XB(0x77) #define V96X_SYSTEM V96XH(0x78) +#define V96X_LB_CFGL V96XB(0x7a) #define V96X_LB_CFG V96XB(0x7b) +#define V96X_PCI_CFG V96XB(0x7c) /* B.2 only */ #define V96X_DMA_PCI_ADDR0 V96XW(0x80) #define V96X_DMA_LOCAL_ADDR0 V96XW(0x84) #define V96X_DMA_LENGTH0 V96XW(0x88) @@ -87,7 +93,8 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_VREV_A 0x0 #define V96X_VREV_B0 0x1 #define V96X_VREV_B1 0x2 -#define V96X_VREV_C0 0x3 +#define V96X_VREV_B2 0x3 +#define V96X_VREV_C0 0x4 #define V96X_PCI_HDR_CFG_LT 0x0000ff00 #define V96X_PCI_HDR_CFG_LT_SHIFT 8 @@ -143,8 +150,9 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_SWAP_NONE (0x0<<8) #define V96X_SWAP_16BIT (0x1<<8) #define V96X_SWAP_8BIT (0x2<<8) +#define V96X_SWAP_AUTO (0x3<<8) -/* pci interruprt status register */ +/* pci interrupt status register */ #define V96X_PCI_INT_STAT_MAILBOX 0x80000000 #define V96X_PCI_INT_STAT_LOCAL 0x40000000 #define V96X_PCI_INT_STAT_DMA1 0x02000000 @@ -210,6 +218,7 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_LB_TYPE_IO (0x1<<1) #define V96X_LB_TYPE_MEM (0x3<<1) #define V96X_LB_TYPE_CONF (0x5<<1) +#define V96X_LB_MAPx_AD_LOW_EN 0x0001 /* C.0 only */ /* local bus interrupt control, status and masks */ #define V96X_LB_INTR_MAILBOX 0x80 @@ -226,6 +235,16 @@ static char * const _v96xp = (char *)P4032_V96x; #define V96X_LB_CFG_ERR_EN 0x02 #define V96X_LB_CFG_RDY_EN 0x01 +/* PCI bus configuration */ +#define V96X_PCI_CFG_I2O_EN 0x8000 +#define V96X_PCI_CFG_IO_REG_DIS 0x4000 +#define V96X_PCI_CFG_IO_DIS 0x2000 +#define V96X_PCI_CFG_EN3V 0x1000 +#define V96X_PCI_CFG_AD_LOW 0x0300 +#define V96X_PCI_CFG_AD_LOW_SHIFT 8 +#define V96X_PCI_CFG_DMA_RTYPE 0x00e0 +#define V96X_PCI_CFG_DMA_WTYPE 0x000e + /* fifo configuration register */ #define V96X_FIFO_CFG_PBRST_MAX 0xc000 #define V96X_FIFO_CFG_PBRST_MAX_SHIFT 14 |