1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-19 15:33:56 +00:00

Add generic PCI to PCI bridge support.

Improve verbose boot messages for unidentified chips.
This commit is contained in:
Stefan Eßer 1996-02-17 23:57:04 +00:00
parent 2e32d69db1
commit 07d9d14a55
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14133
3 changed files with 177 additions and 46 deletions

View File

@ -1,6 +1,6 @@
/************************************************************************** /**************************************************************************
** **
** $Id: pci.c,v 1.43 1996/01/27 20:14:31 wollman Exp $ ** $Id: pci.c,v 1.44 1996/01/30 01:14:29 se Exp $
** **
** General subroutines for the PCI bus. ** General subroutines for the PCI bus.
** pci_configure () ** pci_configure ()
@ -474,6 +474,8 @@ pci_bus_config (void)
real_device: real_device:
#ifndef PCI_QUIET
#ifdef PCI_BRIDGE_DEBUG
if (bootverbose) { if (bootverbose) {
printf ("\tconfig header: 0x%08x 0x%08x 0x%08x 0x%08x\n", printf ("\tconfig header: 0x%08x 0x%08x 0x%08x 0x%08x\n",
pci_conf_read (tag, 0), pci_conf_read (tag, 0),
@ -481,6 +483,8 @@ pci_bus_config (void)
pci_conf_read (tag, 8), pci_conf_read (tag, 8),
pci_conf_read (tag, 12)); pci_conf_read (tag, 12));
} }
#endif
#endif
if (func == 0 && pci_mfdev (bus_no, device)) { if (func == 0 && pci_mfdev (bus_no, device)) {
maxfunc = 7; maxfunc = 7;
@ -1563,7 +1567,7 @@ static struct vt VendorTable[] = {
}; };
typedef struct { typedef struct {
const char subclass; const int subclass;
const char *name; const char *name;
} subclass_name; } subclass_name;
@ -1659,9 +1663,13 @@ static const char *const majclasses[] = {
void not_supported (pcici_t tag, u_long type) void not_supported (pcici_t tag, u_long type)
{ {
u_char reg; u_long reg;
u_long data; u_long data;
u_char class;
u_char subclass;
struct vt * vp; struct vt * vp;
int pciint;
int irq;
/* /*
** lookup the names. ** lookup the names.
@ -1680,47 +1688,86 @@ void not_supported (pcici_t tag, u_long type)
printf (", device=0x%04lx", type >> 16); printf (", device=0x%04lx", type >> 16);
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff; data = pcibus->pb_read(tag, PCI_CLASS_REG);
if (data < sizeof(majclasses) / sizeof(majclasses[0])) class = (data >> 24) & 0xff;
printf(", class=%s", majclasses[data]); subclass = (data >> 16) & 0xff;
if (data < sizeof(subclasses) / sizeof(subclasses[0])) {
const subclass_name *p = subclasses[data];
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 16) & 0xff; if (class < sizeof(majclasses) / sizeof(majclasses[0])) {
while (p->name && (p->subclass != data)) printf(", class=%s", majclasses[class]);
} else {
printf(", class=0x%02x", class);
}
if (subclass < sizeof(subclasses) / sizeof(subclasses[0])) {
const subclass_name *p = subclasses[class];
while (p->name && (p->subclass != subclass))
p++; p++;
if (p->name) { if (p->name) {
printf(" (%s)", p->name); printf(" (%s)", p->name);
} else { } else {
printf(" (unknown subclass 0x%02lx)", data); printf(" (unknown subclass 0x%02lx)", subclass);
} }
} else {
printf(", subclass=0x%02x", subclass);
} }
printf (" [no driver assigned]\n"); data = pcibus->pb_read (tag, PCI_INTERRUPT_REG);
pciint = PCI_INTERRUPT_PIN_EXTRACT(data);
if (pciint) {
printf (" int %c irq ", 0x60+pciint);
irq = PCI_INTERRUPT_LINE_EXTRACT(data);
/*
** If it's zero, the isa irq number is unknown,
** and we cannot bind the pci interrupt.
*/
if (irq && (irq != 0xff))
printf ("%d", irq);
else
printf ("??");
};
if (class != (PCI_CLASS_BRIDGE >> 24))
printf (" [no driver assigned]");
printf ("\n");
if (bootverbose) { if (bootverbose) {
for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) { if (class == (PCI_CLASS_BRIDGE >> 24)) {
data = pcibus->pb_read (tag, reg); printf ("configuration space registers:");
if ((data&~7)==0) continue; for (reg = 0; reg < 0x100; reg+=4) {
switch (data&7) { if ((reg & 0x0f) == 0) printf ("\n%02x:\t", reg);
printf ("%08x ", pcibus->pb_read (tag, reg));
}
printf ("\n");
} else {
for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) {
data = pcibus->pb_read (tag, reg);
if ((data&~7)==0) continue;
switch (data&7) {
case 1: case 1:
case 5: case 5:
printf (" map(%x): io(%lx)\n", printf ("\tmap(%x): io(%04lx)\n",
reg, data & ~3); reg, data & ~3);
break; break;
case 0: case 0:
printf (" map(%x): mem32(%lx)\n", printf ("\tmap(%x): mem32(%08lx)\n",
reg, data & ~7); reg, data & ~7);
break; break;
case 2: case 2:
printf (" map(%x): mem20(%lx)\n", printf ("\tmap(%x): mem20(%05lx)\n",
reg, data & ~7); reg, data & ~7);
break; break;
case 4: case 4:
printf (" map(%x): mem64(%lx)\n", printf ("\tmap(%x): mem64(%08x%08lx)\n",
reg, data & ~7); reg, pcibus->pb_read (tag, reg +4), data & ~7);
reg += 4;
break; break;
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
/************************************************************************** /**************************************************************************
** **
** $Id: pci.c,v 1.43 1996/01/27 20:14:31 wollman Exp $ ** $Id: pci.c,v 1.44 1996/01/30 01:14:29 se Exp $
** **
** General subroutines for the PCI bus. ** General subroutines for the PCI bus.
** pci_configure () ** pci_configure ()
@ -474,6 +474,8 @@ pci_bus_config (void)
real_device: real_device:
#ifndef PCI_QUIET
#ifdef PCI_BRIDGE_DEBUG
if (bootverbose) { if (bootverbose) {
printf ("\tconfig header: 0x%08x 0x%08x 0x%08x 0x%08x\n", printf ("\tconfig header: 0x%08x 0x%08x 0x%08x 0x%08x\n",
pci_conf_read (tag, 0), pci_conf_read (tag, 0),
@ -481,6 +483,8 @@ pci_bus_config (void)
pci_conf_read (tag, 8), pci_conf_read (tag, 8),
pci_conf_read (tag, 12)); pci_conf_read (tag, 12));
} }
#endif
#endif
if (func == 0 && pci_mfdev (bus_no, device)) { if (func == 0 && pci_mfdev (bus_no, device)) {
maxfunc = 7; maxfunc = 7;
@ -1563,7 +1567,7 @@ static struct vt VendorTable[] = {
}; };
typedef struct { typedef struct {
const char subclass; const int subclass;
const char *name; const char *name;
} subclass_name; } subclass_name;
@ -1659,9 +1663,13 @@ static const char *const majclasses[] = {
void not_supported (pcici_t tag, u_long type) void not_supported (pcici_t tag, u_long type)
{ {
u_char reg; u_long reg;
u_long data; u_long data;
u_char class;
u_char subclass;
struct vt * vp; struct vt * vp;
int pciint;
int irq;
/* /*
** lookup the names. ** lookup the names.
@ -1680,47 +1688,86 @@ void not_supported (pcici_t tag, u_long type)
printf (", device=0x%04lx", type >> 16); printf (", device=0x%04lx", type >> 16);
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff; data = pcibus->pb_read(tag, PCI_CLASS_REG);
if (data < sizeof(majclasses) / sizeof(majclasses[0])) class = (data >> 24) & 0xff;
printf(", class=%s", majclasses[data]); subclass = (data >> 16) & 0xff;
if (data < sizeof(subclasses) / sizeof(subclasses[0])) {
const subclass_name *p = subclasses[data];
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 16) & 0xff; if (class < sizeof(majclasses) / sizeof(majclasses[0])) {
while (p->name && (p->subclass != data)) printf(", class=%s", majclasses[class]);
} else {
printf(", class=0x%02x", class);
}
if (subclass < sizeof(subclasses) / sizeof(subclasses[0])) {
const subclass_name *p = subclasses[class];
while (p->name && (p->subclass != subclass))
p++; p++;
if (p->name) { if (p->name) {
printf(" (%s)", p->name); printf(" (%s)", p->name);
} else { } else {
printf(" (unknown subclass 0x%02lx)", data); printf(" (unknown subclass 0x%02lx)", subclass);
} }
} else {
printf(", subclass=0x%02x", subclass);
} }
printf (" [no driver assigned]\n"); data = pcibus->pb_read (tag, PCI_INTERRUPT_REG);
pciint = PCI_INTERRUPT_PIN_EXTRACT(data);
if (pciint) {
printf (" int %c irq ", 0x60+pciint);
irq = PCI_INTERRUPT_LINE_EXTRACT(data);
/*
** If it's zero, the isa irq number is unknown,
** and we cannot bind the pci interrupt.
*/
if (irq && (irq != 0xff))
printf ("%d", irq);
else
printf ("??");
};
if (class != (PCI_CLASS_BRIDGE >> 24))
printf (" [no driver assigned]");
printf ("\n");
if (bootverbose) { if (bootverbose) {
for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) { if (class == (PCI_CLASS_BRIDGE >> 24)) {
data = pcibus->pb_read (tag, reg); printf ("configuration space registers:");
if ((data&~7)==0) continue; for (reg = 0; reg < 0x100; reg+=4) {
switch (data&7) { if ((reg & 0x0f) == 0) printf ("\n%02x:\t", reg);
printf ("%08x ", pcibus->pb_read (tag, reg));
}
printf ("\n");
} else {
for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) {
data = pcibus->pb_read (tag, reg);
if ((data&~7)==0) continue;
switch (data&7) {
case 1: case 1:
case 5: case 5:
printf (" map(%x): io(%lx)\n", printf ("\tmap(%x): io(%04lx)\n",
reg, data & ~3); reg, data & ~3);
break; break;
case 0: case 0:
printf (" map(%x): mem32(%lx)\n", printf ("\tmap(%x): mem32(%08lx)\n",
reg, data & ~7); reg, data & ~7);
break; break;
case 2: case 2:
printf (" map(%x): mem20(%lx)\n", printf ("\tmap(%x): mem20(%05lx)\n",
reg, data & ~7); reg, data & ~7);
break; break;
case 4: case 4:
printf (" map(%x): mem64(%lx)\n", printf ("\tmap(%x): mem64(%08x%08lx)\n",
reg, data & ~7); reg, pcibus->pb_read (tag, reg +4), data & ~7);
reg += 4;
break; break;
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
/************************************************************************** /**************************************************************************
** **
** $Id: pcisupport.c,v 1.30 1996/01/27 20:14:32 wollman Exp $ ** $Id: pcisupport.c,v 1.31 1996/01/28 22:15:46 wollman Exp $
** **
** Device driver for DEC/INTEL PCI chipsets. ** Device driver for DEC/INTEL PCI chipsets.
** **
@ -44,6 +44,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/devconf.h> #include <sys/devconf.h>
@ -77,14 +78,39 @@ struct condmsg {
unsigned char port; unsigned char port;
unsigned char mask; unsigned char mask;
unsigned char value; unsigned char value;
char flags; char flags;
const char *text; const char *text;
}; };
/* make sure formats expand to at least as many chars !!! */
#define PPB_DESCR "generic PCI bridge (vendor=%04x device=%04x subclass=%1.2d)"
static char*
generic_pci_bridge (pcici_t tag)
{
char *descr;
unsigned classreg = pci_conf_read (tag, PCI_CLASS_REG);
if ((classreg & PCI_CLASS_MASK) == PCI_CLASS_BRIDGE) {
unsigned id = pci_conf_read (tag, PCI_ID_REG);
descr = malloc (sizeof PPB_DESCR +1, M_DEVBUF, M_WAITOK);
if (descr) {
sprintf (descr, PPB_DESCR, id & 0xffff, (id >> 16) & 0xffff,
(classreg >> 16) & 0xff);
}
return descr;
}
return 0;
}
static char* static char*
chipset_probe (pcici_t tag, pcidi_t type) chipset_probe (pcici_t tag, pcidi_t type)
{ {
unsigned rev; unsigned rev;
char *descr;
switch (type) { switch (type) {
case 0x04868086: case 0x04868086:
@ -115,11 +141,16 @@ chipset_probe (pcici_t tag, pcidi_t type)
return ("SiS 85c503"); return ("SiS 85c503");
case 0x06011039: case 0x06011039:
return ("SiS 85c601"); return ("SiS 85c601");
case 0x00221014:
return ("IBM 82351 PCI-PCI bridge");
case 0x00011011: case 0x00011011:
return ("DEC 21050 PCI-PCI bridge"); return ("DEC 21050 PCI-PCI bridge");
}; };
return ((char*)0); if (descr = generic_pci_bridge(tag))
return descr;
return NULL;
} }
#ifndef PCI_QUIET #ifndef PCI_QUIET
@ -587,6 +618,12 @@ chipset_attach (pcici_t config_id, int unit)
case 0x122e8086: case 0x122e8086:
writeconfig (config_id, conf82371fb); writeconfig (config_id, conf82371fb);
break; break;
#if 0
case 0x00011011: /* DEC 21050 */
case 0x00221014: /* IBM xxx */
writeconfig (config_id, conf_pci2pci);
break;
#endif
#if 0 #if 0
case 0x12308086: case 0x12308086:
writeconfig (config_id, conf82371fb2); writeconfig (config_id, conf82371fb2);