diff --git a/devices/common/pci/bandit.cpp b/devices/common/pci/bandit.cpp index 9516046..1255dd4 100644 --- a/devices/common/pci/bandit.cpp +++ b/devices/common/pci/bandit.cpp @@ -31,6 +31,15 @@ along with this program. If not, see . #include +const int MultiplyDeBruijnBitPosition2[] = +{ + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 +}; + +/** finds the position of the bit that is set */ +#define WHAT_BIT_SET(val) (MultiplyDeBruijnBitPosition2[(uint32_t)(val * 0x077CB531U) >> 27]) + Bandit::Bandit(int bridge_num, std::string name) : PCIHost(), PCIDevice(name) { supports_types(HWCompType::PCI_HOST | HWCompType::PCI_DEV); @@ -104,24 +113,36 @@ void Bandit::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) uint32_t Bandit::read(uint32_t reg_start, uint32_t offset, int size) { - int fun_num; + int bus_num, dev_num, fun_num; uint8_t reg_offs; uint32_t result, idsel; if (offset & BANDIT_CONFIG_SPACE) { if (offset & 0x00400000) { + fun_num = (this->config_addr >> 8) & 7; + reg_offs = this->config_addr & 0xFCU; + // access to the CONFIG_DATA pseudo-register causes a Config Cycle if (this->config_addr & BANDIT_CAR_TYPE) { - LOG_F(WARNING, "%s: config cycle type 1 not supported yet", this->name.c_str()); + bus_num = (this->config_addr >> 16) & 255; + dev_num = (this->config_addr >> 11) & 31; + LOG_F( + WARNING, "%s: read config cycle type 1 not supported yet %02x:%02x.%x @%02x.%c", + 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; } - idsel = (this->config_addr >> 11) & 0x1FFFFFU; - fun_num = (this->config_addr >> 8) & 7; - reg_offs = this->config_addr & 0xFCU; + idsel = (this->config_addr >> 11) & 0x1FFFFFU; if (!SINGLE_BIT_SET(idsel)) { - LOG_F(ERROR, "%s: invalid IDSEL=0x%X passed", this->name.c_str(), idsel); + LOG_F( + ERROR, "%s: read invalid IDSEL=0x%X config:0x%X ??:??.%x? @%02x?.%c", + this->name.c_str(), idsel, this->config_addr, + fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size + ); return 0; } @@ -131,11 +152,12 @@ uint32_t Bandit::read(uint32_t reg_start, uint32_t offset, int size) if (this->dev_map.count(idsel)) { result = this->dev_map[idsel]->pci_cfg_read(reg_offs, size); } else { + dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( - ERROR, - "%s err: read attempt from non-existing PCI device %d", - this->name.c_str(), - idsel); + ERROR, "%s err: read attempt from non-existing PCI device ??:%02x.%x @%02x.%c", + this->name.c_str(), dev_num, fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size + ); return 0xFFFFFFFFUL; // PCI spec §6.1 } } @@ -158,24 +180,36 @@ uint32_t Bandit::read(uint32_t reg_start, uint32_t offset, int size) void Bandit::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size) { - int fun_num; + int bus_num, dev_num, fun_num; uint8_t reg_offs; uint32_t idsel; if (offset & BANDIT_CONFIG_SPACE) { if (offset & 0x00400000) { + fun_num = (this->config_addr >> 8) & 7; + reg_offs = this->config_addr & 0xFCU; + // access to the CONFIG_DATA pseudo-register causes a Config Cycle if (this->config_addr & BANDIT_CAR_TYPE) { - LOG_F(WARNING, "%s: config cycle type 1 not supported yet", this->name.c_str()); + bus_num = (this->config_addr >> 16) & 255; + dev_num = (this->config_addr >> 11) & 31; + LOG_F( + WARNING, "%s: write config cycle type 1 not supported yet %02x:%02x.%x @%02x.%c = %0*x", + 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, size * 2, value + ); return; } - idsel = (this->config_addr >> 11) & 0x1FFFFFU; - fun_num = (this->config_addr >> 8) & 7; - reg_offs = this->config_addr & 0xFCU; + idsel = (this->config_addr >> 11) & 0x1FFFFFU; if (!SINGLE_BIT_SET(idsel)) { - LOG_F(ERROR, "%s: invalid IDSEL=0x%X passed", this->name.c_str(), idsel); + LOG_F( + ERROR, "%s: write invalid IDSEL=0x%X config:0x%X ??:??.%x? @%02x?.%c = %0*x", + this->name.c_str(), idsel, this->config_addr, + fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value + ); return; } @@ -187,11 +221,12 @@ void Bandit::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size if (this->dev_map.count(idsel)) { this->dev_map[idsel]->pci_cfg_write(reg_offs, value, size); } else { + dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( - ERROR, - "%s err: write attempt to non-existing PCI device %d", - this->name.c_str(), - idsel); + ERROR, "%s err: write attempt to non-existing PCI device ??:%02x.%x @%02x.%c = %0*x", + this->name.c_str(), dev_num, fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value + ); } } else { this->config_addr = BYTESWAP_32(value); @@ -251,29 +286,48 @@ Chaos::Chaos(std::string name) : PCIHost() uint32_t Chaos::read(uint32_t reg_start, uint32_t offset, int size) { - int fun_num; + int bus_num, dev_num, fun_num; uint8_t reg_offs; uint32_t result, idsel; if (offset & BANDIT_CONFIG_SPACE) { if (offset & 0x00400000) { - idsel = (this->config_addr >> 11) & 0x1FFFFFU; - fun_num = (this->config_addr >> 8) & 7; + fun_num = (this->config_addr >> 8) & 7; reg_offs = this->config_addr & 0xFCU; + // access to the CONFIG_DATA pseudo-register causes a Config Cycle + if (this->config_addr & BANDIT_CAR_TYPE) { + bus_num = (this->config_addr >> 16) & 255; + dev_num = (this->config_addr >> 11) & 31; + LOG_F( + WARNING, "%s: read config cycle type 1 not supported yet %02x:%02x.%x @%02x.%c", + 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; + } + + idsel = (this->config_addr >> 11) & 0x1FFFFFU; + if (!SINGLE_BIT_SET(idsel)) { - LOG_F(ERROR, "%s: invalid IDSEL=0x%X passed", this->name.c_str(), idsel); + LOG_F( + ERROR, "%s: read invalid IDSEL=0x%X config:0x%X ??:??.%x? @%02x?.%c", + this->name.c_str(), idsel, this->config_addr, + fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size + ); return 0; } if (this->dev_map.count(idsel)) { result = this->dev_map[idsel]->pci_cfg_read(reg_offs, size); } else { + dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( - ERROR, - "%s err: read attempt from non-existing VCI device %d", - this->name.c_str(), - idsel); + ERROR, "%s err: read attempt from non-existing VCI device ??:%02x.%x @%02x.%c", + this->name.c_str(), dev_num, fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size + ); return 0xFFFFFFFFUL; // PCI spec §6.1 } } else { @@ -288,35 +342,48 @@ uint32_t Chaos::read(uint32_t reg_start, uint32_t offset, int size) void Chaos::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size) { - int fun_num; + int bus_num, dev_num, fun_num; uint8_t reg_offs; uint32_t idsel; if (offset & BANDIT_CONFIG_SPACE) { if (offset & 0x00400000) { + fun_num = (this->config_addr >> 8) & 7; + reg_offs = this->config_addr & 0xFCU; + // access to the CONFIG_DATA pseudo-register causes a Config Cycle if (this->config_addr & BANDIT_CAR_TYPE) { - LOG_F(WARNING, "%s: config cycle type 1 not supported yet", this->name.c_str()); + bus_num = (this->config_addr >> 16) & 255; + dev_num = (this->config_addr >> 11) & 31; + LOG_F( + WARNING, "%s: write config cycle type 1 not supported yet %02x:%02x.%x @%02x.%c = %0*x", + 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, size * 2, value + ); return; } - idsel = (this->config_addr >> 11) & 0x1FFFFFU; - fun_num = (this->config_addr >> 8) & 7; - reg_offs = this->config_addr & 0xFCU; + idsel = (this->config_addr >> 11) & 0x1FFFFFU; if (!SINGLE_BIT_SET(idsel)) { - LOG_F(ERROR, "%s: invalid IDSEL=0x%X passed", this->name.c_str(), idsel); + LOG_F( + ERROR, "%s: write invalid IDSEL=0x%X config:0x%X ??:??.%x? @%02x?.%c = %0*x", + this->name.c_str(), idsel, this->config_addr, + fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value + ); return; } if (this->dev_map.count(idsel)) { this->dev_map[idsel]->pci_cfg_write(reg_offs, value, size); } else { + dev_num = WHAT_BIT_SET(idsel) + 11; LOG_F( - ERROR, - "%s err: write attempt to non-existing VCI device %d", - this->name.c_str(), - idsel); + ERROR, "%s err: write attempt to non-existing VCI device ??:%02x.%x @%02x.%c = %0*x", + this->name.c_str(), dev_num, fun_num, reg_offs + (offset & 3), + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value + ); } } else { this->config_addr = BYTESWAP_32(value); diff --git a/devices/common/pci/pcidevice.cpp b/devices/common/pci/pcidevice.cpp index 71523d1..4d0db09 100644 --- a/devices/common/pci/pcidevice.cpp +++ b/devices/common/pci/pcidevice.cpp @@ -84,8 +84,11 @@ uint32_t PCIDevice::pci_cfg_read(uint32_t reg_offs, uint32_t size) result = (max_lat << 24) | (min_gnt << 16) | (irq_pin << 8) | irq_line; break; default: - LOG_F(WARNING, "%s: attempt to read from reserved/unimplemented register %d", - this->pci_name.c_str(), reg_offs); + LOG_F( + WARNING, "%s: attempt to read from reserved/unimplemented register @%02x.%c", + this->pci_name.c_str(), reg_offs, + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size + ); return 0; } @@ -147,8 +150,11 @@ void PCIDevice::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) this->irq_line = data >> 24; break; default: - LOG_F(WARNING, "%s: attempt to write to reserved/unimplemented register %d", - this->pci_name.c_str(), reg_offs); + LOG_F( + WARNING, "%s: attempt to write to reserved/unimplemented register @%02x.%c = %0*x", + this->pci_name.c_str(), reg_offs, + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, size * 2, value + ); } } diff --git a/devices/memctrl/mpc106.cpp b/devices/memctrl/mpc106.cpp index 05e7f0d..407af00 100644 --- a/devices/memctrl/mpc106.cpp +++ b/devices/memctrl/mpc106.cpp @@ -143,9 +143,10 @@ uint32_t MPC106::pci_read(uint32_t size) { } else { LOG_F( ERROR, - "%s err: read attempt from non-existing PCI device %d", - this->name.c_str(), - dev_num); + "%s err: read attempt from non-existing PCI device %02x:%02x.%x @%02x.%c", + 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; } } @@ -178,9 +179,11 @@ void MPC106::pci_write(uint32_t value, uint32_t size) { } else { LOG_F( ERROR, - "%s err: write attempt to non-existing PCI device %d", - this->name.c_str(), - dev_num); + "%s err: write attempt to non-existing PCI device %02x:%02x.%x @%02x.%c = %0*x", + this->name.c_str(), bus_num, dev_num, fun_num, reg_offs, + size == 4 ? 'l' : size == 2 ? 'w' : size == 1 ? 'b' : '0' + size, + size * 2, value + ); } } }