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:
parent
2e32d69db1
commit
07d9d14a55
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14133
@ -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.
|
||||
** pci_configure ()
|
||||
@ -474,6 +474,8 @@ pci_bus_config (void)
|
||||
|
||||
real_device:
|
||||
|
||||
#ifndef PCI_QUIET
|
||||
#ifdef PCI_BRIDGE_DEBUG
|
||||
if (bootverbose) {
|
||||
printf ("\tconfig header: 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
pci_conf_read (tag, 0),
|
||||
@ -481,6 +483,8 @@ pci_bus_config (void)
|
||||
pci_conf_read (tag, 8),
|
||||
pci_conf_read (tag, 12));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (func == 0 && pci_mfdev (bus_no, device)) {
|
||||
maxfunc = 7;
|
||||
@ -1563,7 +1567,7 @@ static struct vt VendorTable[] = {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char subclass;
|
||||
const int subclass;
|
||||
const char *name;
|
||||
} subclass_name;
|
||||
|
||||
@ -1659,9 +1663,13 @@ static const char *const majclasses[] = {
|
||||
|
||||
void not_supported (pcici_t tag, u_long type)
|
||||
{
|
||||
u_char reg;
|
||||
u_long reg;
|
||||
u_long data;
|
||||
u_char class;
|
||||
u_char subclass;
|
||||
struct vt * vp;
|
||||
int pciint;
|
||||
int irq;
|
||||
|
||||
/*
|
||||
** lookup the names.
|
||||
@ -1680,47 +1688,86 @@ void not_supported (pcici_t tag, u_long type)
|
||||
|
||||
printf (", device=0x%04lx", type >> 16);
|
||||
|
||||
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
|
||||
if (data < sizeof(majclasses) / sizeof(majclasses[0]))
|
||||
printf(", class=%s", majclasses[data]);
|
||||
if (data < sizeof(subclasses) / sizeof(subclasses[0])) {
|
||||
const subclass_name *p = subclasses[data];
|
||||
data = pcibus->pb_read(tag, PCI_CLASS_REG);
|
||||
class = (data >> 24) & 0xff;
|
||||
subclass = (data >> 16) & 0xff;
|
||||
|
||||
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 16) & 0xff;
|
||||
while (p->name && (p->subclass != data))
|
||||
if (class < sizeof(majclasses) / sizeof(majclasses[0])) {
|
||||
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++;
|
||||
if (p->name) {
|
||||
printf(" (%s)", p->name);
|
||||
} 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) {
|
||||
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) {
|
||||
if (class == (PCI_CLASS_BRIDGE >> 24)) {
|
||||
printf ("configuration space registers:");
|
||||
for (reg = 0; reg < 0x100; reg+=4) {
|
||||
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 5:
|
||||
printf (" map(%x): io(%lx)\n",
|
||||
printf ("\tmap(%x): io(%04lx)\n",
|
||||
reg, data & ~3);
|
||||
break;
|
||||
case 0:
|
||||
printf (" map(%x): mem32(%lx)\n",
|
||||
printf ("\tmap(%x): mem32(%08lx)\n",
|
||||
reg, data & ~7);
|
||||
break;
|
||||
case 2:
|
||||
printf (" map(%x): mem20(%lx)\n",
|
||||
printf ("\tmap(%x): mem20(%05lx)\n",
|
||||
reg, data & ~7);
|
||||
break;
|
||||
case 4:
|
||||
printf (" map(%x): mem64(%lx)\n",
|
||||
reg, data & ~7);
|
||||
printf ("\tmap(%x): mem64(%08x%08lx)\n",
|
||||
reg, pcibus->pb_read (tag, reg +4), data & ~7);
|
||||
reg += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
** pci_configure ()
|
||||
@ -474,6 +474,8 @@ pci_bus_config (void)
|
||||
|
||||
real_device:
|
||||
|
||||
#ifndef PCI_QUIET
|
||||
#ifdef PCI_BRIDGE_DEBUG
|
||||
if (bootverbose) {
|
||||
printf ("\tconfig header: 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||
pci_conf_read (tag, 0),
|
||||
@ -481,6 +483,8 @@ pci_bus_config (void)
|
||||
pci_conf_read (tag, 8),
|
||||
pci_conf_read (tag, 12));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (func == 0 && pci_mfdev (bus_no, device)) {
|
||||
maxfunc = 7;
|
||||
@ -1563,7 +1567,7 @@ static struct vt VendorTable[] = {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char subclass;
|
||||
const int subclass;
|
||||
const char *name;
|
||||
} subclass_name;
|
||||
|
||||
@ -1659,9 +1663,13 @@ static const char *const majclasses[] = {
|
||||
|
||||
void not_supported (pcici_t tag, u_long type)
|
||||
{
|
||||
u_char reg;
|
||||
u_long reg;
|
||||
u_long data;
|
||||
u_char class;
|
||||
u_char subclass;
|
||||
struct vt * vp;
|
||||
int pciint;
|
||||
int irq;
|
||||
|
||||
/*
|
||||
** lookup the names.
|
||||
@ -1680,47 +1688,86 @@ void not_supported (pcici_t tag, u_long type)
|
||||
|
||||
printf (", device=0x%04lx", type >> 16);
|
||||
|
||||
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
|
||||
if (data < sizeof(majclasses) / sizeof(majclasses[0]))
|
||||
printf(", class=%s", majclasses[data]);
|
||||
if (data < sizeof(subclasses) / sizeof(subclasses[0])) {
|
||||
const subclass_name *p = subclasses[data];
|
||||
data = pcibus->pb_read(tag, PCI_CLASS_REG);
|
||||
class = (data >> 24) & 0xff;
|
||||
subclass = (data >> 16) & 0xff;
|
||||
|
||||
data = (pcibus->pb_read(tag, PCI_CLASS_REG) >> 16) & 0xff;
|
||||
while (p->name && (p->subclass != data))
|
||||
if (class < sizeof(majclasses) / sizeof(majclasses[0])) {
|
||||
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++;
|
||||
if (p->name) {
|
||||
printf(" (%s)", p->name);
|
||||
} 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) {
|
||||
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) {
|
||||
if (class == (PCI_CLASS_BRIDGE >> 24)) {
|
||||
printf ("configuration space registers:");
|
||||
for (reg = 0; reg < 0x100; reg+=4) {
|
||||
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 5:
|
||||
printf (" map(%x): io(%lx)\n",
|
||||
printf ("\tmap(%x): io(%04lx)\n",
|
||||
reg, data & ~3);
|
||||
break;
|
||||
case 0:
|
||||
printf (" map(%x): mem32(%lx)\n",
|
||||
printf ("\tmap(%x): mem32(%08lx)\n",
|
||||
reg, data & ~7);
|
||||
break;
|
||||
case 2:
|
||||
printf (" map(%x): mem20(%lx)\n",
|
||||
printf ("\tmap(%x): mem20(%05lx)\n",
|
||||
reg, data & ~7);
|
||||
break;
|
||||
case 4:
|
||||
printf (" map(%x): mem64(%lx)\n",
|
||||
reg, data & ~7);
|
||||
printf ("\tmap(%x): mem64(%08x%08lx)\n",
|
||||
reg, pcibus->pb_read (tag, reg +4), data & ~7);
|
||||
reg += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
**
|
||||
@ -44,6 +44,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/devconf.h>
|
||||
|
||||
@ -77,14 +78,39 @@ struct condmsg {
|
||||
unsigned char port;
|
||||
unsigned char mask;
|
||||
unsigned char value;
|
||||
char flags;
|
||||
const char *text;
|
||||
char flags;
|
||||
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*
|
||||
chipset_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
unsigned rev;
|
||||
char *descr;
|
||||
|
||||
switch (type) {
|
||||
case 0x04868086:
|
||||
@ -115,11 +141,16 @@ chipset_probe (pcici_t tag, pcidi_t type)
|
||||
return ("SiS 85c503");
|
||||
case 0x06011039:
|
||||
return ("SiS 85c601");
|
||||
case 0x00221014:
|
||||
return ("IBM 82351 PCI-PCI bridge");
|
||||
case 0x00011011:
|
||||
return ("DEC 21050 PCI-PCI bridge");
|
||||
};
|
||||
|
||||
return ((char*)0);
|
||||
if (descr = generic_pci_bridge(tag))
|
||||
return descr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef PCI_QUIET
|
||||
@ -587,6 +618,12 @@ chipset_attach (pcici_t config_id, int unit)
|
||||
case 0x122e8086:
|
||||
writeconfig (config_id, conf82371fb);
|
||||
break;
|
||||
#if 0
|
||||
case 0x00011011: /* DEC 21050 */
|
||||
case 0x00221014: /* IBM xxx */
|
||||
writeconfig (config_id, conf_pci2pci);
|
||||
break;
|
||||
#endif
|
||||
#if 0
|
||||
case 0x12308086:
|
||||
writeconfig (config_id, conf82371fb2);
|
||||
|
Loading…
Reference in New Issue
Block a user