diff options
author | se <se@FreeBSD.org> | 1994-09-16 00:33:29 +0000 |
---|---|---|
committer | se <se@FreeBSD.org> | 1994-09-16 00:33:29 +0000 |
commit | 082fbb1bea5dc2dc72db5f557f1f73f2ca68b029 (patch) | |
tree | 01a2186c4c4b8fddf2525cfc13e0711e6db9b4ab | |
parent | 8faab3c2e8897f64de6b5ad4ca8c176e74e2bded (diff) | |
download | FreeBSD-src-082fbb1bea5dc2dc72db5f557f1f73f2ca68b029.zip FreeBSD-src-082fbb1bea5dc2dc72db5f557f1f73f2ca68b029.tar.gz |
Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> + <se>
Improved bus probing, symbolic names for registers..
Chip set parameters get dumped for intel PCI chip sets
(82424+82434 only, for now).
-rw-r--r-- | sys/dev/pci/pci.c | 257 | ||||
-rw-r--r-- | sys/i386/pci/pci.c | 257 | ||||
-rw-r--r-- | sys/i386/pci/pci.h | 12 | ||||
-rw-r--r-- | sys/i386/pci/pci_config.c | 33 | ||||
-rw-r--r-- | sys/i386/pci/pci_device.h | 35 | ||||
-rw-r--r-- | sys/i386/pci/pci_intel.c | 61 | ||||
-rw-r--r-- | sys/i386/pci/pcibios.c | 20 | ||||
-rw-r--r-- | sys/i386/pci/pcibios.h | 156 | ||||
-rw-r--r-- | sys/pci/pci.c | 257 |
9 files changed, 551 insertions, 537 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 93b2d17..c2f16b8 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.2 1994/09/01 02:01:34 se Exp $ +** $Id: pci.c,v 2.0.0.12 94/09/15 20:49:23 wolf Exp $ ** ** General subroutines for the PCI bus on 80*86 systems. ** pci_configure () @@ -34,53 +34,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci.c,v $ - * Revision 1.2 1994/09/01 02:01:34 se - * Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> - * Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu) - * and support for multiple NCR chips. - * -** Revision 2.0.0.8 94/08/21 19:57:39 wolf -** Unneeded declarations removed (FreeBSD2.0) -** -** Revision 2.0.0.7 94/08/21 19:25:54 wolf -** pci_intr simplified. -** new not_supported() function. -** Vendor and device ids moved into tables. -** -** Revision 2.0.0.6 94/08/18 22:58:23 wolf -** Symbolic names for pci configuration space registers. -** last_device: from configuration mode -** last_bus: from pcibios. -** PCI_MAX_DPI: changed to 4 (settable by config) -** interrupt configuration by line or pin -** -** Revision 2.0.0.5 94/08/11 19:04:10 wolf -** display of interrupt line configuration register. -** -** Revision 2.0.0.4 94/08/01 20:36:28 wolf -** Tiny clean up. -** -** Revision 2.0.0.3 94/08/01 18:52:33 wolf -** New vendor entry: S3. -** Scan pci busses #0..#255 as default. -** Number of scanned busses and devices settable as option. -** Show these numbers before starting the scan. -** -** Revision 2.0.0.2 94/07/27 09:27:19 wolf -** New option PCI_QUIET: suppress log messages. -** -** Revision 2.0.0.1 94/07/19 19:06:44 wolf -** New vendor entry: MATROX -** -** Revision 2.0 94/07/10 15:53:29 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:19 wolf -** Beta release. -** -*************************************************************************** */ #include <pci.h> @@ -126,15 +79,15 @@ char ident_pci_c[] = - "\n$Id: pci.c,v 1.2 1994/09/01 02:01:34 se Exp $\n" - "Copyright (c) 1994, Wolfgang Stanglmeier\n"; + "\n$Id: pci.c,v 2.0.0.12 94/09/15 20:49:23 wolf Exp $\n"; /* ** Function prototypes missing in system headers */ #if ! (__FreeBSD__ >= 2) -extern pmap_t pmap_kernel(void); +extern pmap_t pmap_kernel(void); +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); #endif @@ -146,7 +99,7 @@ extern pmap_t pmap_kernel(void); */ /* -** per device (interrupt) data structure. +** per slot data structure for passing interupts.. */ static struct { @@ -205,7 +158,8 @@ void pciintr (int unit) u_short i; if (unit >= NPCI) return; for (i=0; i<pcidata[unit].number; i++) { - (void)(*pcidata[unit].vector[i].proc)(pcidata[unit].vector[i].unit); + (void)(*pcidata[unit].vector[i].proc) + (pcidata[unit].vector[i].unit); }; } @@ -273,10 +227,8 @@ void pci_configure() */ #ifndef PCI_QUIET - printf ("PCI configuration mode %d.\n", pci_mode); - printf ("Scanning device 0..%d on pci bus 0..%d " - "($Revision: 1.2 $)\n", - last_device, last_bus); + printf ("pci*: mode=%d, scanning bus 0..%d, device 0..%d.\n", + pci_mode, last_bus, last_device); #endif for (bus=0;bus<=last_bus; bus++) @@ -294,37 +246,47 @@ void pci_configure() if (dvp->pd_device_id == type) break; }; drp = dvp->pd_driver; - + if (!dvp->pd_device_id) { - int data = pci_conf_read(tag, PCI_CLASS_REV_REG); - enum pci_majclass class = PCI_MAJCLASS_OF(data); + + /* + ** not found + ** try to dig out some information. + ** + ** By Garrett Wollman + ** <wollman@halloran-eldar.lcs.mit.edu> + */ + + int data = pci_conf_read(tag, PCI_CLASS_REG); vm_offset_t va; vm_offset_t pa; int reg; - switch(class) { - case PCI_MJC_OLD: - if(PCI_MINCLASS_OF(data) != PCI_MIN_OVGA) - break; - case PCI_MJC_DISPLAY: + switch (data & PCI_CLASS_MASK) { + + case PCI_CLASS_PREHISTORIC: + if ((data & PCI_SUBCLASS_MASK) + != PCI_SUBCLASS_PREHISTORIC_VGA) + break; + + case PCI_CLASS_DISPLAY: for (reg = PCI_MAP_REG_START; reg < PCI_MAP_REG_END; reg += 4) { data = pci_map_mem(tag, reg, &va, &pa); - if(data == 0) - printf( -"pci%d:%d: mapped VGA-like device at physaddr %lx\n", - bus, device, (u_long)pa); + if (data == 0) + printf ( + "pci%d:%d: mapped VGA-like device at physaddr 0x%lx\n", + bus, device, (u_long)pa); } continue; - default: + }; #ifndef PCI_QUIET - printf("pci%d:%d: ", bus, device); - not_supported (tag, type); + printf("pci%d:%d: ", bus, device); + not_supported (tag, type); #endif - } - } + }; if (!drp) { if(dvp->pd_flags & PDF_LOADABLE) { @@ -338,20 +300,17 @@ void pci_configure() ** found it. ** probe returns the device unit. */ + unit = (*drp->probe) (tag); if (unit<0) { printf ("%s <%s>: probe failed on pci%d:%d\n", - drp->name, drp->vendor, bus, device); + dvp->pd_name, drp->name, bus, device); continue; }; - if (drp->name) { - printf ("%s%d <%s>", drp->name, unit, drp->vendor); - } else { - printf ("pci%d: <%s>", bus, drp->vendor); - } - + printf ("%s%d <%s>", dvp->pd_name, unit, drp->name); + /* ** install interrupts */ @@ -368,18 +327,26 @@ void pci_configure() isanum = PCI_INTERRUPT_LINE_EXTRACT(data); if (isanum) { - printf (" il=%d", isanum); + + /* + ** @INT@ FIXME!!! + ** + ** Should try to use "register_interupt" + ** at this point. + */ + + printf (" line=%d", isanum); for (idx = 0; idx < NPCI; idx++) { if (pcidata[idx].isanum == isanum) break; - } - } + }; + }; /* - ** Or believe to the interrupt pin register. + ** Or take the device number as index ... */ - if (idx >= NPCI) idx = intpin-1; + if (idx >= NPCI) idx = device; /* ** And install the interrupt. @@ -396,29 +363,32 @@ void pci_configure() printf (" isa=%d [%d]",pcidata[idx].isanum, entry); pcidata[idx].number=entry; } else { - printf (" not installed"); - } - } - + printf (" no int"); + }; + }; + /* ** enable memory access */ + data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) & 0xffff | PCI_COMMAND_MEM_ENABLE; - pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); - printf (" on pci%d:%d\n", bus, device); + pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); /* ** attach device ** may produce additional log messages, ** i.e. when installing subdevices. */ + + printf (" on pci%d:%d\n", bus, device); + (void) (*drp->attach) (tag); } #ifndef PCI_QUIET - printf ("pci uses physical addresses from %lx to %lx\n", + printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", (u_long)PCI_PMEM_START, (u_long)pci_paddr); #endif } @@ -432,8 +402,6 @@ void pci_configure() **----------------------------------------------------------------------- */ -extern vm_map_t kernel_map; - int pci_map_port (pcici_t tag, u_long reg, u_short* pa) { /* @@ -453,7 +421,7 @@ int pci_map_port (pcici_t tag, u_long reg, u_short* pa) int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) { - u_long data, result; + u_long data; vm_size_t vsize; vm_offset_t vaddr; @@ -492,7 +460,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); if (!vsize) return (EINVAL); - + /* ** align physical address to virtual size */ @@ -502,13 +470,15 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vaddr = pmap_mapdev (pci_paddr, vsize); -#if 0 + if (!vaddr) return (EINVAL); + +#ifndef PCI_QUIET /* ** display values. */ - printf (" virtual=0x%lx physical=0x%lx\n", (u_long)vaddr, - (u_long)pci_paddr); + printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", + reg, (u_long)vaddr, (u_long)pci_paddr); #endif /* @@ -524,19 +494,68 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) pci_conf_write (tag, reg, pci_paddr); + /* + ** and don't forget to increment pci_paddr + */ + + pci_paddr += vsize; + return (0); } +/*----------------------------------------------------------- +** +** Mapping of physical to virtual memory +** +**----------------------------------------------------------- +*/ + +#if ! (__FreeBSD__ >= 2) + +extern vm_map_t kernel_map; + +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +{ + vm_offset_t vaddr,value; + u_long result; + + vaddr = vm_map_min (kernel_map); + + result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, + &vaddr, vsize, TRUE); + + if (result != KERN_SUCCESS) { + printf (" vm_map_find failed(%d)\n", result); + return (0); + }; + + /* + ** map physical + */ + + value = vaddr; + while (vsize >= NBPG) { + pmap_enter (pmap_kernel(), vaddr, paddr, + VM_PROT_READ|VM_PROT_WRITE, TRUE); + vaddr += NBPG; + paddr += NBPG; + vsize -= NBPG; + }; + return (value); +} +#endif + +/*----------------------------------------------------------- +** +** Display of unknown devices. +** +**----------------------------------------------------------- +*/ struct vt { u_short ident; char* name; }; -struct dt { - u_long ident; - char* name; -}; - static struct vt VendorTable[] = { {0x1002, "ATI TECHNOLOGIES INC"}, {0x1011, "DIGITAL EQUIPMENT COMPANY"}, @@ -548,17 +567,9 @@ static struct vt VendorTable[] = { {0,0} }; -static struct dt DeviceTable[] = { - {0x04848086, " 82378IB pci-isa bridge"}, - {0x04838086, " 82424ZX cache dram controller"}, - {0x04828086, " 82375EB pci-eisa bridge"}, - {0x04A38086, " 82434LX pci cache memory controller"}, - {0,0} -}; - static const char *const majclasses[] = { - "old", "storage", "network", "display", "multimedia", "memory", - "bridge" + "old", "storage", "network", "display", + "multimedia", "memory", "bridge" }; void not_supported (pcici_t tag, u_long type) @@ -566,7 +577,6 @@ void not_supported (pcici_t tag, u_long type) u_char reg; u_long data; struct vt * vp; - struct dt * dp; /* ** lookup the names. @@ -576,23 +586,18 @@ void not_supported (pcici_t tag, u_long type) if (vp->ident == (type & 0xffff)) break; - for (dp=DeviceTable; dp->ident; dp++) - if (dp->ident == type) - break; - /* ** and display them. */ if (vp->ident) printf (vp->name); - else printf ("vendor=%lx", type & 0xffff); + else printf ("vendor=0x%lx", type & 0xffff); - if (dp->ident) printf (dp->name); - else printf (", device=%lx", type >> 16); + printf (", device=0x%lx", type >> 16); - data = pci_conf_read(tag, PCI_CLASS_REV_REG); - if (PCI_MAJCLASS_OF(data) < sizeof(majclasses) / sizeof(majclasses[0])) - printf(", class=%s", majclasses[PCI_MAJCLASS_OF(data)]); + data = (pci_conf_read(tag, PCI_CLASS_REG) >> 24) & 0xff; + if (data < sizeof(majclasses) / sizeof(majclasses[0])) + printf(", class=%s", majclasses[data]); printf (" [not supported]\n"); diff --git a/sys/i386/pci/pci.c b/sys/i386/pci/pci.c index 93b2d17..c2f16b8 100644 --- a/sys/i386/pci/pci.c +++ b/sys/i386/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.2 1994/09/01 02:01:34 se Exp $ +** $Id: pci.c,v 2.0.0.12 94/09/15 20:49:23 wolf Exp $ ** ** General subroutines for the PCI bus on 80*86 systems. ** pci_configure () @@ -34,53 +34,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci.c,v $ - * Revision 1.2 1994/09/01 02:01:34 se - * Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> - * Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu) - * and support for multiple NCR chips. - * -** Revision 2.0.0.8 94/08/21 19:57:39 wolf -** Unneeded declarations removed (FreeBSD2.0) -** -** Revision 2.0.0.7 94/08/21 19:25:54 wolf -** pci_intr simplified. -** new not_supported() function. -** Vendor and device ids moved into tables. -** -** Revision 2.0.0.6 94/08/18 22:58:23 wolf -** Symbolic names for pci configuration space registers. -** last_device: from configuration mode -** last_bus: from pcibios. -** PCI_MAX_DPI: changed to 4 (settable by config) -** interrupt configuration by line or pin -** -** Revision 2.0.0.5 94/08/11 19:04:10 wolf -** display of interrupt line configuration register. -** -** Revision 2.0.0.4 94/08/01 20:36:28 wolf -** Tiny clean up. -** -** Revision 2.0.0.3 94/08/01 18:52:33 wolf -** New vendor entry: S3. -** Scan pci busses #0..#255 as default. -** Number of scanned busses and devices settable as option. -** Show these numbers before starting the scan. -** -** Revision 2.0.0.2 94/07/27 09:27:19 wolf -** New option PCI_QUIET: suppress log messages. -** -** Revision 2.0.0.1 94/07/19 19:06:44 wolf -** New vendor entry: MATROX -** -** Revision 2.0 94/07/10 15:53:29 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:19 wolf -** Beta release. -** -*************************************************************************** */ #include <pci.h> @@ -126,15 +79,15 @@ char ident_pci_c[] = - "\n$Id: pci.c,v 1.2 1994/09/01 02:01:34 se Exp $\n" - "Copyright (c) 1994, Wolfgang Stanglmeier\n"; + "\n$Id: pci.c,v 2.0.0.12 94/09/15 20:49:23 wolf Exp $\n"; /* ** Function prototypes missing in system headers */ #if ! (__FreeBSD__ >= 2) -extern pmap_t pmap_kernel(void); +extern pmap_t pmap_kernel(void); +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); #endif @@ -146,7 +99,7 @@ extern pmap_t pmap_kernel(void); */ /* -** per device (interrupt) data structure. +** per slot data structure for passing interupts.. */ static struct { @@ -205,7 +158,8 @@ void pciintr (int unit) u_short i; if (unit >= NPCI) return; for (i=0; i<pcidata[unit].number; i++) { - (void)(*pcidata[unit].vector[i].proc)(pcidata[unit].vector[i].unit); + (void)(*pcidata[unit].vector[i].proc) + (pcidata[unit].vector[i].unit); }; } @@ -273,10 +227,8 @@ void pci_configure() */ #ifndef PCI_QUIET - printf ("PCI configuration mode %d.\n", pci_mode); - printf ("Scanning device 0..%d on pci bus 0..%d " - "($Revision: 1.2 $)\n", - last_device, last_bus); + printf ("pci*: mode=%d, scanning bus 0..%d, device 0..%d.\n", + pci_mode, last_bus, last_device); #endif for (bus=0;bus<=last_bus; bus++) @@ -294,37 +246,47 @@ void pci_configure() if (dvp->pd_device_id == type) break; }; drp = dvp->pd_driver; - + if (!dvp->pd_device_id) { - int data = pci_conf_read(tag, PCI_CLASS_REV_REG); - enum pci_majclass class = PCI_MAJCLASS_OF(data); + + /* + ** not found + ** try to dig out some information. + ** + ** By Garrett Wollman + ** <wollman@halloran-eldar.lcs.mit.edu> + */ + + int data = pci_conf_read(tag, PCI_CLASS_REG); vm_offset_t va; vm_offset_t pa; int reg; - switch(class) { - case PCI_MJC_OLD: - if(PCI_MINCLASS_OF(data) != PCI_MIN_OVGA) - break; - case PCI_MJC_DISPLAY: + switch (data & PCI_CLASS_MASK) { + + case PCI_CLASS_PREHISTORIC: + if ((data & PCI_SUBCLASS_MASK) + != PCI_SUBCLASS_PREHISTORIC_VGA) + break; + + case PCI_CLASS_DISPLAY: for (reg = PCI_MAP_REG_START; reg < PCI_MAP_REG_END; reg += 4) { data = pci_map_mem(tag, reg, &va, &pa); - if(data == 0) - printf( -"pci%d:%d: mapped VGA-like device at physaddr %lx\n", - bus, device, (u_long)pa); + if (data == 0) + printf ( + "pci%d:%d: mapped VGA-like device at physaddr 0x%lx\n", + bus, device, (u_long)pa); } continue; - default: + }; #ifndef PCI_QUIET - printf("pci%d:%d: ", bus, device); - not_supported (tag, type); + printf("pci%d:%d: ", bus, device); + not_supported (tag, type); #endif - } - } + }; if (!drp) { if(dvp->pd_flags & PDF_LOADABLE) { @@ -338,20 +300,17 @@ void pci_configure() ** found it. ** probe returns the device unit. */ + unit = (*drp->probe) (tag); if (unit<0) { printf ("%s <%s>: probe failed on pci%d:%d\n", - drp->name, drp->vendor, bus, device); + dvp->pd_name, drp->name, bus, device); continue; }; - if (drp->name) { - printf ("%s%d <%s>", drp->name, unit, drp->vendor); - } else { - printf ("pci%d: <%s>", bus, drp->vendor); - } - + printf ("%s%d <%s>", dvp->pd_name, unit, drp->name); + /* ** install interrupts */ @@ -368,18 +327,26 @@ void pci_configure() isanum = PCI_INTERRUPT_LINE_EXTRACT(data); if (isanum) { - printf (" il=%d", isanum); + + /* + ** @INT@ FIXME!!! + ** + ** Should try to use "register_interupt" + ** at this point. + */ + + printf (" line=%d", isanum); for (idx = 0; idx < NPCI; idx++) { if (pcidata[idx].isanum == isanum) break; - } - } + }; + }; /* - ** Or believe to the interrupt pin register. + ** Or take the device number as index ... */ - if (idx >= NPCI) idx = intpin-1; + if (idx >= NPCI) idx = device; /* ** And install the interrupt. @@ -396,29 +363,32 @@ void pci_configure() printf (" isa=%d [%d]",pcidata[idx].isanum, entry); pcidata[idx].number=entry; } else { - printf (" not installed"); - } - } - + printf (" no int"); + }; + }; + /* ** enable memory access */ + data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) & 0xffff | PCI_COMMAND_MEM_ENABLE; - pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); - printf (" on pci%d:%d\n", bus, device); + pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); /* ** attach device ** may produce additional log messages, ** i.e. when installing subdevices. */ + + printf (" on pci%d:%d\n", bus, device); + (void) (*drp->attach) (tag); } #ifndef PCI_QUIET - printf ("pci uses physical addresses from %lx to %lx\n", + printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", (u_long)PCI_PMEM_START, (u_long)pci_paddr); #endif } @@ -432,8 +402,6 @@ void pci_configure() **----------------------------------------------------------------------- */ -extern vm_map_t kernel_map; - int pci_map_port (pcici_t tag, u_long reg, u_short* pa) { /* @@ -453,7 +421,7 @@ int pci_map_port (pcici_t tag, u_long reg, u_short* pa) int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) { - u_long data, result; + u_long data; vm_size_t vsize; vm_offset_t vaddr; @@ -492,7 +460,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); if (!vsize) return (EINVAL); - + /* ** align physical address to virtual size */ @@ -502,13 +470,15 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vaddr = pmap_mapdev (pci_paddr, vsize); -#if 0 + if (!vaddr) return (EINVAL); + +#ifndef PCI_QUIET /* ** display values. */ - printf (" virtual=0x%lx physical=0x%lx\n", (u_long)vaddr, - (u_long)pci_paddr); + printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", + reg, (u_long)vaddr, (u_long)pci_paddr); #endif /* @@ -524,19 +494,68 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) pci_conf_write (tag, reg, pci_paddr); + /* + ** and don't forget to increment pci_paddr + */ + + pci_paddr += vsize; + return (0); } +/*----------------------------------------------------------- +** +** Mapping of physical to virtual memory +** +**----------------------------------------------------------- +*/ + +#if ! (__FreeBSD__ >= 2) + +extern vm_map_t kernel_map; + +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +{ + vm_offset_t vaddr,value; + u_long result; + + vaddr = vm_map_min (kernel_map); + + result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, + &vaddr, vsize, TRUE); + + if (result != KERN_SUCCESS) { + printf (" vm_map_find failed(%d)\n", result); + return (0); + }; + + /* + ** map physical + */ + + value = vaddr; + while (vsize >= NBPG) { + pmap_enter (pmap_kernel(), vaddr, paddr, + VM_PROT_READ|VM_PROT_WRITE, TRUE); + vaddr += NBPG; + paddr += NBPG; + vsize -= NBPG; + }; + return (value); +} +#endif + +/*----------------------------------------------------------- +** +** Display of unknown devices. +** +**----------------------------------------------------------- +*/ struct vt { u_short ident; char* name; }; -struct dt { - u_long ident; - char* name; -}; - static struct vt VendorTable[] = { {0x1002, "ATI TECHNOLOGIES INC"}, {0x1011, "DIGITAL EQUIPMENT COMPANY"}, @@ -548,17 +567,9 @@ static struct vt VendorTable[] = { {0,0} }; -static struct dt DeviceTable[] = { - {0x04848086, " 82378IB pci-isa bridge"}, - {0x04838086, " 82424ZX cache dram controller"}, - {0x04828086, " 82375EB pci-eisa bridge"}, - {0x04A38086, " 82434LX pci cache memory controller"}, - {0,0} -}; - static const char *const majclasses[] = { - "old", "storage", "network", "display", "multimedia", "memory", - "bridge" + "old", "storage", "network", "display", + "multimedia", "memory", "bridge" }; void not_supported (pcici_t tag, u_long type) @@ -566,7 +577,6 @@ void not_supported (pcici_t tag, u_long type) u_char reg; u_long data; struct vt * vp; - struct dt * dp; /* ** lookup the names. @@ -576,23 +586,18 @@ void not_supported (pcici_t tag, u_long type) if (vp->ident == (type & 0xffff)) break; - for (dp=DeviceTable; dp->ident; dp++) - if (dp->ident == type) - break; - /* ** and display them. */ if (vp->ident) printf (vp->name); - else printf ("vendor=%lx", type & 0xffff); + else printf ("vendor=0x%lx", type & 0xffff); - if (dp->ident) printf (dp->name); - else printf (", device=%lx", type >> 16); + printf (", device=0x%lx", type >> 16); - data = pci_conf_read(tag, PCI_CLASS_REV_REG); - if (PCI_MAJCLASS_OF(data) < sizeof(majclasses) / sizeof(majclasses[0])) - printf(", class=%s", majclasses[PCI_MAJCLASS_OF(data)]); + data = (pci_conf_read(tag, PCI_CLASS_REG) >> 24) & 0xff; + if (data < sizeof(majclasses) / sizeof(majclasses[0])) + printf(", class=%s", majclasses[data]); printf (" [not supported]\n"); diff --git a/sys/i386/pci/pci.h b/sys/i386/pci/pci.h index a7ff99d..0c634af 100644 --- a/sys/i386/pci/pci.h +++ b/sys/i386/pci/pci.h @@ -33,18 +33,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci.h,v $ -** Revision 2.0.0.1 94/08/18 23:09:26 wolf -** Copyright message. -** -** Revision 2.0 94/07/10 15:53:30 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:21 wolf -** Beta release. -** -*************************************************************************** */ #ifndef __PCI_H__ diff --git a/sys/i386/pci/pci_config.c b/sys/i386/pci/pci_config.c index 06cec3c..63b7722 100644 --- a/sys/i386/pci/pci_config.c +++ b/sys/i386/pci/pci_config.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci_config.c,v 1.2 1994/09/01 02:01:39 se Exp $ +** $Id: pci_config.c,v 2.0.0.4 94/09/15 20:57:49 wolf Exp $ ** ** @PCI@ this should be part of "ioconf.c". ** @@ -33,24 +33,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci_config.c,v $ - * Revision 1.2 1994/09/01 02:01:39 se - * Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> - * Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu) - * and support for multiple NCR chips. - * -** Revision 2.0.0.1 94/08/18 23:07:28 wolf -** Copyright message. -** Hook for DEC ethernet driver "de". -** -** Revision 2.0 94/07/10 15:53:30 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:04:37 wolf -** Beta release. -** -*************************************************************************** */ #include <sys/types.h> @@ -59,13 +41,15 @@ #include "ncr.h" #if NNCR>0 -extern struct pci_driver ncrdevice; +extern struct pci_driver ncr810_device; +extern struct pci_driver ncr825_device; #endif #include "de.h" #if NDE > 0 extern struct pci_driver dedevice; #endif + extern struct pci_driver intel82378_device; extern struct pci_driver intel82424_device; extern struct pci_driver intel82375_device; @@ -74,19 +58,24 @@ extern struct pci_driver intel82434_device; struct pci_device pci_devtab[] = { #if NNCR>0 - {&ncrdevice, 0x00011000ul, "ncr", 0}, + {&ncr810_device, 0x00011000ul, "ncr", 0}, + {&ncr825_device, 0x00031000ul, "ncr", 0}, #else {0, 0x00011000ul, "ncr", PDF_LOADABLE}, + {0, 0x00031000ul, "ncr", PDF_LOADABLE}, #endif + #if NDE>0 {&dedevice, 0x00011011ul, "de", 0}, /* FIXME!!! */ #else {0, 0x00011011ul, "de", PDF_LOADABLE}, /* FIXME!!! */ #endif + {0, 0x10001042ul, "wd", PDF_COVERED}, + {&intel82378_device, 0x04848086, "ichip", 0}, {&intel82424_device, 0x04838086, "ichip", 0}, {&intel82375_device, 0x04828086, "ichip", 0}, {&intel82434_device, 0x04a38086, "ichip", 0}, - {0, 0, 0} + {0, 0, 0, 0} }; diff --git a/sys/i386/pci/pci_device.h b/sys/i386/pci/pci_device.h index 59c4751..de84248 100644 --- a/sys/i386/pci/pci_device.h +++ b/sys/i386/pci/pci_device.h @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci_device.h,v 1.2 1994/09/01 02:01:41 se Exp $ +** $Id: pci_device.h,v 2.0.0.3 94/09/15 19:23:53 wolf Exp $ ** ** #define for pci based device drivers ** @@ -33,23 +33,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci_device.h,v $ - * Revision 1.2 1994/09/01 02:01:41 se - * Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> - * Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu) - * and support for multiple NCR chips. - * -** Revision 2.0.0.1 94/08/18 23:06:43 wolf -** Copyright message. -** -** Revision 2.0 94/07/10 15:53:31 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:22 wolf -** Beta release. -** -*************************************************************************** */ #ifndef __PCI_DEVICE_H__ @@ -66,8 +49,7 @@ struct pci_driver { int (*probe )(pcici_t pci_ident); /* test whether device is present */ int (*attach)(pcici_t pci_ident); /* setup driver for a device */ pcidi_t device_id; /* device pci id */ - char *name; /* device name */ - char *vendor; /* device long name */ + char *name; /* device (long) name */ int (*intr)(int); /* interupt handler */ }; @@ -81,15 +63,20 @@ struct pci_driver { ** This is a first attempt to include the pci bus to 386bsd. ** So this structure may grow .. ** +** Extended by Garrett Wollman <wollman@halloran-eldar.lcs.mit.edu> +** for future loadable drivers . +** **----------------------------------------------------------- */ struct pci_device { - struct pci_driver * pd_driver; - pcidi_t pd_device_id; /* device pci id */ - const char *pd_name; /* for future loadable drivers */ - int pd_flags; + struct + pci_driver* pd_driver; + pcidi_t pd_device_id; /* device pci id */ + const char * pd_name; /* for future loadable drivers */ + int pd_flags; }; + #define PDF_LOADABLE 0x01 #define PDF_COVERED 0x02 diff --git a/sys/i386/pci/pci_intel.c b/sys/i386/pci/pci_intel.c index e743c11..6c82b7c 100644 --- a/sys/i386/pci/pci_intel.c +++ b/sys/i386/pci/pci_intel.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci_intel.c,v 1.1 1994/09/06 22:39:11 se Exp $ +** $Id: pci_intel.c,v 1.2 94/09/15 21:01:52 wolf Exp $ ** ** Device driver for INTEL PCI chipsets. ** @@ -14,7 +14,7 @@ ** **------------------------------------------------------------------------- ** -** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. +** Copyright (c) 1994 Stefan Esser. All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions @@ -39,18 +39,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci_intel.c,v $ - * Revision 1.1 1994/09/06 22:39:11 se - * Initial revision - * - * Revision 1.1 94/09/05 22:38:38 wolf - * Initial revision - * - * Revision 1.1 94/09/04 16:05:20 wolf - * Initial revision - * -*************************************************************************** */ @@ -69,9 +57,9 @@ static int probe1(pcici_t config_id); static int return0(int unit); -static int intel_attach(pcici_t config_id, pcidi_t type); -static int intel_82424zx_attach(pcici_t config_id, pcidi_t type); -static int intel_82434lx_attach(pcici_t config_id, pcidi_t type); +static int intel_attach(pcici_t config_id); +static int intel_82424zx_attach(pcici_t config_id); +static int intel_82434lx_attach(pcici_t config_id); extern void printf(); static char confread(pcici_t config_id, int port); @@ -92,7 +80,6 @@ struct pci_driver intel82378_device = { probe1, intel_attach, 0x04848086, - 0, "intel 82378IB pci-isa bridge", return0 }; @@ -101,7 +88,6 @@ struct pci_driver intel82424_device = { probe1, intel_82424zx_attach, 0x04838086, - 0, "intel 82424ZX cache dram controller", return0 }; @@ -110,7 +96,6 @@ struct pci_driver intel82375_device = { probe1, intel_attach, 0x04828086, - 0, "intel 82375EB pci-eisa bridge", return0 }; @@ -119,7 +104,6 @@ struct pci_driver intel82434_device = { probe1, intel_82434lx_attach, 0x04a38086, - 0, "intel 82434LX pci cache memory controller", return0 }; @@ -139,12 +123,12 @@ struct condmsg conf82424zx[] = { 0x53, 0x01, 0x00, M_EQ, "OFF" }, { 0x53, 0x01, 0x01, M_EQ, "ON" }, - { 0x56, 0x30, 0x00, M_NE, "\t\nWarning:" }, + { 0x56, 0x30, 0x00, M_NE, "\n\tWarning:" }, { 0x56, 0x20, 0x00, M_NE, " NO cache parity!" }, { 0x56, 0x10, 0x00, M_NE, " NO DRAM parity!" }, - { 0x55, 0x04, 0x04, M_EQ, "\nWarning: refresh OFF! " }, + { 0x55, 0x04, 0x04, M_EQ, "\n\tWarning: refresh OFF! " }, - { 0x00, 0x00, 0x00, TRUE, "\t\nCache: " }, + { 0x00, 0x00, 0x00, TRUE, "\n\tCache: " }, { 0x52, 0x01, 0x00, M_EQ, "None" }, { 0x52, 0xc1, 0x01, M_EQ, "64KB" }, { 0x52, 0xc1, 0x41, M_EQ, "128KB" }, @@ -157,7 +141,7 @@ struct condmsg conf82424zx[] = { 0x52, 0x05, 0x01, M_EQ, "3-1-1-1" }, { 0x52, 0x05, 0x05, M_EQ, "2-1-1-1" }, - { 0x00, 0x00, 0x00, TRUE, "\t\nDRAM:" }, + { 0x00, 0x00, 0x00, TRUE, "\n\tDRAM:" }, { 0x55, 0x43, 0x00, M_NE, " page mode" }, { 0x55, 0x02, 0x02, M_EQ, " code fetch" }, { 0x55, 0x43, 0x43, M_EQ, "," }, @@ -172,13 +156,13 @@ struct condmsg conf82424zx[] = { 0x55, 0x20, 0x00, M_EQ, "X-2-2-2" }, { 0x55, 0x20, 0x20, M_EQ, "X-1-2-1" }, - { 0x00, 0x00, 0x00, TRUE, "\t\nPCI: CPU->PCI posting " }, + { 0x00, 0x00, 0x00, TRUE, "\n\tPCI: CPU->PCI posting " }, { 0x53, 0x02, 0x02, M_EQ, "ON" }, { 0x53, 0x02, 0x00, M_EQ, "OFF" }, { 0x00, 0x00, 0x00, TRUE, ", CPU->PCI burst mode " }, { 0x54, 0x02, 0x02, M_EQ, "ON" }, { 0x54, 0x02, 0x00, M_EQ, "OFF" }, - { 0x00, 0x00, 0x00, TRUE, ", PCI->Mem. posting " }, + { 0x00, 0x00, 0x00, TRUE, ", PCI->Memory posting " }, { 0x54, 0x01, 0x01, M_EQ, "ON" }, { 0x54, 0x01, 0x00, M_EQ, "OFF" }, @@ -204,11 +188,11 @@ struct condmsg conf82434lx[] = { 0x53, 0x04, 0x00, M_NE, ", read around write"}, - { 0x71, 0xc0, 0x00, M_NE, "\t\nWarning: NO cache parity!" }, - { 0x57, 0x20, 0x00, M_NE, "\t\nWarning: NO DRAM parity!" }, - { 0x55, 0x01, 0x01, M_EQ, "\t\nWarning: refresh OFF! " }, + { 0x71, 0xc0, 0x00, M_NE, "\n\tWarning: NO cache parity!" }, + { 0x57, 0x20, 0x00, M_NE, "\n\tWarning: NO DRAM parity!" }, + { 0x55, 0x01, 0x01, M_EQ, "\n\tWarning: refresh OFF! " }, - { 0x00, 0x00, 0x00, TRUE, "\t\nCache: " }, + { 0x00, 0x00, 0x00, TRUE, "\n\tCache: " }, { 0x52, 0x01, 0x00, M_EQ, "None" }, { 0x52, 0x81, 0x01, M_EQ, "" }, { 0x52, 0xc1, 0x81, M_EQ, "256KB" }, @@ -220,7 +204,7 @@ struct condmsg conf82434lx[] = { 0x52, 0x20, 0x00, M_EQ, "3-2-2-2/4-2-2-2" }, { 0x52, 0x20, 0x00, M_NE, "3-1-1-1" }, - { 0x00, 0x00, 0x00, TRUE, "\t\nDRAM:" }, + { 0x00, 0x00, 0x00, TRUE, "\n\tDRAM:" }, { 0x57, 0x10, 0x00, M_EQ, " page mode" }, { 0x00, 0x00, 0x00, TRUE, " memory clocks=" }, @@ -229,7 +213,7 @@ struct condmsg conf82434lx[] = { 0x57, 0xc0, 0x80, M_EQ, "???" }, { 0x57, 0xc0, 0xc0, M_EQ, "X-3-3-3 (50ns)" }, - { 0x00, 0x00, 0x00, TRUE, "\t\nPCI: CPU->PCI posting " }, + { 0x00, 0x00, 0x00, TRUE, "\n\tPCI: CPU->PCI posting " }, { 0x53, 0x02, 0x02, M_EQ, "ON" }, { 0x53, 0x02, 0x00, M_EQ, "OFF" }, { 0x00, 0x00, 0x00, TRUE, ", CPU->PCI burst mode " }, @@ -282,7 +266,6 @@ static void writeconfig(pcici_t config_id, struct condmsg *tbl) case M_NE: if ((v & tbl->mask) != tbl->value) cond = 1; break; - default: } } if (cond) printf ("%s", tbl->text); @@ -290,24 +273,24 @@ static void writeconfig(pcici_t config_id, struct condmsg *tbl) } } -int intel_attach(pcici_t config_id, pcidi_t type) +int intel_attach(pcici_t config_id) { - printf (" [40] %lx [50] %lx [54] %lx\n", + printf ("\t[40] %lx [50] %lx [54] %lx\n", pci_conf_read (config_id, 0x40), pci_conf_read (config_id, 0x50), pci_conf_read (config_id, 0x54)); return(0); } -int intel_82424zx_attach(pcici_t config_id, pcidi_t type) +int intel_82424zx_attach(pcici_t config_id) { writeconfig (config_id, conf82424zx); return (0); } -int intel_82434lx_attach(pcici_t config_id, pcidi_t type) +int intel_82434lx_attach(pcici_t config_id) { - writeconfig (config_id, conf82424zx); + writeconfig (config_id, conf82434lx); return (0); } diff --git a/sys/i386/pci/pcibios.c b/sys/i386/pci/pcibios.c index 8f0ad3f..0764814 100644 --- a/sys/i386/pci/pcibios.c +++ b/sys/i386/pci/pcibios.c @@ -33,23 +33,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pcibios.c,v $ -** Revision 2.0.0.2 94/08/18 23:04:11 wolf -** Copyright message. -** New function pci_last_bus(). -** -** Revision 2.0.0.1 94/08/01 20:35:29 wolf -** Option: PCI_CONF_MODE to disable pci autodetect code. -** Flipped code for mode1 and mode2. -** -** Revision 2.0 94/07/10 15:53:31 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:20 wolf -** Beta release. -** -*************************************************************************** */ @@ -64,8 +47,7 @@ extern int printf(); static char pci_mode; char ident_pcibios_c[] = - "\n$Id: pcibios.c,v 2.0.0.2 94/08/18 23:04:11 wolf Exp $\n" - "Copyright (c) 1994, Wolfgang Stanglmeier\n"; + "\n$Id: pcibios.c,v 2.0.0.2 94/08/18 23:04:11 wolf Exp $\n"; /*-------------------------------------------------------------------- diff --git a/sys/i386/pci/pcibios.h b/sys/i386/pci/pcibios.h index a5cf491..3ceb86f 100644 --- a/sys/i386/pci/pcibios.h +++ b/sys/i386/pci/pcibios.h @@ -1,14 +1,16 @@ /************************************************************************** ** -** $Id: pcibios.h,v 1.2 1994/09/01 02:01:45 se Exp $ +** $Id: pcibios.h,v 2.0.0.2 94/09/15 19:55:26 wolf Exp $ ** -** #define for pci-bus bios functions. +** #define for pci-bus bios functions. +** #define for pci configuration space registers. ** ** 386bsd / FreeBSD ** **------------------------------------------------------------------------- ** ** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. +** Copyright (c) 1994 Charles Hannum. All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions @@ -33,26 +35,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pcibios.h,v $ - * Revision 1.2 1994/09/01 02:01:45 se - * Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> - * Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu) - * and support for multiple NCR chips. - * -** Revision 2.0.0.1 94/08/18 23:05:36 wolf -** -** Copyright message. -** New function: pci_last_bus(). -** Symbolic names for pci configuration space registers. -** -** Revision 2.0 94/07/10 15:53:32 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:23 wolf -** Beta release. -** -*************************************************************************** */ #ifndef __PCIBIOS_H__ @@ -89,40 +71,117 @@ u_long pci_conf_read (pcici_t tag, u_long reg ); void pci_conf_write (pcici_t tag, u_long reg, u_long data); -/* +/*------------------------------------------------------------------ +** ** Names for PCI configuration space registers. -** Copied from pcireg.h +** +** Copyright (c) 1994 Charles Hannum. All rights reserved. +** +**------------------------------------------------------------------ */ +/* + * Device identification register; contains a vendor ID and a device ID. + * We have little need to distinguish the two parts. + */ #define PCI_ID_REG 0x00 +/* + * Command and status register. + */ #define PCI_COMMAND_STATUS_REG 0x04 + +#define PCI_COMMAND_IO_ENABLE 0x00000001 #define PCI_COMMAND_MEM_ENABLE 0x00000002 +#define PCI_COMMAND_MASTER_ENABLE 0x00000004 +#define PCI_COMMAND_SPECIAL_ENABLE 0x00000008 +#define PCI_COMMAND_INVALIDATE_ENABLE 0x00000010 +#define PCI_COMMAND_PALETTE_ENABLE 0x00000020 +#define PCI_COMMAND_PARITY_ENABLE 0x00000040 +#define PCI_COMMAND_STEPPING_ENABLE 0x00000080 +#define PCI_COMMAND_SERR_ENABLE 0x00000100 +#define PCI_COMMAND_BACKTOBACK_ENABLE 0x00000200 + +#define PCI_STATUS_BACKTOBACK_OKAY 0x00800000 +#define PCI_STATUS_PARITY_ERROR 0x01000000 +#define PCI_STATUS_DEVSEL_FAST 0x00000000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x02000000 +#define PCI_STATUS_DEVSEL_SLOW 0x04000000 +#define PCI_STATUS_DEVSEL_MASK 0x06000000 +#define PCI_STATUS_TARGET_TARGET_ABORT 0x08000000 +#define PCI_STATUS_MASTER_TARGET_ABORT 0x10000000 +#define PCI_STATUS_MASTER_ABORT 0x20000000 +#define PCI_STATUS_SPECIAL_ERROR 0x40000000 +#define PCI_STATUS_PARITY_DETECT 0x80000000 -#define PCI_CLASS_REV_REG 0x08 -#define PCI_MAJCLASS_OF(x) (((x) >> 24) & 0xff) -#define PCI_MINCLASS_OF(x) (((x) >> 16) & 0xff) -#define PCI_PROGINT_OF(x) (((x) >> 8) & 0xff) -#define PCI_REV_OF(x) ((x) & 0xff) -enum pci_majclass { PCI_MJC_OLD = 0, PCI_MJC_STOR, PCI_MJC_NET, - PCI_MJC_DISPLAY, PCI_MJC_MEDIA, PCI_MJC_MEM, - PCI_MJC_BRIDGE }; -enum pci_old_minclass { PCI_MIN_OLD = 0, PCI_MIN_OVGA }; -enum pci_stor_minclass { PCI_MIN_SCSI = 0, PCI_MIN_IDE, PCI_MIN_FLOP, - PCI_MIN_IPI, PCI_MIN_OSTOR }; -enum pci_net_minclass { PCI_MIN_ETHER = 0, PCI_MIN_TOKEN, PCI_MIN_FDDI, - PCI_MIN_ONET }; -enum pci_disp_minclass { PCI_MIN_VGA = 0, PCI_MIN_XGA, PCI_MIN_ODISP }; -enum pci_media_minclass { PCI_MIN_VIDEO = 0, PCI_MIN_AUDIO, PCI_MIN_OMEDIA }; -enum pci_mem_minclass { PCI_MIN_RAM = 0, PCI_MIN_FLASH, PCI_MIN_OMEM }; -enum pci_bridge_minclass { PCI_MIN_HOST = 0, PCI_MIN_ISA, PCI_MIN_EISA, - PCI_MIN_MC, PCI_MIN_PCI, PCI_MIN_PCMCIA, - PCI_MIN_OBRIDGE }; +/* + * Class register; defines basic type of device. + */ +#define PCI_CLASS_REG 0x08 + +#define PCI_CLASS_MASK 0xff000000 +#define PCI_SUBCLASS_MASK 0x00ff0000 + +/* base classes */ +#define PCI_CLASS_PREHISTORIC 0x00000000 +#define PCI_CLASS_MASS_STORAGE 0x01000000 +#define PCI_CLASS_NETWORK 0x02000000 +#define PCI_CLASS_DISPLAY 0x03000000 +#define PCI_CLASS_MULTIMEDIA 0x04000000 +#define PCI_CLASS_MEMORY 0x05000000 +#define PCI_CLASS_BRIDGE 0x06000000 +#define PCI_CLASS_UNDEFINED 0xff000000 + +/* 0x00 prehistoric subclasses */ +#define PCI_SUBCLASS_PREHISTORIC_MISC 0x00000000 +#define PCI_SUBCLASS_PREHISTORIC_VGA 0x00010000 + +/* 0x01 mass storage subclasses */ +#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00000000 +#define PCI_SUBCLASS_MASS_STORAGE_IDE 0x00010000 +#define PCI_SUBCLASS_MASS_STORAGE_FLOPPY 0x00020000 +#define PCI_SUBCLASS_MASS_STORAGE_IPI 0x00030000 +#define PCI_SUBCLASS_MASS_STORAGE_MISC 0x00800000 + +/* 0x02 network subclasses */ +#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00000000 +#define PCI_SUBCLASS_NETWORK_TOKENRING 0x00010000 +#define PCI_SUBCLASS_NETWORK_FDDI 0x00020000 +#define PCI_SUBCLASS_NETWORK_MISC 0x00800000 + +/* 0x03 display subclasses */ +#define PCI_SUBCLASS_DISPLAY_VGA 0x00000000 +#define PCI_SUBCLASS_DISPLAY_XGA 0x00010000 +#define PCI_SUBCLASS_DISPLAY_MISC 0x00800000 + +/* 0x04 multimedia subclasses */ +#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00000000 +#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x00010000 +#define PCI_SUBCLASS_MULTIMEDIA_MISC 0x00800000 + +/* 0x05 memory subclasses */ +#define PCI_SUBCLASS_MEMORY_RAM 0x00000000 +#define PCI_SUBCLASS_MEMORY_FLASH 0x00010000 +#define PCI_SUBCLASS_MEMORY_MISC 0x00800000 + +/* 0x06 bridge subclasses */ +#define PCI_SUBCLASS_BRIDGE_HOST 0x00000000 +#define PCI_SUBCLASS_BRIDGE_ISA 0x00010000 +#define PCI_SUBCLASS_BRIDGE_EISA 0x00020000 +#define PCI_SUBCLASS_BRIDGE_MC 0x00030000 +#define PCI_SUBCLASS_BRIDGE_PCI 0x00040000 +#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x00050000 +#define PCI_SUBCLASS_BRIDGE_MISC 0x00800000 +/* + * Mapping registers + */ #define PCI_MAP_REG_START 0x10 #define PCI_MAP_REG_END 0x28 + #define PCI_MAP_MEMORY 0x00000000 #define PCI_MAP_IO 0x00000001 + #define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000 #define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002 #define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004 @@ -130,10 +189,21 @@ enum pci_bridge_minclass { PCI_MIN_HOST = 0, PCI_MIN_ISA, PCI_MIN_EISA, #define PCI_MAP_MEMORY_CACHABLE 0x00000008 #define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0 +/* + * Interrupt configuration register + */ #define PCI_INTERRUPT_REG 0x3c + #define PCI_INTERRUPT_PIN_MASK 0x0000ff00 #define PCI_INTERRUPT_PIN_EXTRACT(x) ((((x) & PCI_INTERRUPT_PIN_MASK) >> 8) & 0xff) +#define PCI_INTERRUPT_PIN_NONE 0x00 +#define PCI_INTERRUPT_PIN_A 0x01 +#define PCI_INTERRUPT_PIN_B 0x02 +#define PCI_INTERRUPT_PIN_C 0x03 +#define PCI_INTERRUPT_PIN_D 0x04 + #define PCI_INTERRUPT_LINE_MASK 0x000000ff #define PCI_INTERRUPT_LINE_EXTRACT(x) ((((x) & PCI_INTERRUPT_LINE_MASK) >> 0) & 0xff) +#define PCI_INTERRUPT_LINE_INSERT(x,v) (((x) & ~PCI_INTERRUPT_LINE_MASK) | ((v) << 0)) #endif diff --git a/sys/pci/pci.c b/sys/pci/pci.c index 93b2d17..c2f16b8 100644 --- a/sys/pci/pci.c +++ b/sys/pci/pci.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pci.c,v 1.2 1994/09/01 02:01:34 se Exp $ +** $Id: pci.c,v 2.0.0.12 94/09/15 20:49:23 wolf Exp $ ** ** General subroutines for the PCI bus on 80*86 systems. ** pci_configure () @@ -34,53 +34,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** **------------------------------------------------------------------------- -** -** $Log: pci.c,v $ - * Revision 1.2 1994/09/01 02:01:34 se - * Submitted by: Wolfgang Stanglmeier <wolf@dentaro.GUN.de> - * Merged in changes required for NetBSD support (by mycroft@gnu.ai.mit.edu) - * and support for multiple NCR chips. - * -** Revision 2.0.0.8 94/08/21 19:57:39 wolf -** Unneeded declarations removed (FreeBSD2.0) -** -** Revision 2.0.0.7 94/08/21 19:25:54 wolf -** pci_intr simplified. -** new not_supported() function. -** Vendor and device ids moved into tables. -** -** Revision 2.0.0.6 94/08/18 22:58:23 wolf -** Symbolic names for pci configuration space registers. -** last_device: from configuration mode -** last_bus: from pcibios. -** PCI_MAX_DPI: changed to 4 (settable by config) -** interrupt configuration by line or pin -** -** Revision 2.0.0.5 94/08/11 19:04:10 wolf -** display of interrupt line configuration register. -** -** Revision 2.0.0.4 94/08/01 20:36:28 wolf -** Tiny clean up. -** -** Revision 2.0.0.3 94/08/01 18:52:33 wolf -** New vendor entry: S3. -** Scan pci busses #0..#255 as default. -** Number of scanned busses and devices settable as option. -** Show these numbers before starting the scan. -** -** Revision 2.0.0.2 94/07/27 09:27:19 wolf -** New option PCI_QUIET: suppress log messages. -** -** Revision 2.0.0.1 94/07/19 19:06:44 wolf -** New vendor entry: MATROX -** -** Revision 2.0 94/07/10 15:53:29 wolf -** FreeBSD release. -** -** Revision 1.0 94/06/07 20:02:19 wolf -** Beta release. -** -*************************************************************************** */ #include <pci.h> @@ -126,15 +79,15 @@ char ident_pci_c[] = - "\n$Id: pci.c,v 1.2 1994/09/01 02:01:34 se Exp $\n" - "Copyright (c) 1994, Wolfgang Stanglmeier\n"; + "\n$Id: pci.c,v 2.0.0.12 94/09/15 20:49:23 wolf Exp $\n"; /* ** Function prototypes missing in system headers */ #if ! (__FreeBSD__ >= 2) -extern pmap_t pmap_kernel(void); +extern pmap_t pmap_kernel(void); +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize); #endif @@ -146,7 +99,7 @@ extern pmap_t pmap_kernel(void); */ /* -** per device (interrupt) data structure. +** per slot data structure for passing interupts.. */ static struct { @@ -205,7 +158,8 @@ void pciintr (int unit) u_short i; if (unit >= NPCI) return; for (i=0; i<pcidata[unit].number; i++) { - (void)(*pcidata[unit].vector[i].proc)(pcidata[unit].vector[i].unit); + (void)(*pcidata[unit].vector[i].proc) + (pcidata[unit].vector[i].unit); }; } @@ -273,10 +227,8 @@ void pci_configure() */ #ifndef PCI_QUIET - printf ("PCI configuration mode %d.\n", pci_mode); - printf ("Scanning device 0..%d on pci bus 0..%d " - "($Revision: 1.2 $)\n", - last_device, last_bus); + printf ("pci*: mode=%d, scanning bus 0..%d, device 0..%d.\n", + pci_mode, last_bus, last_device); #endif for (bus=0;bus<=last_bus; bus++) @@ -294,37 +246,47 @@ void pci_configure() if (dvp->pd_device_id == type) break; }; drp = dvp->pd_driver; - + if (!dvp->pd_device_id) { - int data = pci_conf_read(tag, PCI_CLASS_REV_REG); - enum pci_majclass class = PCI_MAJCLASS_OF(data); + + /* + ** not found + ** try to dig out some information. + ** + ** By Garrett Wollman + ** <wollman@halloran-eldar.lcs.mit.edu> + */ + + int data = pci_conf_read(tag, PCI_CLASS_REG); vm_offset_t va; vm_offset_t pa; int reg; - switch(class) { - case PCI_MJC_OLD: - if(PCI_MINCLASS_OF(data) != PCI_MIN_OVGA) - break; - case PCI_MJC_DISPLAY: + switch (data & PCI_CLASS_MASK) { + + case PCI_CLASS_PREHISTORIC: + if ((data & PCI_SUBCLASS_MASK) + != PCI_SUBCLASS_PREHISTORIC_VGA) + break; + + case PCI_CLASS_DISPLAY: for (reg = PCI_MAP_REG_START; reg < PCI_MAP_REG_END; reg += 4) { data = pci_map_mem(tag, reg, &va, &pa); - if(data == 0) - printf( -"pci%d:%d: mapped VGA-like device at physaddr %lx\n", - bus, device, (u_long)pa); + if (data == 0) + printf ( + "pci%d:%d: mapped VGA-like device at physaddr 0x%lx\n", + bus, device, (u_long)pa); } continue; - default: + }; #ifndef PCI_QUIET - printf("pci%d:%d: ", bus, device); - not_supported (tag, type); + printf("pci%d:%d: ", bus, device); + not_supported (tag, type); #endif - } - } + }; if (!drp) { if(dvp->pd_flags & PDF_LOADABLE) { @@ -338,20 +300,17 @@ void pci_configure() ** found it. ** probe returns the device unit. */ + unit = (*drp->probe) (tag); if (unit<0) { printf ("%s <%s>: probe failed on pci%d:%d\n", - drp->name, drp->vendor, bus, device); + dvp->pd_name, drp->name, bus, device); continue; }; - if (drp->name) { - printf ("%s%d <%s>", drp->name, unit, drp->vendor); - } else { - printf ("pci%d: <%s>", bus, drp->vendor); - } - + printf ("%s%d <%s>", dvp->pd_name, unit, drp->name); + /* ** install interrupts */ @@ -368,18 +327,26 @@ void pci_configure() isanum = PCI_INTERRUPT_LINE_EXTRACT(data); if (isanum) { - printf (" il=%d", isanum); + + /* + ** @INT@ FIXME!!! + ** + ** Should try to use "register_interupt" + ** at this point. + */ + + printf (" line=%d", isanum); for (idx = 0; idx < NPCI; idx++) { if (pcidata[idx].isanum == isanum) break; - } - } + }; + }; /* - ** Or believe to the interrupt pin register. + ** Or take the device number as index ... */ - if (idx >= NPCI) idx = intpin-1; + if (idx >= NPCI) idx = device; /* ** And install the interrupt. @@ -396,29 +363,32 @@ void pci_configure() printf (" isa=%d [%d]",pcidata[idx].isanum, entry); pcidata[idx].number=entry; } else { - printf (" not installed"); - } - } - + printf (" no int"); + }; + }; + /* ** enable memory access */ + data = pci_conf_read (tag, PCI_COMMAND_STATUS_REG) & 0xffff | PCI_COMMAND_MEM_ENABLE; - pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); - printf (" on pci%d:%d\n", bus, device); + pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data); /* ** attach device ** may produce additional log messages, ** i.e. when installing subdevices. */ + + printf (" on pci%d:%d\n", bus, device); + (void) (*drp->attach) (tag); } #ifndef PCI_QUIET - printf ("pci uses physical addresses from %lx to %lx\n", + printf ("pci uses physical addresses from 0x%lx to 0x%lx\n", (u_long)PCI_PMEM_START, (u_long)pci_paddr); #endif } @@ -432,8 +402,6 @@ void pci_configure() **----------------------------------------------------------------------- */ -extern vm_map_t kernel_map; - int pci_map_port (pcici_t tag, u_long reg, u_short* pa) { /* @@ -453,7 +421,7 @@ int pci_map_port (pcici_t tag, u_long reg, u_short* pa) int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) { - u_long data, result; + u_long data; vm_size_t vsize; vm_offset_t vaddr; @@ -492,7 +460,7 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK)); if (!vsize) return (EINVAL); - + /* ** align physical address to virtual size */ @@ -502,13 +470,15 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) vaddr = pmap_mapdev (pci_paddr, vsize); -#if 0 + if (!vaddr) return (EINVAL); + +#ifndef PCI_QUIET /* ** display values. */ - printf (" virtual=0x%lx physical=0x%lx\n", (u_long)vaddr, - (u_long)pci_paddr); + printf ("\treg%d: virtual=0x%lx physical=0x%lx\n", + reg, (u_long)vaddr, (u_long)pci_paddr); #endif /* @@ -524,19 +494,68 @@ int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa) pci_conf_write (tag, reg, pci_paddr); + /* + ** and don't forget to increment pci_paddr + */ + + pci_paddr += vsize; + return (0); } +/*----------------------------------------------------------- +** +** Mapping of physical to virtual memory +** +**----------------------------------------------------------- +*/ + +#if ! (__FreeBSD__ >= 2) + +extern vm_map_t kernel_map; + +static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize) +{ + vm_offset_t vaddr,value; + u_long result; + + vaddr = vm_map_min (kernel_map); + + result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0, + &vaddr, vsize, TRUE); + + if (result != KERN_SUCCESS) { + printf (" vm_map_find failed(%d)\n", result); + return (0); + }; + + /* + ** map physical + */ + + value = vaddr; + while (vsize >= NBPG) { + pmap_enter (pmap_kernel(), vaddr, paddr, + VM_PROT_READ|VM_PROT_WRITE, TRUE); + vaddr += NBPG; + paddr += NBPG; + vsize -= NBPG; + }; + return (value); +} +#endif + +/*----------------------------------------------------------- +** +** Display of unknown devices. +** +**----------------------------------------------------------- +*/ struct vt { u_short ident; char* name; }; -struct dt { - u_long ident; - char* name; -}; - static struct vt VendorTable[] = { {0x1002, "ATI TECHNOLOGIES INC"}, {0x1011, "DIGITAL EQUIPMENT COMPANY"}, @@ -548,17 +567,9 @@ static struct vt VendorTable[] = { {0,0} }; -static struct dt DeviceTable[] = { - {0x04848086, " 82378IB pci-isa bridge"}, - {0x04838086, " 82424ZX cache dram controller"}, - {0x04828086, " 82375EB pci-eisa bridge"}, - {0x04A38086, " 82434LX pci cache memory controller"}, - {0,0} -}; - static const char *const majclasses[] = { - "old", "storage", "network", "display", "multimedia", "memory", - "bridge" + "old", "storage", "network", "display", + "multimedia", "memory", "bridge" }; void not_supported (pcici_t tag, u_long type) @@ -566,7 +577,6 @@ void not_supported (pcici_t tag, u_long type) u_char reg; u_long data; struct vt * vp; - struct dt * dp; /* ** lookup the names. @@ -576,23 +586,18 @@ void not_supported (pcici_t tag, u_long type) if (vp->ident == (type & 0xffff)) break; - for (dp=DeviceTable; dp->ident; dp++) - if (dp->ident == type) - break; - /* ** and display them. */ if (vp->ident) printf (vp->name); - else printf ("vendor=%lx", type & 0xffff); + else printf ("vendor=0x%lx", type & 0xffff); - if (dp->ident) printf (dp->name); - else printf (", device=%lx", type >> 16); + printf (", device=0x%lx", type >> 16); - data = pci_conf_read(tag, PCI_CLASS_REV_REG); - if (PCI_MAJCLASS_OF(data) < sizeof(majclasses) / sizeof(majclasses[0])) - printf(", class=%s", majclasses[PCI_MAJCLASS_OF(data)]); + data = (pci_conf_read(tag, PCI_CLASS_REG) >> 24) & 0xff; + if (data < sizeof(majclasses) / sizeof(majclasses[0])) + printf(", class=%s", majclasses[data]); printf (" [not supported]\n"); |