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.
|
** 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user