From patchwork Mon Feb 18 23:12:48 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Korolev X-Patchwork-Id: 221553 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 6DB842C0089 for ; Tue, 19 Feb 2013 10:13:41 +1100 (EST) Received: from localhost ([::1]:60330 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7Ztz-0000ME-5V for incoming@patchwork.ozlabs.org; Mon, 18 Feb 2013 18:13:39 -0500 Received: from eggs.gnu.org ([208.118.235.92]:55600) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7ZtS-0008Mv-Uf for qemu-devel@nongnu.org; Mon, 18 Feb 2013 18:13:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U7ZtN-00082o-BQ for qemu-devel@nongnu.org; Mon, 18 Feb 2013 18:13:06 -0500 Received: from mail-pb0-f51.google.com ([209.85.160.51]:49235) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U7ZtM-00082H-V5 for qemu-devel@nongnu.org; Mon, 18 Feb 2013 18:13:01 -0500 Received: by mail-pb0-f51.google.com with SMTP id un15so1903156pbc.10 for ; Mon, 18 Feb 2013 15:13:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:subject:date:message-id:x-mailer:in-reply-to :references; bh=4Xa8GeETmLhniuaTzsBb+lLc5GMOiS/MqRuXmeFubvg=; b=Kjx/EAzCG/pKfvkU/4nBjYCMrxXO692rMNVx55BH530ggDsNmOqNa8P47Py/9/LwLR wVoD4st9OuwLkRJzBkVlqjQPVx/3YN3Hezd1ahDXpgQj8R8/FsT95tXAG7d1NotRVuL7 8LvQFqHmLqTrD+UxBZYphy1+umvtl0+R1y4mwsb+Pesuid+Dajkx3UdeuOD/xFms6WvG r6qx0fSYCpq2MP+nbehDeyS9OtGCMTt7FnPsMZMuhUWv55nSme+Oo4jPNqduVVSxRDEv b9iWXoq3scxCXgRw2M3bSRJbfw2ghcukU0IqNHaxxQr95lEUiM2wp8fMy+m2ApXd+F/B tJtA== X-Received: by 10.66.82.35 with SMTP id f3mr39952807pay.49.1361229180341; Mon, 18 Feb 2013 15:13:00 -0800 (PST) Received: from nzhmlwks0118.et.endace.com. ([210.7.32.45]) by mx.google.com with ESMTPS id ab1sm15775579pbd.37.2013.02.18.15.12.57 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 18 Feb 2013 15:12:59 -0800 (PST) From: Alexey Korolev To: qemu-devel@nongnu.org, mst@redhat.com Date: Tue, 19 Feb 2013 12:12:48 +1300 Message-Id: <1361229171-23902-2-git-send-email-akorolex@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1361229171-23902-1-git-send-email-akorolex@gmail.com> References: <1361229171-23902-1-git-send-email-akorolex@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.160.51 Subject: [Qemu-devel] [PATCH 1/3] Replacing memory_region_add_subregion_overlap X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org At the moment qemu memory manager considers every memory region as overlappable. Thus the function memory_region_add_subregion_overlap can only set the priority of the region. Code will be more clear if we use only the memory_region_add_subregion function to add a subregion to a container, and optionally use memory_region_set_priority() to change priority from the default. This patch adds predefined priority values in memory.h. Priority can take one of 4 possible values: low (default), medium, high and exclusive (highest). Signed-off-by: Alexey Korolev --- hw/armv7m_nvic.c | 4 ++-- hw/cirrus_vga.c | 15 ++++++++------- hw/kvm/pci-assign.c | 7 +++---- hw/kvmvapic.c | 3 ++- hw/lpc_ich9.c | 7 ++++--- hw/onenand.c | 7 +++---- hw/pam.c | 4 ++-- hw/pc.c | 6 ++---- hw/pc_sysfw.c | 14 ++++++-------- hw/pci/pci.c | 4 ++-- hw/pci/pci_bridge.c | 3 ++- hw/piix_pci.c | 9 +++++---- hw/q35.c | 5 +++-- hw/sysbus.c | 7 ------- hw/sysbus.h | 2 -- hw/vga-isa.c | 7 ++++--- hw/vga.c | 12 ++++++------ hw/xen_pt_msi.c | 6 +++--- include/exec/memory.h | 41 ++++++++++++++++++++--------------------- memory.c | 36 +++++++++++++++++------------------- 20 files changed, 94 insertions(+), 105 deletions(-) diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c index d5798d0..0710356 100644 --- a/hw/armv7m_nvic.c +++ b/hw/armv7m_nvic.c @@ -496,8 +496,8 @@ static int armv7m_nvic_init(SysBusDevice *dev) */ memory_region_init_alias(&s->gic_iomem_alias, "nvic-gic", &s->gic.iomem, 0x100, 0xc00); - memory_region_add_subregion_overlap(&s->container, 0x100, - &s->gic_iomem_alias, 1); + memory_region_set_priority(&s->gic_iomem_alias, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(&s->container, 0x100, &s->gic_iomem_alias); /* Map the whole thing into system memory at the location required * by the v7M architecture. */ diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 2a2c8da..70f04ff 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2386,7 +2386,8 @@ static void map_linear_vram(CirrusVGAState *s) { if (s->bustype == CIRRUS_BUSTYPE_PCI && !s->linear_vram) { s->linear_vram = true; - memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1); + memory_region_set_priority(&s->vga.vram, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(&s->pci_bar, 0, &s->vga.vram); } map_linear_vram_bank(s, 0); map_linear_vram_bank(s, 1); @@ -2850,13 +2851,13 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, MemoryRegion *bank = &s->cirrus_bank[i]; memory_region_init_alias(bank, names[i], &s->vga.vram, 0, 0x8000); memory_region_set_enabled(bank, false); - memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000, - bank, 1); + memory_region_set_priority(bank, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(&s->low_mem_container, i * 0x8000, bank); } - memory_region_add_subregion_overlap(system_memory, - isa_mem_base + 0x000a0000, - &s->low_mem_container, - 1); + memory_region_set_priority(&s->low_mem_container, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(system_memory, + isa_mem_base + 0x000a0000, + &s->low_mem_container); memory_region_set_coalescing(&s->low_mem); /* I/O handler for LFB */ diff --git a/hw/kvm/pci-assign.c b/hw/kvm/pci-assign.c index da64b5b..5da41cf 100644 --- a/hw/kvm/pci-assign.c +++ b/hw/kvm/pci-assign.c @@ -308,10 +308,9 @@ static void assigned_dev_iomem_setup(PCIDevice *pci_dev, int region_num, r_dev->msix_table_addr) { uint64_t offset = r_dev->msix_table_addr - real_region->base_addr; - memory_region_add_subregion_overlap(®ion->container, - offset, - &r_dev->mmio, - 1); + memory_region_set_priority(&r_dev->mmio, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(®ion->container, + offset, &r_dev->mmio); } } } diff --git a/hw/kvmvapic.c b/hw/kvmvapic.c index 1b5f416..3e10eba 100644 --- a/hw/kvmvapic.c +++ b/hw/kvmvapic.c @@ -598,7 +598,8 @@ static void vapic_map_rom_writable(VAPICROMState *s) memory_region_init_alias(&s->rom, "kvmvapic-rom", section.mr, rom_paddr, rom_size); - memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000); + memory_region_set_priority(&s->rom, MR_PRIORITY_EXCLUSIVE); + memory_region_add_subregion(as, rom_paddr, &s->rom); s->rom_mapped_writable = true; } diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c index e25689b..e5b6e0d 100644 --- a/hw/lpc_ich9.c +++ b/hw/lpc_ich9.c @@ -404,9 +404,10 @@ static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old) memory_region_del_subregion(get_system_memory(), &lpc->rbca_mem); } if (rbca & ICH9_LPC_RCBA_EN) { - memory_region_add_subregion_overlap(get_system_memory(), - rbca & ICH9_LPC_RCBA_BA_MASK, - &lpc->rbca_mem, 1); + memory_region_set_priority(&lpc->rbca_mem, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(get_system_memory(), + rbca & ICH9_LPC_RCBA_BA_MASK, + &lpc->rbca_mem); } } diff --git a/hw/onenand.c b/hw/onenand.c index 00a8738..ea1e309 100644 --- a/hw/onenand.c +++ b/hw/onenand.c @@ -118,10 +118,9 @@ static void onenand_mem_setup(OneNANDState *s) memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram", &s->ram, 0x0200 << s->shift, 0xbe00 << s->shift); - memory_region_add_subregion_overlap(&s->container, - 0x0200 << s->shift, - &s->mapped_ram, - 1); + memory_region_set_priority(&s->mapped_ram, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(&s->container, 0x0200 << s->shift, + &s->mapped_ram); } static void onenand_intr_update(OneNANDState *s) diff --git a/hw/pam.c b/hw/pam.c index 1d72e88..33391ef 100644 --- a/hw/pam.c +++ b/hw/pam.c @@ -71,8 +71,8 @@ void init_pam(MemoryRegion *ram_memory, MemoryRegion *system_memory, for (i = 0; i < 4; ++i) { memory_region_set_enabled(&mem->alias[i], false); - memory_region_add_subregion_overlap(system_memory, start, - &mem->alias[i], 1); + memory_region_set_priority(&mem->alias[i], MR_PRIORITY_MEDIUM); + memory_region_add_subregion(system_memory, start, &mem->alias[i]); } mem->current = 0; } diff --git a/hw/pc.c b/hw/pc.c index 53cc173..a48479a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -949,10 +949,8 @@ void *pc_memory_init(MemoryRegion *system_memory, option_rom_mr = g_malloc(sizeof(*option_rom_mr)); memory_region_init_ram(option_rom_mr, "pc.rom", PC_ROM_SIZE); vmstate_register_ram_global(option_rom_mr); - memory_region_add_subregion_overlap(rom_memory, - PC_ROM_MIN_VGA, - option_rom_mr, - 1); + memory_region_set_priority(option_rom_mr, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(rom_memory, PC_ROM_MIN_VGA, option_rom_mr); fw_cfg = bochs_bios_init(); rom_set_fw(fw_cfg); diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c index 7f6c12c..96ec366 100644 --- a/hw/pc_sysfw.c +++ b/hw/pc_sysfw.c @@ -59,10 +59,10 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory, isa_bios = g_malloc(sizeof(*isa_bios)); memory_region_init_ram(isa_bios, "isa-bios", isa_bios_size); vmstate_register_ram_global(isa_bios); - memory_region_add_subregion_overlap(rom_memory, - 0x100000 - isa_bios_size, - isa_bios, - 1); + memory_region_set_priority(isa_bios, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(rom_memory, + 0x100000 - isa_bios_size, + isa_bios); /* copy ISA rom image from top of flash memory */ flash_ptr = memory_region_get_ram_ptr(flash_mem); @@ -181,10 +181,8 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory) isa_bios = g_malloc(sizeof(*isa_bios)); memory_region_init_alias(isa_bios, "isa-bios", bios, bios_size - isa_bios_size, isa_bios_size); - memory_region_add_subregion_overlap(rom_memory, - 0x100000 - isa_bios_size, - isa_bios, - 1); + memory_region_set_priority(isa_bios, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(rom_memory, 0x100000 - isa_bios_size, isa_bios); memory_region_set_readonly(isa_bios, true); /* map all the bios at the top of memory */ diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2f45c8f..b9e92ea 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1032,8 +1032,8 @@ static void pci_update_mappings(PCIDevice *d) } r->addr = new_addr; if (r->addr != PCI_BAR_UNMAPPED) { - memory_region_add_subregion_overlap(r->address_space, - r->addr, r->memory, 1); + memory_region_set_priority(r->memory, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(r->address_space, r->addr, r->memory); } } } diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 995842a..71d4e40 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -148,7 +148,8 @@ static void pci_bridge_init_alias(PCIBridge *bridge, MemoryRegion *alias, pcibus_t size = enabled && limit >= base ? limit + 1 - base : 0; memory_region_init_alias(alias, name, space, base, size); - memory_region_add_subregion_overlap(parent_space, base, alias, 1); + memory_region_set_priority(alias, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(parent_space, base, alias); } static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br) diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 6c77e49..659b6fa 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -269,8 +269,8 @@ static PCIBus *i440fx_common_init(const char *device_name, } memory_region_init_alias(&f->smram_region, "smram-region", f->pci_address_space, 0xa0000, 0x20000); - memory_region_add_subregion_overlap(f->system_memory, 0xa0000, - &f->smram_region, 1); + memory_region_set_priority(&f->smram_region, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(f->system_memory, 0xa0000, &f->smram_region); memory_region_set_enabled(&f->smram_region, false); init_pam(f->ram_memory, f->system_memory, f->pci_address_space, &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); @@ -547,8 +547,9 @@ static int piix3_initfn(PCIDevice *dev) isa_bus_new(&d->dev.qdev, pci_address_space_io(dev)); memory_region_init_io(&d->rcr_mem, &rcr_ops, d, "piix3-reset-control", 1); - memory_region_add_subregion_overlap(pci_address_space_io(dev), RCR_IOPORT, - &d->rcr_mem, 1); + memory_region_set_priority(&d->rcr_mem, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(pci_address_space_io(dev), RCR_IOPORT, + &d->rcr_mem); qemu_register_reset(piix3_reset, d); return 0; diff --git a/hw/q35.c b/hw/q35.c index efebc27..b67e79b 100644 --- a/hw/q35.c +++ b/hw/q35.c @@ -264,8 +264,9 @@ static int mch_init(PCIDevice *d) cpu_smm_register(&mch_set_smm, mch); memory_region_init_alias(&mch->smram_region, "smram-region", mch->pci_address_space, 0xa0000, 0x20000); - memory_region_add_subregion_overlap(mch->system_memory, 0xa0000, - &mch->smram_region, 1); + memory_region_set_priority(&mch->smram_region, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(mch->system_memory, 0xa0000, + &mch->smram_region); memory_region_set_enabled(&mch->smram_region, false); init_pam(mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); diff --git a/hw/sysbus.c b/hw/sysbus.c index 6d9d1df..5dfdf78 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -220,13 +220,6 @@ void sysbus_add_memory(SysBusDevice *dev, hwaddr addr, memory_region_add_subregion(get_system_memory(), addr, mem); } -void sysbus_add_memory_overlap(SysBusDevice *dev, hwaddr addr, - MemoryRegion *mem, unsigned priority) -{ - memory_region_add_subregion_overlap(get_system_memory(), addr, mem, - priority); -} - void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem) { memory_region_del_subregion(get_system_memory(), mem); diff --git a/hw/sysbus.h b/hw/sysbus.h index a7fcded..88f5e1c 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -58,8 +58,6 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq); void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr); void sysbus_add_memory(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem); -void sysbus_add_memory_overlap(SysBusDevice *dev, hwaddr addr, - MemoryRegion *mem, unsigned priority); void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem); void sysbus_add_io(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem); diff --git a/hw/vga-isa.c b/hw/vga-isa.c index 762e45a..776fa31 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -58,9 +58,10 @@ static int vga_initfn(ISADevice *dev) if (vbe_ports) { isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe"); } - memory_region_add_subregion_overlap(isa_address_space(dev), - isa_mem_base + 0x000a0000, - vga_io_memory, 1); + memory_region_set_priority(vga_io_memory, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(isa_address_space(dev), + isa_mem_base + 0x000a0000, + vga_io_memory); memory_region_set_coalescing(vga_io_memory); s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); diff --git a/hw/vga.c b/hw/vga.c index e2ba7f2..f16f77b 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -202,8 +202,8 @@ static void vga_update_memory_access(VGACommonState *s) base += isa_mem_base; region = g_malloc(sizeof(*region)); memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size); - memory_region_add_subregion_overlap(s->legacy_address_space, base, - region, 2); + memory_region_set_priority(region, MR_PRIORITY_HIGH); + memory_region_add_subregion(s->legacy_address_space, base, region); s->chain4_alias = region; } if (old_region) { @@ -2359,10 +2359,10 @@ void vga_init(VGACommonState *s, MemoryRegion *address_space, s->legacy_address_space = address_space; vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports); - memory_region_add_subregion_overlap(address_space, - isa_mem_base + 0x000a0000, - vga_io_memory, - 1); + memory_region_set_priority(vga_io_memory, MR_PRIORITY_MEDIUM); + memory_region_add_subregion(address_space, + isa_mem_base + 0x000a0000, + vga_io_memory); memory_region_set_coalescing(vga_io_memory); if (init_vga_ports) { portio_list_init(vga_port_list, vga_ports, s, "vga"); diff --git a/hw/xen_pt_msi.c b/hw/xen_pt_msi.c index db757cd..85353ed 100644 --- a/hw/xen_pt_msi.c +++ b/hw/xen_pt_msi.c @@ -583,9 +583,9 @@ int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base) XEN_PT_LOG(d, "mapping physical MSI-X table to %p\n", msix->phys_iomem_base); - memory_region_add_subregion_overlap(&s->bar[bar_index], table_off, - &msix->mmio, - 2); /* Priority: pci default + 1 */ + /* Priority: pci default + 1 */ + memory_region_set_priority(&msix->mmio, MR_PRIORITY_HIGH); + memory_region_add_subregion(&s->bar[bar_index], table_off, &msix->mmio); return 0; diff --git a/include/exec/memory.h b/include/exec/memory.h index 2322732..162bdba 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -38,6 +38,11 @@ typedef struct MemoryRegionMmio MemoryRegionMmio; #define DIRTY_MEMORY_CODE 1 #define DIRTY_MEMORY_MIGRATION 3 +#define MR_PRIORITY_LOW 0 +#define MR_PRIORITY_MEDIUM 1 +#define MR_PRIORITY_HIGH 2 +#define MR_PRIORITY_EXCLUSIVE 3 + struct MemoryRegionMmio { CPUReadMemoryFunc *read[3]; CPUWriteMemoryFunc *write[3]; @@ -642,27 +647,6 @@ void memory_region_del_eventfd(MemoryRegion *mr, void memory_region_add_subregion(MemoryRegion *mr, hwaddr offset, MemoryRegion *subregion); -/** - * memory_region_add_subregion_overlap: Add a subregion to a container - * with overlap. - * - * Adds a subregion at @offset. The subregion may overlap with other - * subregions. Conflicts are resolved by having a higher @priority hide a - * lower @priority. Subregions without priority are taken as @priority 0. - * A region may only be added once as a subregion (unless removed with - * memory_region_del_subregion()); use memory_region_init_alias() if you - * want a region to be a subregion in multiple locations. - * - * @mr: the region to contain the new subregion; must be a container - * initialized with memory_region_init(). - * @offset: the offset relative to @mr where @subregion is added. - * @subregion: the subregion to be added. - * @priority: used for resolving overlaps; highest priority wins. - */ -void memory_region_add_subregion_overlap(MemoryRegion *mr, - hwaddr offset, - MemoryRegion *subregion, - unsigned priority); /** * memory_region_get_ram_addr: Get the ram address associated with a memory @@ -722,6 +706,21 @@ void memory_region_set_address(MemoryRegion *mr, hwaddr addr); void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset); +/* + * memory_region_set_priority: dynamically update the priority of a region + * + * Dynamically updates the priority of a region. The default @priority of + * the subregion is MR_PRIORITY_LOW. If one memory region overlaps another + * the conflicts are resolved by having a higher @priority hide a lower + * @priority. + * May be used on regions are currently part of a memory hierarchy. + * + * @mr: the region to be updated + * @priority: used for resolving overlaps; highest priority wins. + */ +void memory_region_set_priority(MemoryRegion *mr, + unsigned priority); + /** * memory_region_find: locate a MemoryRegion in an address space * diff --git a/memory.c b/memory.c index 92a2196..ec5aa57 100644 --- a/memory.c +++ b/memory.c @@ -805,7 +805,7 @@ void memory_region_init(MemoryRegion *mr, mr->readonly = false; mr->rom_device = false; mr->destructor = memory_region_destructor_none; - mr->priority = 0; + mr->priority = MR_PRIORITY_LOW; mr->may_overlap = false; mr->alias = NULL; QTAILQ_INIT(&mr->subregions); @@ -1359,17 +1359,6 @@ void memory_region_add_subregion(MemoryRegion *mr, subregion->priority = 0; memory_region_add_subregion_common(mr, offset, subregion); } - -void memory_region_add_subregion_overlap(MemoryRegion *mr, - hwaddr offset, - MemoryRegion *subregion, - unsigned priority) -{ - subregion->may_overlap = true; - subregion->priority = priority; - memory_region_add_subregion_common(mr, offset, subregion); -} - void memory_region_del_subregion(MemoryRegion *mr, MemoryRegion *subregion) { @@ -1395,8 +1384,6 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled) void memory_region_set_address(MemoryRegion *mr, hwaddr addr) { MemoryRegion *parent = mr->parent; - unsigned priority = mr->priority; - bool may_overlap = mr->may_overlap; if (addr == mr->addr || !parent) { mr->addr = addr; @@ -1405,11 +1392,7 @@ void memory_region_set_address(MemoryRegion *mr, hwaddr addr) memory_region_transaction_begin(); memory_region_del_subregion(parent, mr); - if (may_overlap) { - memory_region_add_subregion_overlap(parent, addr, mr, priority); - } else { - memory_region_add_subregion(parent, addr, mr); - } + memory_region_add_subregion(parent, addr, mr); memory_region_transaction_commit(); } @@ -1427,6 +1410,21 @@ void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset) memory_region_transaction_commit(); } +void memory_region_set_priority(MemoryRegion *mr, unsigned priority) +{ + MemoryRegion *parent = mr->parent; + + mr->priority = priority; + if (!parent) { + return; + } + + memory_region_transaction_begin(); + memory_region_del_subregion(parent, mr); + memory_region_add_subregion(parent, mr->addr, mr); + memory_region_transaction_commit(); +} + ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr) { return mr->ram_addr;