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.
This commit is contained in:
joevt 2022-12-12 00:16:59 -08:00
parent 911acb4bc2
commit 52fa30b71d
4 changed files with 32 additions and 0 deletions

View File

@ -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<MemCtrlBase *>
(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)) {

View File

@ -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);

View File

@ -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) {

View File

@ -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);