bool linear_vram; /* vga.vram mapped over cirrus_linear_io */
MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
MemoryRegion low_mem; /* always mapped, overridden by: */
- MemoryRegion *cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */
+ MemoryRegion cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */
uint32_t cirrus_addr_mask;
uint32_t linear_mmio_mask;
uint8_t cirrus_shadow_gr0;
s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
if (s->cirrus_srccounter <= 0)
goto the_end;
- /* more bytes than needed can be transfered because of
+ /* more bytes than needed can be transferred because of
word alignment, so we keep them for the next line */
/* XXX: keep alignment to speed up transfer */
end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
},
};
- static void unmap_bank(CirrusVGAState *s, unsigned bank)
- {
- if (s->cirrus_bank[bank]) {
- memory_region_del_subregion(&s->low_mem_container,
- s->cirrus_bank[bank]);
- memory_region_destroy(s->cirrus_bank[bank]);
- g_free(s->cirrus_bank[bank]);
- s->cirrus_bank[bank] = NULL;
- }
- }
-
static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
{
- MemoryRegion *mr;
- static const char *names[] = { "vga.bank0", "vga.bank1" };
-
- if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
+ MemoryRegion *mr = &s->cirrus_bank[bank];
+ bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end)
&& !((s->vga.sr[0x07] & 0x01) == 0)
&& !((s->vga.gr[0x0B] & 0x14) == 0x14)
- && !(s->vga.gr[0x0B] & 0x02)) {
-
- mr = g_malloc(sizeof(*mr));
- memory_region_init_alias(mr, names[bank], &s->vga.vram,
- s->cirrus_bank_base[bank], 0x8000);
- memory_region_add_subregion_overlap(
- &s->low_mem_container,
- 0x8000 * bank,
- mr,
- 1);
- unmap_bank(s, bank);
- s->cirrus_bank[bank] = mr;
- } else {
- unmap_bank(s, bank);
- }
+ && !(s->vga.gr[0x0B] & 0x02);
+
+ memory_region_set_enabled(mr, enabled);
+ memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]);
}
static void map_linear_vram(CirrusVGAState *s)
s->linear_vram = false;
memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
}
- unmap_bank(s, 0);
- unmap_bank(s, 1);
+ memory_region_set_enabled(&s->cirrus_bank[0], false);
+ memory_region_set_enabled(&s->cirrus_bank[1], false);
}
/* Compute the memory access functions */
memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
"cirrus-low-memory", 0x20000);
memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+ for (i = 0; i < 2; ++i) {
+ static const char *names[] = { "vga.bank0", "vga.bank1" };
+ 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_add_subregion_overlap(system_memory,
isa_mem_base + 0x000a0000,
&s->low_mem_container,
*
***************************************/
-void isa_cirrus_vga_init(MemoryRegion *system_memory)
+DeviceState *isa_cirrus_vga_init(MemoryRegion *system_memory)
{
CirrusVGAState *s;
vmstate_register(NULL, 0, &vmstate_cirrus_vga, s);
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
/* XXX ISA-LFB support */
+ /* FIXME not qdev yet */
+ return NULL;
}
/***************************************
return 0;
}
-void pci_cirrus_vga_init(PCIBus *bus)
+DeviceState *pci_cirrus_vga_init(PCIBus *bus)
{
- pci_create_simple(bus, -1, "cirrus-vga");
+ return &pci_create_simple(bus, -1, "cirrus-vga")->qdev;
}
static PCIDeviceInfo cirrus_vga_info = {
PAMMemoryRegion pam_regions[13];
MemoryRegion smram_region;
uint8_t smm_enabled;
- bool smram_enabled;
PIIX3State *piix3;
};
{
int i, r;
uint32_t smram;
+ bool smram_enabled;
memory_region_transaction_begin();
update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
&d->pam_regions[i+1]);
}
smram = d->dev.config[I440FX_SMRAM];
- if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
- if (!d->smram_enabled) {
- memory_region_del_subregion(d->system_memory, &d->smram_region);
- d->smram_enabled = true;
- }
- } else {
- if (d->smram_enabled) {
- memory_region_add_subregion_overlap(d->system_memory, 0xa0000,
- &d->smram_region, 1);
- d->smram_enabled = false;
- }
- }
+ smram_enabled = (d->smm_enabled && (smram & 0x08)) || (smram & 0x40);
+ memory_region_set_enabled(&d->smram_region, !smram_enabled);
memory_region_transaction_commit();
}
address_space_io, 0);
s->bus = b;
qdev_init_nofail(dev);
+ qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL);
d = pci_create_simple(b, 0, device_name);
*pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
}
memory_region_init_alias(&f->smram_region, "smram-region",
f->pci_address_space, 0xa0000, 0x20000);
- f->smram_enabled = true;
+ memory_region_add_subregion_overlap(f->system_memory, 0xa0000,
+ &f->smram_region, 1);
+ memory_region_set_enabled(&f->smram_region, false);
/* Xen supports additional interrupt routes from the PCI devices to
* the IOAPIC: the four pins of each PCI device on the bus are also
pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
PIIX_NUM_PIRQS);
}
+ qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
piix3->pic = pic;
(*pi440fx_state)->piix3 = piix3;
bool terminates;
bool readable;
bool readonly; /* For RAM regions */
+ bool enabled;
MemoryRegion *alias;
target_phys_addr_t alias_offset;
unsigned priority;
/**
* memory_region_init: Initialize a memory region
*
- * The region typically acts as a container for other memory regions. Us
+ * The region typically acts as a container for other memory regions. Use
* memory_region_add_subregion() to add subregions.
*
* @mr: the #MemoryRegion to be initialized
/**
* memory_region_init_io: Initialize an I/O memory region.
*
- * Accesses into the region will be cause the callbacks in @ops to be called.
+ * Accesses into the region will cause the callbacks in @ops to be called.
* if @size is nonzero, subregions will be clipped to @size.
*
* @mr: the #MemoryRegion to be initialized.
/**
* memory_region_init_ram: Initialize RAM memory region. Accesses into the
- * region will be modify memory directly.
+ * region will modify memory directly.
*
* @mr: the #MemoryRegion to be initialized.
* @dev: a device associated with the region; may be %NULL.
/**
* memory_region_init_ram: Initialize RAM memory region from a user-provided.
- * pointer. Accesses into the region will be modify
+ * pointer. Accesses into the region will modify
* memory directly.
*
* @mr: the #MemoryRegion to be initialized.
uint64_t size);
/**
- * memory_region_destroy: Destroy a memory region and relaim all resources.
+ * memory_region_destroy: Destroy a memory region and reclaim all resources.
*
* @mr: the region to be destroyed. May not currently be a subregion
* (see memory_region_add_subregion()) or referenced in an alias
*
* Marks a word in an IO region (initialized with memory_region_init_io())
* as a trigger for an eventfd event. The I/O callback will not be called.
- * The caller must be prepared to handle failure (hat is, take the required
+ * The caller must be prepared to handle failure (that is, take the required
* action if the callback _is_ called).
*
* @mr: the memory region being updated.
int fd);
/**
- * memory_region_del_eventfd: Cancel and eventfd.
+ * memory_region_del_eventfd: Cancel an eventfd.
*
- * Cancels an eventfd trigger request by a previous memory_region_add_eventfd()
- * call.
+ * Cancels an eventfd trigger requested by a previous
+ * memory_region_add_eventfd() call.
*
* @mr: the memory region being updated.
* @addr: the address within @mr that is to be monitored
uint64_t data,
int fd);
/**
- * memory_region_add_subregion: Add a sub-region to a container.
+ * memory_region_add_subregion: Add a subregion to a container.
*
- * Adds a sub-region at @offset. The sub-region may not overlap with other
+ * Adds a subregion at @offset. The subregion may not overlap with other
* subregions (except for those explicitly marked as overlapping). A region
* may only be added once as a subregion (unless removed with
* memory_region_del_subregion()); use memory_region_init_alias() if you
target_phys_addr_t offset,
MemoryRegion *subregion);
/**
- * memory_region_add_subregion: Add a sub-region to a container, with overlap.
+ * memory_region_add_subregion: Add a subregion to a container, with overlap.
*
- * Adds a sub-region at @offset. The sub-region may overlap with other
+ * 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
void memory_region_del_subregion(MemoryRegion *mr,
MemoryRegion *subregion);
-
+ /*
+ * memory_region_set_enabled: dynamically enable or disable a region
+ *
+ * Enables or disables a memory region. A disabled memory region
+ * ignores all accesses to itself and its subregions. It does not
+ * obscure sibling subregions with lower priority - it simply behaves as
+ * if it was removed from the hierarchy.
+ *
+ * Regions default to being enabled.
+ *
+ * @mr: the region to be updated
+ * @enabled: whether to enable or disable the region
+ */
+ void memory_region_set_enabled(MemoryRegion *mr, bool enabled);
+
+ /*
+ * memory_region_set_address: dynamically update the address of a region
+ *
+ * Dynamically updates the address of a region, relative to its parent.
+ * May be used on regions are currently part of a memory hierarchy.
+ *
+ * @mr: the region to be updated
+ * @addr: new address, relative to parent region
+ */
+ void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr);
+
+ /*
+ * memory_region_set_alias_offset: dynamically update a memory alias's offset
+ *
+ * Dynamically updates the offset into the target region that an alias points
+ * to, as if the fourth argument to memory_region_init_alias() has changed.
+ *
+ * @mr: the #MemoryRegion to be updated; should be an alias.
+ * @offset: the new offset into the target memory region
+ */
+ void memory_region_set_alias_offset(MemoryRegion *mr,
+ target_phys_addr_t offset);
+
-/* Start a transaction; changes will be accumulated and made visible only
- * when the transaction ends.
+/**
+ * memory_region_transaction_begin: Start a transaction.
+ *
+ * During a transaction, changes will be accumulated and made visible
+ * only when the transaction ends (is commited).
*/
void memory_region_transaction_begin(void);
-/* Commit a transaction and make changes visible to the guest.
+
+/**
+ * memory_region_transaction_commit: Commit a transaction and make changes
+ * visible to the guest.
*/
void memory_region_transaction_commit(void);