Fix return value for bad pci config address

PCI config read fails should return all 1 bits.
All unused registers in an existing PCI device should return 0.

Because that's what my Power Mac 8600 returns when I run my Open Firmware lspci command.
Any bus/device/function that doesn't exist returns FF and won't be listed by lspci.
Any registers that are unused will show as 00 in the lspci output.

Make grackle log bus:device.function @register.size in all cases.
This commit is contained in:
joevt 2022-08-24 07:12:35 -07:00
parent 6c59bf4203
commit e41b196977
2 changed files with 27 additions and 24 deletions

View File

@ -90,7 +90,7 @@ uint32_t Bandit::pci_cfg_read(uint32_t reg_offs, uint32_t size)
this->pci_name.c_str(), reg_offs);
}
return 0xFFFFFFFFUL; // PCI spec §6.1
return 0;
}
void Bandit::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size)
@ -131,7 +131,7 @@ uint32_t Bandit::read(uint32_t rgn_start, uint32_t offset, int size)
this->name.c_str(), bus_num, dev_num, fun_num, reg_offs + (offset & 3),
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size
);
return 0;
return 0xFFFFFFFFUL; // PCI spec §6.1
}
idsel = (this->config_addr >> 11) & 0x1FFFFFU;
@ -143,7 +143,7 @@ uint32_t Bandit::read(uint32_t rgn_start, uint32_t offset, int size)
fun_num, reg_offs + (offset & 3),
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size
);
return 0;
return 0xFFFFFFFFUL; // PCI spec §6.1
}
if (idsel == BANDIT_ID_SEL) { // access to myself
@ -304,7 +304,7 @@ uint32_t Chaos::read(uint32_t rgn_start, uint32_t offset, int size)
this->name.c_str(), bus_num, dev_num, fun_num, reg_offs + (offset & 3),
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size
);
return 0;
return 0xFFFFFFFFUL; // PCI spec §6.1
}
idsel = (this->config_addr >> 11) & 0x1FFFFFU;
@ -316,7 +316,7 @@ uint32_t Chaos::read(uint32_t rgn_start, uint32_t offset, int size)
fun_num, reg_offs + (offset & 3),
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size
);
return 0;
return 0xFFFFFFFFUL; // PCI spec §6.1
}
if (this->dev_map.count(idsel)) {

View File

@ -122,19 +122,20 @@ uint32_t MPC106::pci_read(uint32_t size) {
int bus_num, dev_num, fun_num, reg_offs;
bus_num = (this->config_addr >> 8) & 0xFF;
if (bus_num) {
LOG_F(
ERROR,
"%s err: read attempt from non-local PCI bus, config_addr = %x",
this->name.c_str(),
this->config_addr);
return 0;
}
dev_num = (this->config_addr >> 19) & 0x1F;
fun_num = (this->config_addr >> 16) & 0x07;
reg_offs = (this->config_addr >> 24) & 0xFC;
if (bus_num) {
LOG_F(
ERROR,
"%s err: read attempt from non-local PCI bus, config_addr = %x %02x:%02x.%x @%02x.%c",
this->name.c_str(), this->config_addr, bus_num, dev_num, fun_num, reg_offs,
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size
);
return 0xFFFFFFFFUL; // PCI spec §6.1
}
if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself
return this->pci_cfg_read(reg_offs, size);
} else {
@ -147,7 +148,7 @@ uint32_t MPC106::pci_read(uint32_t size) {
this->name.c_str(), bus_num, dev_num, fun_num, reg_offs,
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size
);
return 0;
return 0xFFFFFFFFUL; // PCI spec §6.1
}
}
@ -158,19 +159,21 @@ void MPC106::pci_write(uint32_t value, uint32_t size) {
int bus_num, dev_num, fun_num, reg_offs;
bus_num = (this->config_addr >> 8) & 0xFF;
if (bus_num) {
LOG_F(
ERROR,
"%s err: write attempt to non-local PCI bus, config_addr = %x",
this->name.c_str(),
this->config_addr);
return;
}
dev_num = (this->config_addr >> 19) & 0x1F;
fun_num = (this->config_addr >> 16) & 0x07;
reg_offs = (this->config_addr >> 24) & 0xFC;
if (bus_num) {
LOG_F(
ERROR,
"%s err: write attempt to non-local PCI bus, config_addr = %x %02x:%02x.%x @%02x.%c = %0*x",
this->name.c_str(), this->config_addr, bus_num, dev_num, fun_num, reg_offs,
size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size,
size * 2, value
);
return;
}
if (dev_num == 0 && fun_num == 0) { // dev_num 0 is assigned to myself
this->pci_cfg_write(reg_offs, value, size);
} else {