Browse Source

Fix PCI scan bugs and clean pciconf.c file.

1. fix error on PCI bridge BAR space allocation.
2. fix error on PCI bridge expand ROM space allocation.
3. fix 7A/2K PCIE bridge wrong class/subclass code bug by fake the configure access return value.

Change-Id: I19a15959b2c4046f773707a3c605e893c3cf378c
master
Chen Xinke 7 years ago
committed by zhangbaoqi
parent
commit
122984b983
  1. 8
      Targets/Bonito3a3000_7a/pci/ls7a_pci.c
  2. 4
      Targets/LS2K/pci/ls2k_pci.c
  3. 151
      sys/dev/pci/pciconf.c
  4. 3
      sys/dev/pci/pcireg.h
  5. 9
      sys/dev/pci/ppb.c

8
Targets/Bonito3a3000_7a/pci/ls7a_pci.c

@ -64,10 +64,11 @@ u32 _pci_conf_readn(device_t tag, int reg, int width)
}
_pci_break_tag (tag, &bus, &device, &function);
//skip scan of some devices
//if(bus == 0 && device <= 2) return -1;
//if(bus == 0 && device == 31) return -1;
if(bus != 0 && device != 0) return -1;
//workaround pcie header
if(bus == 0 && (device >=9 && device <= 20) && reg == 0x8){
return 0x06040001;
}
if (bus == 0) {
/* Type 0 configuration on onboard PCI bus */
@ -76,7 +77,6 @@ u32 _pci_conf_readn(device_t tag, int reg, int width)
printf("_pci_conf_readn: bad device 0x%x, function 0x%x\n", device, function);
return ~0; /* device out of range */
}
//if(bus == 0 && device == 6 && reg == 0x20) return 0;
return pci_read_type0_config32(device, function, reg);
} else {
/* Type 1 configuration on offboard PCI bus */

4
Targets/LS2K/pci/ls2k_pci.c

@ -52,6 +52,10 @@ u32 _pci_conf_readn(device_t tag, int reg, int width)
_pci_break_tag (tag, &bus, &device, &function);
if(bus == 0 && device == 2) return -1;
//workaround pcie header
if(bus == 0 && (device >=9 && device <= 14) && reg == 0x8){
return 0x06040001;
}
if (bus == 0) {
/* Type 0 configuration on onboard PCI bus */

151
sys/dev/pci/pciconf.c

@ -73,9 +73,6 @@
extern char *getenv __P((const char *));
extern long atol __P((const char *));
extern void *pmalloc __P((size_t ));
extern void pfree __P((void * ));
@ -205,6 +202,7 @@ static inline int fls(int x)
* requirements.
*/
static void
_pci_query_dev_func (struct pci_device *dev, pcitag_t tag, int initialise)
{
pcireg_t id, class;
@ -216,9 +214,7 @@ _pci_query_dev_func (struct pci_device *dev, pcitag_t tag, int initialise)
struct pci_device *pd;
unsigned int x;
int bus, device, function;
#if defined(LOONGSON_2K)
int isbridge = 0;
#endif
class = _pci_conf_read(tag, PCI_CLASS_REG);
id = _pci_conf_read(tag, PCI_ID_REG);
@ -323,19 +319,13 @@ _pci_query_dev_func (struct pci_device *dev, pcitag_t tag, int initialise)
/*
* Check to see if device is a PCI Bridge
*/
#if defined(LOONGSON_2K)
if (PCI_ISCLASS(class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) || PCI_ISCLASS(class, PCI_CLASS_PROCESSOR, 0x30)) {
isbridge = 1;
#elif defined(LS7A)
if (PCI_ISCLASS(class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST)) {
#else
if (PCI_ISCLASS(class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI)) {
#endif
struct pci_device *pcidev;
struct pci_win *pm_mem = NULL;
struct pci_win *pm_io = NULL;
struct pci_win *pm;
pcireg_t tmp;
isbridge = 1;
pd->bridge.pribus_num = bus;
pd->bridge.secbus_num = ++_pci_nbus;
@ -351,6 +341,7 @@ _pci_query_dev_func (struct pci_device *dev, pcitag_t tag, int initialise)
/* Update sub bus number */
for(pcidev = dev; pcidev != NULL; pcidev = pcidev->parent) {
//printf("pcidev = 0x%x\n", pcidev);
pcidev->bridge.subbus_num = pd->bridge.secbus_num;
tmp = _pci_conf_read(pcidev->pa.pa_tag, PCI_PRIBUS_1);
tmp &= 0xff00ffff;
@ -385,7 +376,7 @@ _pci_query_dev_func (struct pci_device *dev, pcitag_t tag, int initialise)
/*
* Sum up the address space needed by secondary side of bridge
*/
if(pm_io == NULL) {
if(pm_io == NULL) {
pm_io = pmalloc(sizeof(struct pci_win));
if(pm_io == NULL) {
PRINTF ("pci: can't alloc memory for pci memory window\n");
@ -408,8 +399,8 @@ if(pm_io == NULL) {
pm_mem->flags = PCI_MAPREG_MEM_TYPE_32BIT;
}
/* Sum up I/O Space needed */
{
int max=0;
for(pm = pd->bridge.iospace; pm != NULL; pm = pm->next) {
if(max < pm->align)
@ -421,8 +412,10 @@ if(pm_io == NULL) {
pd->bridge.io_mask = ~(max-1);
pm_io->align = max;
}
/* Sum up Memory Space needed */
max=0;
{
int max = 0;
for(pm = pd->bridge.memspace; pm != NULL; pm = pm->next) {
if(max < pm->align)
max = pm->align;
@ -432,19 +425,20 @@ if(pm_io == NULL) {
if(max<0x100000) max = 0x100000;
pd->bridge.mem_mask = ~(max-1);
pm_mem->align = max;
/* Round to minimum granularity requierd for a bridge */
pm_io->size = _pci_roundup(pm_io->size, 0x1000);
pm_mem->size = _pci_roundup(pm_mem->size, 0x100000);
}
if(pm_io) {
/* Round to minimum granularity requierd for a bridge */
pm_io->size = _pci_roundup(pm_io->size, 0x1000);
_insertsort_window(&pd->parent->bridge.iospace, pm_io);
}
if(pm_mem) {
/* Round to minimum granularity requierd for a bridge */
pm_mem->size = _pci_roundup(pm_mem->size, 0x100000);
_insertsort_window(&pd->parent->bridge.memspace,pm_mem);
}
}
else if (PCI_ISCLASS(class, PCI_CLASS_MASS_STORAGE,
PCI_SUBCLASS_MASS_STORAGE_IDE) &&
else if (PCI_ISCLASS(class, PCI_CLASS_MASS_STORAGE, PCI_SUBCLASS_MASS_STORAGE_IDE) &&
dev->bridge.secbus->minpciioaddr == 0) {
/*
* There is no need to setup memory regions for IDE storage devices
@ -452,19 +446,12 @@ if(pm_io == NULL) {
*/
return;
#if defined(LOONGSON_2K)
}
//set BAR for this dev
{
#else
} else {
#endif
int skipnext = 0;
#if defined(LOONGSON_2K)
for (reg = PCI_MAPREG_START; reg < (isbridge?PCI_MAPREG_PPB_END:PCI_MAPREG_END); reg += 4) {
#else
for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END; reg += 4) {
#endif
for (reg = PCI_MAPREG_START; reg < (isbridge ? PCI_MAPREG_PPB_END : PCI_MAPREG_END); reg += 4) {
struct pci_win *pm;
if (skipnext) {
@ -482,8 +469,7 @@ if(pm_io == NULL) {
}
if (_pciverbose >= 3) {
_pci_tagprintf (tag, "reg 0x%x = 0x%x\n",
reg, mask);
_pci_tagprintf (tag, "reg 0x%x = 0x%x\n", reg, mask);
}
if (PCI_MAPREG_TYPE(mask) == PCI_MAPREG_TYPE_IO) {
@ -530,21 +516,14 @@ if(pm_io == NULL) {
pm->reg = reg;
pm->flags = PCI_MAPREG_MEM_TYPE_32BIT;
pm->size = -(PCI_MAPREG_MEM_ADDR(mask));
#ifdef USE_BMC || defined(CONFIG_GFXUMA)
if(PCI_ISCLASS(((pd->pa.pa_class)&0xff00ffff), PCI_CLASS_DISPLAY, PCI_SUBCLASS_DISPLAY_VGA)){
if(reg==0x10){
pm->size = VRAM_SIZE<<20;
printf("pm->size = %08x\n", pm->size);
}
}
#endif
pm->align = pm->size;
_insertsort_window(&pd->parent->bridge.memspace, pm);
}
}
{
/* Finally check for Expansion ROM */
reg = PCI_MAPREG_ROM;
reg = isbridge ? PCI_MAPREG_PPB_ROM : PCI_MAPREG_ROM;
old = _pci_conf_read(tag, reg);
_pci_conf_write(tag, reg, 0xfffffffe);
mask = _pci_conf_read(tag, reg);
@ -569,6 +548,7 @@ if(pm_io == NULL) {
_insertsort_window(&pd->parent->bridge.memspace, pm);
}
}
}
}
static int
@ -618,7 +598,7 @@ static void
_pci_query_dev (struct pci_device *dev, int bus, int device, int initialise)
{
pcitag_t tag;
pcireg_t id, typ;
pcireg_t id;
pcireg_t misc;
tag = _pci_make_tag(bus, device, 0);
@ -641,7 +621,6 @@ _pci_query_dev (struct pci_device *dev, int bus, int device, int initialise)
#endif
delay(1000); //fix that the correct id sometimes can not read;
id = _pci_conf_read(tag, PCI_ID_REG);
typ = _pci_conf_read(tag, PCI_CLASS_REG);
if (_pciverbose >= 2) {
PRINTF ("completed\n");
@ -681,7 +660,6 @@ _pci_query_dev (struct pci_device *dev, int bus, int device, int initialise)
_pci_query_dev_func (dev, tag, initialise);
}
}
pcireg_t
_pci_allocate_mem(dev, size, align)
@ -774,6 +752,7 @@ _pci_setup_windows (struct pci_device *dev)
pd = pm->device;
next = pm->next;
if(pd->bridge.child) align = ~pd->bridge.mem_mask+1;
else align = 1<<(fls(pm->size)-1);
@ -793,26 +772,12 @@ _pci_setup_windows (struct pci_device *dev)
if (_pciverbose >= 2)
_pci_tagprintf (pd->pa.pa_tag, "mem @%p, reg 0x%x %d bytes\n", pm->address, pm->reg, pm->size);
#if defined(LOONGSON_2K)
if ((PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) || PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_PROCESSOR, 0x30)) &&
(pm->reg == PCI_MEMBASE_1)) {
if (PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) && (pm->reg == PCI_MEMBASE_1)) {
pcireg_t memory;
pm->address = (pm->address + (~pd->bridge.mem_mask))& pd->bridge.mem_mask; //yang23 2013-11-26
dev->bridge.secbus->minpcimemaddr = pm->address + pm->size; //yang23 2013-11-26
#elif defined(LS7A)
if (PCI_ISCLASS(pd->pa.pa_class,
PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST) &&
(pm->reg == PCI_MEMBASE_1)) {
pcireg_t memory;
#else
if (PCI_ISCLASS(pd->pa.pa_class,
PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) &&
(pm->reg == PCI_MEMBASE_1)) {
pcireg_t memory;
#endif
pd->bridge.secbus->minpcimemaddr = pm->address;
pd->bridge.secbus->nextpcimemaddr = pm->address + pm->size;
@ -884,13 +849,14 @@ _pci_setup_windows (struct pci_device *dev)
pm->address = 0x000c0000; /* XXX PCI MEM @ 0x000!!! */
}
#endif
if (pm->reg == PCI_MAPREG_ROM) {
if ((PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) && (pm->reg == PCI_MAPREG_PPB_ROM)) || (pm->reg == PCI_MAPREG_ROM)) {
/* expansion rom */
if (_pciverbose >= 2)
_pci_tagprintf (pd->pa.pa_tag, "exp @%p, %d bytes\n",
pm->address, pm->size);
if (_pciverbose >= 2){
_pci_tagprintf (pd->pa.pa_tag, "exp @%p, %d bytes\n", pm->address, pm->size);
}
_pci_conf_write(pd->pa.pa_tag, pm->reg, pm->address | PCI_MAPREG_TYPE_ROM);
}
next = pm->next;
dev->bridge.memspace = next;
pfree(pm);
@ -901,6 +867,7 @@ _pci_setup_windows (struct pci_device *dev)
pd = pm->device;
next = pm->next;
if(pd->bridge.child) align = ~pd->bridge.io_mask+1;
else align = 1<<(fls(pm->size)-1);
@ -913,23 +880,10 @@ _pci_setup_windows (struct pci_device *dev)
pci_bigio_address += pm->size;
}
if (_pciverbose >= 2)
#if defined(LOONGSON_2K)
_pci_tagprintf (pd->pa.pa_tag, "i/o @%p, reg 0x%x %d bytes\n", pm->address, pm->reg, pm->size);
if ((PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) || PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_PROCESSOR, 0x30)) &&
(pm->reg == PCI_IOBASEL_1)) {
#elif defined(LS7A)
_pci_tagprintf (pd->pa.pa_tag, "i/o @%p, %d bytes\n", pm->address, pm->size);
if (PCI_ISCLASS(pd->pa.pa_class,
PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST) &&
(pm->reg == PCI_IOBASEL_1)) {
#else
_pci_tagprintf (pd->pa.pa_tag, "i/o @%p, %d bytes\n", pm->address, pm->size);
if (PCI_ISCLASS(pd->pa.pa_class,
PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) &&
if (PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) &&
(pm->reg == PCI_IOBASEL_1)) {
#endif
pcireg_t tmp;
pd->bridge.secbus->minpciioaddr = pm->address;
@ -944,31 +898,6 @@ _pci_setup_windows (struct pci_device *dev)
tmp = (pm->address >> 16) & 0xffff;
tmp |= ((pm->address + pm->size-1) & 0xffff0000);
_pci_conf_write(pd->pa.pa_tag,PCI_IOBASEH_1, tmp);
/*
//first to identify whether 32-bit IO space is supported
//added by whd
if(tmp & 0x1){
tmp &= 0xffff0000;
tmp |= (pm->address >> 8) & 0xf0;
tmp |= ((pm->address + pm->size) & 0xf000);
//printf("whd:IO space of bridge : pd->pa.pa_tag = %X,PCI_IOBASEL_1 = %X, tmp= %X, pm->address + pm->size = %X\n",pd->pa.pa_tag,PCI_IOBASEL_1, tmp,pm->address + pm->size);
_pci_conf_write(pd->pa.pa_tag,PCI_IOBASEL_1, tmp);
tmp = (pm->address >> 16) & 0xffff;
tmp |= ((pm->address + pm->size) & 0xffff0000);
//printf("whd:IO space of bridge : pd->pa.pa_tag = %X,PCI_IOBASEH_1 = %X, tmp= %X\n",pd->pa.pa_tag,PCI_IOBASEH_1, tmp);
_pci_conf_write(pd->pa.pa_tag,PCI_IOBASEH_1, tmp);
} else {//do NOT support
tmp &= 0xffff0000;
tmp |= (pm->address >> 8) & 0xf0;
if((pm->address + pm->size) > 0xffff)
tmp |= 0xf000;
else
tmp |= ((pm->address + pm->size) & 0xf000);
//printf("whd:IO space of bridge : pd->pa.pa_tag = %X,PCI_IOBASEL_1 = %X, tmp= %X, pm->address + pm->size = %X\n",pd->pa.pa_tag,PCI_IOBASEL_1, tmp,pm->address + pm->size);
_pci_conf_write(pd->pa.pa_tag,PCI_IOBASEL_1, tmp);
}
*/
}
else {
@ -980,15 +909,7 @@ _pci_setup_windows (struct pci_device *dev)
/* Recursive allocate memory for secondary buses */
for(pd = dev->bridge.child; pd != NULL; pd = pd->next) {
#if defined(LOONGSON_2K)
if (PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) || PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_PROCESSOR, 0x30)) {
#elif defined(LS7A)
if (PCI_ISCLASS(pd->pa.pa_class,
PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_HOST)) {
#else
if (PCI_ISCLASS(pd->pa.pa_class,
PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI)) {
#endif
if (PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI)) {
_pci_setup_windows(pd);
}
}
@ -1124,13 +1045,7 @@ _pci_setup_devices (struct pci_device *parent, int initialise)
| ((PCI_CACHE_LINE_SIZE & 0xff) << PCI_CACHELINE_SHIFT);
_pci_conf_write (tag, PCI_BHLC_REG, misc);
#if defined(LOONGSON_2K)
if(PCI_CLASS(class) == PCI_CLASS_BRIDGE || PCI_CLASS(class) == PCI_CLASS_PROCESSOR ||
PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_PCI || pd->bridge.child != NULL) {
#else
if(PCI_CLASS(class) == PCI_CLASS_BRIDGE ||
PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_PCI || pd->bridge.child != NULL) {
#endif
if((PCI_CLASS(class) == PCI_CLASS_BRIDGE && PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_PCI) || pd->bridge.child != NULL) {
_pci_setup_devices (pd, initialise);
}
}
@ -1148,7 +1063,7 @@ _pci_businit (int init)
if (v) {
_pciverbose = atol(v);
}
tgt_putchar('2');
tgt_putchar('2');
/* intialise the PCI bridge */
if (/*init*/ 1) {

3
sys/dev/pci/pcireg.h

@ -376,8 +376,9 @@ typedef u_int8_t pci_revision_t;
*/
#define PCI_MAPREG_START 0x10
#define PCI_MAPREG_END 0x28
#define PCI_MAPREG_ROM 0x30
#define PCI_MAPREG_PPB_END 0x18
#define PCI_MAPREG_ROM 0x30
#define PCI_MAPREG_PPB_ROM 0x38
#define PCI_MAPREG_PCB_END 0x14
#define PCI_MAPREG_TYPE(mr) \

9
sys/dev/pci/ppb.c

@ -81,14 +81,7 @@ ppbmatch(parent, match, aux)
* If it is, we assume that we can deal with it; it _should_
* work in a standardized way...
*/
#if defined(LOONGSON_2K)
if (PCI_ISCLASS(pa->pa_class, PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) || PCI_ISCLASS(pa->pa_class, PCI_CLASS_PROCESSOR, 0x30))
#elif defined (LS7A)
if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && pa->pa_id == 0x7a290014)
#else
if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI)
#endif
if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI)
return (1);
return (0);

Loading…
Cancel
Save