From 52fa30b71d9f6a5ca904c8eee4513ac909ddfd6c Mon Sep 17 00:00:00 2001 From: joevt Date: Mon, 12 Dec 2022 00:16:59 -0800 Subject: [PATCH] Add ability to unregister mmio region. mmio regions are registered when a PCI BAR is set. Add the ability to reverse that - for when a PCI BAR is changed. --- devices/common/pci/pcihost.cpp | 8 ++++++++ devices/common/pci/pcihost.h | 1 + devices/memctrl/memctrlbase.cpp | 22 ++++++++++++++++++++++ devices/memctrl/memctrlbase.h | 1 + 4 files changed, 32 insertions(+) diff --git a/devices/common/pci/pcihost.cpp b/devices/common/pci/pcihost.cpp index 51dacf1..761a57a 100644 --- a/devices/common/pci/pcihost.cpp +++ b/devices/common/pci/pcihost.cpp @@ -53,6 +53,14 @@ bool PCIHost::pci_register_mmio_region(uint32_t start_addr, uint32_t size, PCIDe return mem_ctrl->add_mmio_region(start_addr, size, obj); } +bool PCIHost::pci_unregister_mmio_region(uint32_t start_addr, uint32_t size, PCIDevice* obj) +{ + MemCtrlBase *mem_ctrl = dynamic_cast + (gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL)); + // FIXME: add sanity checks! + return mem_ctrl->remove_mmio_region(start_addr, size, obj); +} + void PCIHost::attach_pci_device(std::string& dev_name, int slot_id) { if (!DeviceRegistry::device_registered(dev_name)) { diff --git a/devices/common/pci/pcihost.h b/devices/common/pci/pcihost.h index d21c27e..5a0499a 100644 --- a/devices/common/pci/pcihost.h +++ b/devices/common/pci/pcihost.h @@ -42,6 +42,7 @@ public: virtual bool pci_register_device(int dev_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); virtual void attach_pci_device(std::string& dev_name, int slot_id); diff --git a/devices/memctrl/memctrlbase.cpp b/devices/memctrl/memctrlbase.cpp index 8632263..6e0c6d2 100644 --- a/devices/memctrl/memctrlbase.cpp +++ b/devices/memctrl/memctrlbase.cpp @@ -233,6 +233,28 @@ bool MemCtrlBase::add_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice return true; } +bool MemCtrlBase::remove_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice* dev_instance) { + int found = 0; + + uint32_t end = start_addr + size - 1; + address_map.erase(std::remove_if(address_map.begin(), address_map.end(), + [start_addr, end, dev_instance, &found](const AddressMapEntry *entry) { + bool result = (start_addr == entry->start && end == entry->end && (!dev_instance || dev_instance == entry->devobj)); + found += result; + return result; + } + ), address_map.end()); + + if (found == 0) + LOG_F(ERROR, "Cannot find mmio region 0x%X..0x%X%s%s%s to remove", start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : ""); + else if (found > 1) + LOG_F(ERROR, "Removed %d occurrences of mmio region 0x%X..0x%X%s%s%s", found, start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : ""); + else + LOG_F(INFO, "Removed mmio region 0x%X..0x%X%s%s%s", start_addr, end, dev_instance ? " (" : "", dev_instance ? dev_instance->get_name().c_str() : "", dev_instance ? ")" : ""); + + return (found > 0); +} + AddressMapEntry* MemCtrlBase::find_rom_region() { for (auto& entry : address_map) { diff --git a/devices/memctrl/memctrlbase.h b/devices/memctrl/memctrlbase.h index 484f79c..209bff1 100644 --- a/devices/memctrl/memctrlbase.h +++ b/devices/memctrl/memctrlbase.h @@ -68,6 +68,7 @@ public: virtual bool add_mem_mirror(uint32_t start_addr, uint32_t dest_addr); virtual bool add_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice* dev_instance); + virtual bool remove_mmio_region(uint32_t start_addr, uint32_t size, MMIODevice* dev_instance); virtual bool set_data(uint32_t reg_addr, const uint8_t* data, uint32_t size);