From b47212374631192966e6510fd812ed78f5f7b92b Mon Sep 17 00:00:00 2001 From: joevt Date: Sun, 5 Feb 2023 00:37:29 -0800 Subject: [PATCH] Standardize PCIDevice slot_id for PCIHost. PCIHost - PCIHosts (bandit and grackle) now use device number and function number for identifying attached PCIDevices. A macro DEV_FUN is added to calculate this new slot_id. Bandit no longer uses IDSEL. Grackle no longer uses only device number. machinecatalyst, machinegossamer, machinetnt - Use DEV_FUN to attach PCI devices by device number and function number. --- devices/common/pci/bandit.cpp | 19 ++++++++++--------- devices/common/pci/bandit.h | 1 + devices/common/pci/pcihost.cpp | 6 +++--- devices/common/pci/pcihost.h | 4 +++- devices/memctrl/mpc106.cpp | 16 ++++++++-------- machines/machinecatalyst.cpp | 2 +- machines/machinegazelle.cpp | 2 +- machines/machinegossamer.cpp | 4 ++-- machines/machinetnt.cpp | 4 ++-- 9 files changed, 31 insertions(+), 27 deletions(-) diff --git a/devices/common/pci/bandit.cpp b/devices/common/pci/bandit.cpp index 675faa9..1291e39 100644 --- a/devices/common/pci/bandit.cpp +++ b/devices/common/pci/bandit.cpp @@ -39,6 +39,7 @@ const int MultiplyDeBruijnBitPosition2[] = /** finds the position of the bit that is set */ #define WHAT_BIT_SET(val) (MultiplyDeBruijnBitPosition2[(uint32_t)(val * 0x077CB531U) >> 27]) +#define IDSEL_TO_DEV_FUN(idsel) DEV_FUN(WHAT_BIT_SET(idsel) + 11,0) BanditPciDevice::BanditPciDevice(int bridge_num, std::string name, int dev_id, int rev) : PCIDevice(name) @@ -159,18 +160,18 @@ uint32_t BanditHost::read(uint32_t rgn_start, uint32_t offset, int size) return 0xFFFFFFFFUL; // PCI spec §6.1 } - if (this->dev_map.count(idsel)) { + if (this->dev_map.count(IDSEL_TO_DEV_FUN(idsel))) { AccessDetails details; details.offset = offset & 3; details.size = size; details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_READ; - result = this->dev_map[idsel]->pci_cfg_read(REG_NUM(), details); + result = this->dev_map[IDSEL_TO_DEV_FUN(idsel)]->pci_cfg_read(REG_NUM(), details); return pci_conv_rd_data(result, details); } else { LOG_F( ERROR, "%s err: read attempt from non-existing PCI device ??:%02x.%x @%02x", - this->name.c_str(), WHAT_BIT_SET(idsel) + 11, FUN_NUM(), REG_NUM() + (offset & 3) + this->name.c_str(), IDSEL_TO_DEV_FUN(idsel), FUN_NUM(), REG_NUM() + (offset & 3) ); return 0xFFFFFFFFUL; // PCI spec §6.1 } @@ -215,23 +216,23 @@ void BanditHost::write(uint32_t rgn_start, uint32_t offset, uint32_t value, int return; } - if (this->dev_map.count(idsel)) { + if (this->dev_map.count(IDSEL_TO_DEV_FUN(idsel))) { AccessDetails details; details.offset = offset & 3; details.size = size; details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_WRITE; if (size == 4 && !details.offset) { // aligned DWORD writes -> fast path - this->dev_map[idsel]->pci_cfg_write(REG_NUM(), BYTESWAP_32(value), details); + this->dev_map[IDSEL_TO_DEV_FUN(idsel)]->pci_cfg_write(REG_NUM(), BYTESWAP_32(value), details); } else { // otherwise perform necessary data transformations -> slow path - uint32_t old_val = this->dev_map[idsel]->pci_cfg_read(REG_NUM(), details); + uint32_t old_val = this->dev_map[IDSEL_TO_DEV_FUN(idsel)]->pci_cfg_read(REG_NUM(), details); uint32_t new_val = pci_conv_wr_data(old_val, value, details); - this->dev_map[idsel]->pci_cfg_write(REG_NUM(), new_val, details); + this->dev_map[IDSEL_TO_DEV_FUN(idsel)]->pci_cfg_write(REG_NUM(), new_val, details); } } else { LOG_F( ERROR, "%s err: write attempt to non-existing PCI device ??:%02x.%x @%02x", - this->name.c_str(), WHAT_BIT_SET(idsel) + 11, FUN_NUM(), REG_NUM() + (offset & 3) + this->name.c_str(), IDSEL_TO_DEV_FUN(idsel), FUN_NUM(), REG_NUM() + (offset & 3) ); } break; @@ -276,7 +277,7 @@ Bandit::Bandit(int bridge_num, std::string name, int dev_id, int rev) this->my_pci_device = unique_ptr( new BanditPciDevice(bridge_num, name, dev_id, rev) ); - this->pci_register_device(1, this->my_pci_device.get()); + this->pci_register_device(DEV_FUN(BANDIT_DEV,0), this->my_pci_device.get()); } Chaos::Chaos(std::string name) : BanditHost() diff --git a/devices/common/pci/bandit.h b/devices/common/pci/bandit.h index 007442e..e693417 100644 --- a/devices/common/pci/bandit.h +++ b/devices/common/pci/bandit.h @@ -46,6 +46,7 @@ along with this program. If not, see . #include #include +#define BANDIT_DEV (11) // Bandit's own device number #define BANDIT_CAR_TYPE (1 << 0) // Bandit config address type bit /* Convenient macros for parsing CONFIG_ADDR fields. */ diff --git a/devices/common/pci/pcihost.cpp b/devices/common/pci/pcihost.cpp index 47d997c..d639a1f 100644 --- a/devices/common/pci/pcihost.cpp +++ b/devices/common/pci/pcihost.cpp @@ -28,13 +28,13 @@ along with this program. If not, see . #include -bool PCIHost::pci_register_device(int dev_num, PCIDevice* dev_instance) +bool PCIHost::pci_register_device(int dev_fun_num, PCIDevice* dev_instance) { // return false if dev_num already registered - if (this->dev_map.count(dev_num)) + if (this->dev_map.count(dev_fun_num)) return false; - this->dev_map[dev_num] = dev_instance; + this->dev_map[dev_fun_num] = dev_instance; dev_instance->set_host(this); diff --git a/devices/common/pci/pcihost.h b/devices/common/pci/pcihost.h index 4615dd2..0566569 100644 --- a/devices/common/pci/pcihost.h +++ b/devices/common/pci/pcihost.h @@ -48,6 +48,8 @@ typedef struct AccessDetails { uint8_t flags; } AccessDetails; +#define DEV_FUN(dev_num,fun_num) (((dev_num) << 3) | (fun_num)) + class PCIDevice; // forward declaration to prevent errors class PCIHost { @@ -58,7 +60,7 @@ public: }; ~PCIHost() = default; - virtual bool pci_register_device(int dev_num, PCIDevice* dev_instance); + virtual bool pci_register_device(int dev_fun_num, PCIDevice* dev_instance); virtual bool pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj); virtual bool pci_unregister_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj); diff --git a/devices/memctrl/mpc106.cpp b/devices/memctrl/mpc106.cpp index bf62faf..5e7ce0a 100644 --- a/devices/memctrl/mpc106.cpp +++ b/devices/memctrl/mpc106.cpp @@ -48,7 +48,7 @@ MPC106::MPC106() : MemCtrlBase(), PCIDevice("Grackle"), PCIHost() this->status = 0x80; // assign PCI device number zero to myself - this->pci_register_device(0, this); + this->pci_register_device(DEV_FUN(0,0), this); // add PCI/ISA I/O space, 64K for now add_mmio_region(0xFE000000, 0x10000, this); @@ -62,7 +62,7 @@ int MPC106::device_postinit() std::string pci_dev_name; static const std::map pci_slots = { - {"pci_A1", 0xD}, {"pci_B1", 0xE}, {"pci_C1", 0xF} + {"pci_A1", DEV_FUN(0xD,0)}, {"pci_B1", DEV_FUN(0xE,0)}, {"pci_C1", DEV_FUN(0xF,0)} }; for (auto& slot : pci_slots) { @@ -131,12 +131,12 @@ uint32_t MPC106::pci_read(uint32_t offset, uint32_t size) { return 0xFFFFFFFFUL; // PCI spec §6.1 } - if (this->dev_map.count(dev_num)) { + if (this->dev_map.count(DEV_FUN(dev_num,fun_num))) { AccessDetails details; details.offset = offset & 3; details.size = size; details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_READ; - uint32_t result = this->dev_map[dev_num]->pci_cfg_read(reg_offs, details); + uint32_t result = this->dev_map[DEV_FUN(dev_num,fun_num)]->pci_cfg_read(reg_offs, details); return pci_conv_rd_data(result, details); } else { LOG_F(ERROR, "%s: read attempt from non-existing PCI device ??:%02x.%x @%02x", @@ -158,18 +158,18 @@ void MPC106::pci_write(uint32_t offset, uint32_t value, uint32_t size) { return; } - if (this->dev_map.count(dev_num)) { + if (this->dev_map.count(DEV_FUN(dev_num,fun_num))) { AccessDetails details; details.offset = offset & 3; details.size = size; details.flags = PCI_CONFIG_TYPE_0 | PCI_CONFIG_WRITE; if (size == 4 && !details.offset) { // aligned DWORD writes -> fast path - this->dev_map[dev_num]->pci_cfg_write(reg_offs, BYTESWAP_32(value), details); + this->dev_map[DEV_FUN(dev_num,fun_num)]->pci_cfg_write(reg_offs, BYTESWAP_32(value), details); } else { // otherwise perform necessary data transformations -> slow path - uint32_t old_val = this->dev_map[dev_num]->pci_cfg_read(reg_offs, details); + uint32_t old_val = this->dev_map[DEV_FUN(dev_num,fun_num)]->pci_cfg_read(reg_offs, details); uint32_t new_val = pci_conv_wr_data(old_val, value, details); - this->dev_map[dev_num]->pci_cfg_write(reg_offs, new_val, details); + this->dev_map[DEV_FUN(dev_num,fun_num)]->pci_cfg_write(reg_offs, new_val, details); } } else { LOG_F(ERROR, "%s: write attempt to non-existing PCI device ??:%02x.%x @%02x", diff --git a/machines/machinecatalyst.cpp b/machines/machinecatalyst.cpp index 831699f..474931a 100644 --- a/machines/machinecatalyst.cpp +++ b/machines/machinecatalyst.cpp @@ -44,7 +44,7 @@ int initialize_catalyst(std::string& id) // add the GrandCentral I/O controller pci_host->pci_register_device( - 32, dynamic_cast(gMachineObj->get_comp_by_name("GrandCentral"))); + DEV_FUN(0x10,0), dynamic_cast(gMachineObj->get_comp_by_name("GrandCentral"))); // get (raw) pointer to the memory controller platinum_obj = dynamic_cast(gMachineObj->get_comp_by_name("Platinum")); diff --git a/machines/machinegazelle.cpp b/machines/machinegazelle.cpp index db95645..064e92d 100644 --- a/machines/machinegazelle.cpp +++ b/machines/machinegazelle.cpp @@ -53,7 +53,7 @@ int initialize_gazelle(std::string& id) // register O'Hare I/O controller with the main PCI bus pci_host->pci_register_device( - 32, dynamic_cast(gMachineObj->get_comp_by_name("OHare"))); + DEV_FUN(0x10,0), dynamic_cast(gMachineObj->get_comp_by_name("OHare"))); PsxCtrl* psx_obj = dynamic_cast(gMachineObj->get_comp_by_name("Psx")); diff --git a/machines/machinegossamer.cpp b/machines/machinegossamer.cpp index 4ffa438..d4d24fd 100644 --- a/machines/machinegossamer.cpp +++ b/machines/machinegossamer.cpp @@ -124,9 +124,9 @@ int initialize_gossamer(std::string& id) // add pci devices grackle_obj->pci_register_device( - 16, dynamic_cast(gMachineObj->get_comp_by_name("Heathrow"))); + DEV_FUN(0x10,0), dynamic_cast(gMachineObj->get_comp_by_name("Heathrow"))); grackle_obj->pci_register_device( - 18, dynamic_cast(gMachineObj->get_comp_by_name(id == "pmg3twr" ? "AtiRagePro" : "AtiRageGT"))); + DEV_FUN(0x12,0), dynamic_cast(gMachineObj->get_comp_by_name(id == "pmg3twr" ? "AtiRagePro" : "AtiRageGT"))); // add Athens clock generator device and register it with the I2C host gMachineObj->add_device("Athens", std::unique_ptr(new AthensClocks(0x28))); diff --git a/machines/machinetnt.cpp b/machines/machinetnt.cpp index 0c281d1..e1a2648 100644 --- a/machines/machinetnt.cpp +++ b/machines/machinetnt.cpp @@ -44,14 +44,14 @@ int initialize_tnt(std::string& id) // connect GrandCentral I/O controller to the PCI1 bus pci_host->pci_register_device( - 32, dynamic_cast(gMachineObj->get_comp_by_name("GrandCentral"))); + DEV_FUN(0x10,0), dynamic_cast(gMachineObj->get_comp_by_name("GrandCentral"))); // get video PCI controller object PCIHost *vci_host = dynamic_cast(gMachineObj->get_comp_by_name("Chaos")); // connect built-in video device to the VCI bus vci_host->pci_register_device( - 1, dynamic_cast(gMachineObj->get_comp_by_name("ControlVideo"))); + DEV_FUN(0x0B,0), dynamic_cast(gMachineObj->get_comp_by_name("ControlVideo"))); // get (raw) pointer to the memory controller memctrl_obj = dynamic_cast(gMachineObj->get_comp_by_name("Hammerhead"));