mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 03:13:44 +08:00
Merge remote-tracking branch 'bonzini/iommu-for-anthony' into staging
# By Paolo Bonzini (11) and others # Via Paolo Bonzini * bonzini/iommu-for-anthony: memory: clean up phys_page_find memory: populate FlatView for new address spaces memory: limit sections in the radix tree to the actual address space size s390x: reduce TARGET_PHYS_ADDR_SPACE_BITS to 62 memory: fix address space initialization/destruction memory: make memory_global_sync_dirty_bitmap take an AddressSpace memory: do not duplicate memory_region_destructor_none memory: Rename readable flag to romd_mode memory: Replace open-coded memory_region_is_romd memory: allow memory_region_find() to run on non-root memory regions memory: assert that PhysPageEntry's ptr does not overflow exec: eliminate stq_phys_notdirty exec: make qemu_get_ram_ptr private exec: eliminate qemu_put_ram_ptr exec: remove obsolete comment Message-id: 1369414987-8839-1-git-send-email-pbonzini@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
fd469df97a
@ -386,7 +386,7 @@ static void migration_bitmap_sync(void)
|
||||
}
|
||||
|
||||
trace_migration_bitmap_sync_start();
|
||||
memory_global_sync_dirty_bitmap(get_system_memory());
|
||||
address_space_sync_dirty_bitmap(&address_space_memory);
|
||||
|
||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
|
||||
|
68
exec.c
68
exec.c
@ -187,19 +187,15 @@ MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index)
|
||||
PhysPageEntry lp = d->phys_map;
|
||||
PhysPageEntry *p;
|
||||
int i;
|
||||
uint16_t s_index = phys_section_unassigned;
|
||||
|
||||
for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) {
|
||||
if (lp.ptr == PHYS_MAP_NODE_NIL) {
|
||||
goto not_found;
|
||||
return &phys_sections[phys_section_unassigned];
|
||||
}
|
||||
p = phys_map_nodes[lp.ptr];
|
||||
lp = p[(index >> (i * L2_BITS)) & (L2_SIZE - 1)];
|
||||
}
|
||||
|
||||
s_index = lp.ptr;
|
||||
not_found:
|
||||
return &phys_sections[s_index];
|
||||
return &phys_sections[lp.ptr];
|
||||
}
|
||||
|
||||
bool memory_region_is_unassigned(MemoryRegion *mr)
|
||||
@ -639,12 +635,6 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
|
||||
iotlb |= phys_section_rom;
|
||||
}
|
||||
} else {
|
||||
/* IO handlers are currently passed a physical address.
|
||||
It would be nice to pass an offset from the base address
|
||||
of that region. This would avoid having to special case RAM,
|
||||
and avoid full address decoding in every device.
|
||||
We can't use the high bits of pd for this because
|
||||
IO_MEM_ROMD uses these as a ram address. */
|
||||
iotlb = section - phys_sections;
|
||||
iotlb += memory_region_section_addr(section, paddr);
|
||||
}
|
||||
@ -719,6 +709,12 @@ static void destroy_all_mappings(AddressSpaceDispatch *d)
|
||||
|
||||
static uint16_t phys_section_add(MemoryRegionSection *section)
|
||||
{
|
||||
/* The physical section number is ORed with a page-aligned
|
||||
* pointer to produce the iotlb entries. Thus it should
|
||||
* never overflow into the page-aligned value.
|
||||
*/
|
||||
assert(phys_sections_nb < TARGET_PAGE_SIZE);
|
||||
|
||||
if (phys_sections_nb == phys_sections_nb_alloc) {
|
||||
phys_sections_nb_alloc = MAX(phys_sections_nb_alloc * 2, 16);
|
||||
phys_sections = g_renew(MemoryRegionSection, phys_sections,
|
||||
@ -775,10 +771,21 @@ static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *sec
|
||||
section_index);
|
||||
}
|
||||
|
||||
QEMU_BUILD_BUG_ON(TARGET_PHYS_ADDR_SPACE_BITS > MAX_PHYS_ADDR_SPACE_BITS)
|
||||
|
||||
static MemoryRegionSection limit(MemoryRegionSection section)
|
||||
{
|
||||
section.size = MIN(section.offset_within_address_space + section.size,
|
||||
MAX_PHYS_ADDR + 1)
|
||||
- section.offset_within_address_space;
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
|
||||
{
|
||||
AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
|
||||
MemoryRegionSection now = *section, remain = *section;
|
||||
MemoryRegionSection now = limit(*section), remain = limit(*section);
|
||||
|
||||
if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
|
||||
|| (now.size < TARGET_PAGE_SIZE)) {
|
||||
@ -1340,11 +1347,6 @@ static void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size)
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_put_ram_ptr(void *addr)
|
||||
{
|
||||
trace_qemu_put_ram_ptr(addr);
|
||||
}
|
||||
|
||||
int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
|
||||
{
|
||||
RAMBlock *block;
|
||||
@ -1934,7 +1936,6 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
|
||||
ptr = qemu_get_ram_ptr(addr1);
|
||||
memcpy(ptr, buf, l);
|
||||
invalidate_and_set_dirty(addr1, l);
|
||||
qemu_put_ram_ptr(ptr);
|
||||
}
|
||||
} else {
|
||||
if (!(memory_region_is_ram(section->mr) ||
|
||||
@ -1964,7 +1965,6 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
|
||||
+ memory_region_section_addr(section,
|
||||
addr));
|
||||
memcpy(buf, ptr, l);
|
||||
qemu_put_ram_ptr(ptr);
|
||||
}
|
||||
}
|
||||
len -= l;
|
||||
@ -2026,7 +2026,6 @@ void cpu_physical_memory_write_rom(hwaddr addr,
|
||||
ptr = qemu_get_ram_ptr(addr1);
|
||||
memcpy(ptr, buf, l);
|
||||
invalidate_and_set_dirty(addr1, l);
|
||||
qemu_put_ram_ptr(ptr);
|
||||
}
|
||||
len -= l;
|
||||
buf += l;
|
||||
@ -2404,33 +2403,6 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
void stq_phys_notdirty(hwaddr addr, uint64_t val)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
MemoryRegionSection *section;
|
||||
|
||||
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
|
||||
|
||||
if (!memory_region_is_ram(section->mr) || section->readonly) {
|
||||
addr = memory_region_section_addr(section, addr);
|
||||
if (memory_region_is_ram(section->mr)) {
|
||||
section = &phys_sections[phys_section_rom];
|
||||
}
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
io_mem_write(section->mr, addr, val >> 32, 4);
|
||||
io_mem_write(section->mr, addr + 4, (uint32_t)val, 4);
|
||||
#else
|
||||
io_mem_write(section->mr, addr, (uint32_t)val, 4);
|
||||
io_mem_write(section->mr, addr + 4, val >> 32, 4);
|
||||
#endif
|
||||
} else {
|
||||
ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
|
||||
& TARGET_PAGE_MASK)
|
||||
+ memory_region_section_addr(section, addr));
|
||||
stq_p(ptr, val);
|
||||
}
|
||||
}
|
||||
|
||||
/* warning: addr must be aligned */
|
||||
static inline void stl_phys_internal(hwaddr addr, uint32_t val,
|
||||
enum device_endian endian)
|
||||
|
@ -105,7 +105,7 @@ static void pflash_timer (void *opaque)
|
||||
DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
|
||||
/* Reset flash */
|
||||
pfl->status ^= 0x80;
|
||||
memory_region_rom_device_set_readable(&pfl->mem, true);
|
||||
memory_region_rom_device_set_romd(&pfl->mem, true);
|
||||
pfl->wcycle = 0;
|
||||
pfl->cmd = 0;
|
||||
}
|
||||
@ -281,7 +281,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
|
||||
|
||||
if (!pfl->wcycle) {
|
||||
/* Set the device in I/O access mode */
|
||||
memory_region_rom_device_set_readable(&pfl->mem, false);
|
||||
memory_region_rom_device_set_romd(&pfl->mem, false);
|
||||
}
|
||||
|
||||
switch (pfl->wcycle) {
|
||||
@ -458,7 +458,7 @@ static void pflash_write(pflash_t *pfl, hwaddr offset,
|
||||
"\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
|
||||
|
||||
reset_flash:
|
||||
memory_region_rom_device_set_readable(&pfl->mem, true);
|
||||
memory_region_rom_device_set_romd(&pfl->mem, true);
|
||||
|
||||
pfl->wcycle = 0;
|
||||
pfl->cmd = 0;
|
||||
|
@ -111,7 +111,7 @@ static void pflash_setup_mappings(pflash_t *pfl)
|
||||
|
||||
static void pflash_register_memory(pflash_t *pfl, int rom_mode)
|
||||
{
|
||||
memory_region_rom_device_set_readable(&pfl->orig_mem, rom_mode);
|
||||
memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
|
||||
pfl->rom_mode = rom_mode;
|
||||
}
|
||||
|
||||
|
@ -1959,8 +1959,6 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
|
||||
pci_patch_ids(pdev, ptr, size);
|
||||
}
|
||||
|
||||
qemu_put_ram_ptr(ptr);
|
||||
|
||||
pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
|
||||
|
||||
return 0;
|
||||
|
@ -711,7 +711,6 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
|
||||
|
||||
ptr = memory_region_get_ram_ptr(&s->dev.rom);
|
||||
memcpy(biosver, ptr + 0x41, 31);
|
||||
qemu_put_ram_ptr(ptr);
|
||||
memcpy(info.image_component[1].name, "BIOS", 4);
|
||||
memcpy(info.image_component[1].version, biosver,
|
||||
strlen((const char *)biosver));
|
||||
|
@ -49,9 +49,6 @@ typedef void CPUWriteMemoryFunc(void *opaque, hwaddr addr, uint32_t value);
|
||||
typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
|
||||
|
||||
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
|
||||
/* This should only be used for ram local to a device. */
|
||||
void *qemu_get_ram_ptr(ram_addr_t addr);
|
||||
void qemu_put_ram_ptr(void *addr);
|
||||
/* This should not be used by devices. */
|
||||
int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
|
||||
ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
|
||||
@ -105,7 +102,6 @@ uint32_t lduw_phys(hwaddr addr);
|
||||
uint32_t ldl_phys(hwaddr addr);
|
||||
uint64_t ldq_phys(hwaddr addr);
|
||||
void stl_phys_notdirty(hwaddr addr, uint32_t val);
|
||||
void stq_phys_notdirty(hwaddr addr, uint64_t val);
|
||||
void stw_phys(hwaddr addr, uint32_t val);
|
||||
void stl_phys(hwaddr addr, uint32_t val);
|
||||
void stq_phys(hwaddr addr, uint64_t val);
|
||||
|
@ -46,6 +46,7 @@ void address_space_destroy_dispatch(AddressSpace *as);
|
||||
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
|
||||
MemoryRegion *mr);
|
||||
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
|
||||
void *qemu_get_ram_ptr(ram_addr_t addr);
|
||||
void qemu_ram_free(ram_addr_t addr);
|
||||
void qemu_ram_free_from_ptr(ram_addr_t addr);
|
||||
|
||||
|
@ -26,6 +26,9 @@
|
||||
#include "exec/ioport.h"
|
||||
#include "qemu/int128.h"
|
||||
|
||||
#define MAX_PHYS_ADDR_SPACE_BITS 62
|
||||
#define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
|
||||
|
||||
typedef struct MemoryRegionOps MemoryRegionOps;
|
||||
typedef struct MemoryRegionPortio MemoryRegionPortio;
|
||||
typedef struct MemoryRegionMmio MemoryRegionMmio;
|
||||
@ -126,7 +129,7 @@ struct MemoryRegion {
|
||||
ram_addr_t ram_addr;
|
||||
bool subpage;
|
||||
bool terminates;
|
||||
bool readable;
|
||||
bool romd_mode;
|
||||
bool ram;
|
||||
bool readonly; /* For RAM regions */
|
||||
bool enabled;
|
||||
@ -355,16 +358,16 @@ uint64_t memory_region_size(MemoryRegion *mr);
|
||||
bool memory_region_is_ram(MemoryRegion *mr);
|
||||
|
||||
/**
|
||||
* memory_region_is_romd: check whether a memory region is ROMD
|
||||
* memory_region_is_romd: check whether a memory region is in ROMD mode
|
||||
*
|
||||
* Returns %true is a memory region is ROMD and currently set to allow
|
||||
* Returns %true if a memory region is a ROM device and currently set to allow
|
||||
* direct reads.
|
||||
*
|
||||
* @mr: the memory region being queried
|
||||
*/
|
||||
static inline bool memory_region_is_romd(MemoryRegion *mr)
|
||||
{
|
||||
return mr->rom_device && mr->readable;
|
||||
return mr->rom_device && mr->romd_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -502,18 +505,18 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
|
||||
void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
|
||||
|
||||
/**
|
||||
* memory_region_rom_device_set_readable: enable/disable ROM readability
|
||||
* memory_region_rom_device_set_romd: enable/disable ROMD mode
|
||||
*
|
||||
* Allows a ROM device (initialized with memory_region_init_rom_device() to
|
||||
* to be marked as readable (default) or not readable. When it is readable,
|
||||
* the device is mapped to guest memory. When not readable, reads are
|
||||
* forwarded to the #MemoryRegion.read function.
|
||||
* set to ROMD mode (default) or MMIO mode. When it is in ROMD mode, the
|
||||
* device is mapped to guest memory and satisfies read access directly.
|
||||
* When in MMIO mode, reads are forwarded to the #MemoryRegion.read function.
|
||||
* Writes are always handled by the #MemoryRegion.write function.
|
||||
*
|
||||
* @mr: the memory region to be updated
|
||||
* @readable: whether reads are satisified directly (%true) or via callbacks
|
||||
* (%false)
|
||||
* @romd_mode: %true to put the region into ROMD mode
|
||||
*/
|
||||
void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable);
|
||||
void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode);
|
||||
|
||||
/**
|
||||
* memory_region_set_coalescing: Enable memory coalescing for the region.
|
||||
@ -718,24 +721,34 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
|
||||
hwaddr offset);
|
||||
|
||||
/**
|
||||
* memory_region_find: locate a MemoryRegion in an address space
|
||||
* memory_region_find: translate an address/size relative to a
|
||||
* MemoryRegion into a #MemoryRegionSection.
|
||||
*
|
||||
* Locates the first #MemoryRegion within an address space given by
|
||||
* @address_space that overlaps the range given by @addr and @size.
|
||||
* Locates the first #MemoryRegion within @mr that overlaps the range
|
||||
* given by @addr and @size.
|
||||
*
|
||||
* Returns a #MemoryRegionSection that describes a contiguous overlap.
|
||||
* It will have the following characteristics:
|
||||
* .@offset_within_address_space >= @addr
|
||||
* .@offset_within_address_space + .@size <= @addr + @size
|
||||
* .@size = 0 iff no overlap was found
|
||||
* .@mr is non-%NULL iff an overlap was found
|
||||
*
|
||||
* @address_space: a top-level (i.e. parentless) region that contains
|
||||
* the region to be found
|
||||
* @addr: start of the area within @address_space to be searched
|
||||
* Remember that in the return value the @offset_within_region is
|
||||
* relative to the returned region (in the .@mr field), not to the
|
||||
* @mr argument.
|
||||
*
|
||||
* Similarly, the .@offset_within_address_space is relative to the
|
||||
* address space that contains both regions, the passed and the
|
||||
* returned one. However, in the special case where the @mr argument
|
||||
* has no parent (and thus is the root of the address space), the
|
||||
* following will hold:
|
||||
* .@offset_within_address_space >= @addr
|
||||
* .@offset_within_address_space + .@size <= @addr + @size
|
||||
*
|
||||
* @mr: a MemoryRegion within which @addr is a relative address
|
||||
* @addr: start of the area within @as to be searched
|
||||
* @size: size of the area to be searched
|
||||
*/
|
||||
MemoryRegionSection memory_region_find(MemoryRegion *address_space,
|
||||
MemoryRegionSection memory_region_find(MemoryRegion *mr,
|
||||
hwaddr addr, uint64_t size);
|
||||
|
||||
/**
|
||||
@ -756,13 +769,12 @@ memory_region_section_addr(MemoryRegionSection *section,
|
||||
}
|
||||
|
||||
/**
|
||||
* memory_global_sync_dirty_bitmap: synchronize the dirty log for all memory
|
||||
* address_space_sync_dirty_bitmap: synchronize the dirty log for all memory
|
||||
*
|
||||
* Synchronizes the dirty page log for an entire address space.
|
||||
* @address_space: a top-level (i.e. parentless) region that contains the
|
||||
* memory being synchronized
|
||||
* @as: the address space that contains the memory being synchronized
|
||||
*/
|
||||
void memory_global_sync_dirty_bitmap(MemoryRegion *address_space);
|
||||
void address_space_sync_dirty_bitmap(AddressSpace *as);
|
||||
|
||||
/**
|
||||
* memory_region_transaction_begin: Start a transaction.
|
||||
|
@ -42,7 +42,6 @@
|
||||
#pragma GCC poison ldl_phys
|
||||
#pragma GCC poison ldq_phys
|
||||
#pragma GCC poison stl_phys_notdirty
|
||||
#pragma GCC poison stq_phys_notdirty
|
||||
#pragma GCC poison stw_phys
|
||||
#pragma GCC poison stl_phys
|
||||
#pragma GCC poison stq_phys
|
||||
|
64
memory.c
64
memory.c
@ -213,7 +213,7 @@ struct FlatRange {
|
||||
hwaddr offset_in_region;
|
||||
AddrRange addr;
|
||||
uint8_t dirty_log_mask;
|
||||
bool readable;
|
||||
bool romd_mode;
|
||||
bool readonly;
|
||||
};
|
||||
|
||||
@ -236,7 +236,7 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
|
||||
return a->mr == b->mr
|
||||
&& addrrange_equal(a->addr, b->addr)
|
||||
&& a->offset_in_region == b->offset_in_region
|
||||
&& a->readable == b->readable
|
||||
&& a->romd_mode == b->romd_mode
|
||||
&& a->readonly == b->readonly;
|
||||
}
|
||||
|
||||
@ -276,7 +276,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
|
||||
r1->addr.size),
|
||||
int128_make64(r2->offset_in_region))
|
||||
&& r1->dirty_log_mask == r2->dirty_log_mask
|
||||
&& r1->readable == r2->readable
|
||||
&& r1->romd_mode == r2->romd_mode
|
||||
&& r1->readonly == r2->readonly;
|
||||
}
|
||||
|
||||
@ -532,7 +532,7 @@ static void render_memory_region(FlatView *view,
|
||||
fr.offset_in_region = offset_in_region;
|
||||
fr.addr = addrrange_make(base, now);
|
||||
fr.dirty_log_mask = mr->dirty_log_mask;
|
||||
fr.readable = mr->readable;
|
||||
fr.romd_mode = mr->romd_mode;
|
||||
fr.readonly = readonly;
|
||||
flatview_insert(view, i, &fr);
|
||||
++i;
|
||||
@ -552,7 +552,7 @@ static void render_memory_region(FlatView *view,
|
||||
fr.offset_in_region = offset_in_region;
|
||||
fr.addr = addrrange_make(base, remain);
|
||||
fr.dirty_log_mask = mr->dirty_log_mask;
|
||||
fr.readable = mr->readable;
|
||||
fr.romd_mode = mr->romd_mode;
|
||||
fr.readonly = readonly;
|
||||
flatview_insert(view, i, &fr);
|
||||
}
|
||||
@ -768,10 +768,6 @@ static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
|
||||
qemu_ram_free_from_ptr(mr->ram_addr);
|
||||
}
|
||||
|
||||
static void memory_region_destructor_iomem(MemoryRegion *mr)
|
||||
{
|
||||
}
|
||||
|
||||
static void memory_region_destructor_rom_device(MemoryRegion *mr)
|
||||
{
|
||||
qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
|
||||
@ -801,7 +797,7 @@ void memory_region_init(MemoryRegion *mr,
|
||||
mr->enabled = true;
|
||||
mr->terminates = false;
|
||||
mr->ram = false;
|
||||
mr->readable = true;
|
||||
mr->romd_mode = true;
|
||||
mr->readonly = false;
|
||||
mr->rom_device = false;
|
||||
mr->destructor = memory_region_destructor_none;
|
||||
@ -929,7 +925,6 @@ void memory_region_init_io(MemoryRegion *mr,
|
||||
mr->ops = ops;
|
||||
mr->opaque = opaque;
|
||||
mr->terminates = true;
|
||||
mr->destructor = memory_region_destructor_iomem;
|
||||
mr->ram_addr = ~(ram_addr_t)0;
|
||||
}
|
||||
|
||||
@ -1121,11 +1116,11 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
|
||||
}
|
||||
}
|
||||
|
||||
void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
|
||||
void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode)
|
||||
{
|
||||
if (mr->readable != readable) {
|
||||
if (mr->romd_mode != romd_mode) {
|
||||
memory_region_transaction_begin();
|
||||
mr->readable = readable;
|
||||
mr->romd_mode = romd_mode;
|
||||
memory_region_update_pending |= mr->enabled;
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
@ -1451,15 +1446,24 @@ static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
|
||||
sizeof(FlatRange), cmp_flatrange_addr);
|
||||
}
|
||||
|
||||
MemoryRegionSection memory_region_find(MemoryRegion *address_space,
|
||||
MemoryRegionSection memory_region_find(MemoryRegion *mr,
|
||||
hwaddr addr, uint64_t size)
|
||||
{
|
||||
AddressSpace *as = memory_region_to_address_space(address_space);
|
||||
AddrRange range = addrrange_make(int128_make64(addr),
|
||||
int128_make64(size));
|
||||
FlatRange *fr = address_space_lookup(as, range);
|
||||
MemoryRegionSection ret = { .mr = NULL, .size = 0 };
|
||||
MemoryRegion *root;
|
||||
AddressSpace *as;
|
||||
AddrRange range;
|
||||
FlatRange *fr;
|
||||
|
||||
addr += mr->addr;
|
||||
for (root = mr; root->parent; ) {
|
||||
root = root->parent;
|
||||
addr += root->addr;
|
||||
}
|
||||
|
||||
as = memory_region_to_address_space(root);
|
||||
range = addrrange_make(int128_make64(addr), int128_make64(size));
|
||||
fr = address_space_lookup(as, range);
|
||||
if (!fr) {
|
||||
return ret;
|
||||
}
|
||||
@ -1470,6 +1474,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
|
||||
}
|
||||
|
||||
ret.mr = fr->mr;
|
||||
ret.address_space = as;
|
||||
range = addrrange_intersection(range, fr->addr);
|
||||
ret.offset_within_region = fr->offset_in_region;
|
||||
ret.offset_within_region += int128_get64(int128_sub(range.start,
|
||||
@ -1480,9 +1485,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *address_space,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
|
||||
void address_space_sync_dirty_bitmap(AddressSpace *as)
|
||||
{
|
||||
AddressSpace *as = memory_region_to_address_space(address_space);
|
||||
FlatRange *fr;
|
||||
|
||||
FOR_EACH_FLAT_RANGE(fr, as->current_map) {
|
||||
@ -1568,10 +1572,13 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
|
||||
as->root = root;
|
||||
as->current_map = g_new(FlatView, 1);
|
||||
flatview_init(as->current_map);
|
||||
as->ioeventfd_nb = 0;
|
||||
as->ioeventfds = NULL;
|
||||
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
|
||||
as->name = NULL;
|
||||
memory_region_transaction_commit();
|
||||
address_space_init_dispatch(as);
|
||||
memory_region_update_pending |= root->enabled;
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
void address_space_destroy(AddressSpace *as)
|
||||
@ -1584,6 +1591,7 @@ void address_space_destroy(AddressSpace *as)
|
||||
address_space_destroy_dispatch(as);
|
||||
flatview_destroy(as->current_map);
|
||||
g_free(as->current_map);
|
||||
g_free(as->ioeventfds);
|
||||
}
|
||||
|
||||
uint64_t io_mem_read(MemoryRegion *mr, hwaddr addr, unsigned size)
|
||||
@ -1649,9 +1657,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
|
||||
base + mr->addr
|
||||
+ (hwaddr)int128_get64(mr->size) - 1,
|
||||
mr->priority,
|
||||
mr->readable ? 'R' : '-',
|
||||
!mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
|
||||
: '-',
|
||||
mr->romd_mode ? 'R' : '-',
|
||||
!mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
|
||||
: '-',
|
||||
mr->name,
|
||||
mr->alias->name,
|
||||
mr->alias_offset,
|
||||
@ -1664,9 +1672,9 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
|
||||
base + mr->addr
|
||||
+ (hwaddr)int128_get64(mr->size) - 1,
|
||||
mr->priority,
|
||||
mr->readable ? 'R' : '-',
|
||||
!mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
|
||||
: '-',
|
||||
mr->romd_mode ? 'R' : '-',
|
||||
!mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
|
||||
: '-',
|
||||
mr->name);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,10 @@
|
||||
#include "exec/cpu-defs.h"
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 64
|
||||
/* Actually 64-bits, limited by the memory API to 62 bits. We
|
||||
* never use that much.
|
||||
*/
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 62
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 64
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
@ -813,9 +813,6 @@ xen_map_cache_return(void* ptr) "%p"
|
||||
xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64
|
||||
xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
|
||||
|
||||
# exec.c
|
||||
qemu_put_ram_ptr(void* addr) "%p"
|
||||
|
||||
# hw/xen_platform.c
|
||||
xen_platform_log(char *s) "xen platform: %s"
|
||||
|
||||
|
@ -1358,7 +1358,7 @@ void tb_invalidate_phys_addr(hwaddr addr)
|
||||
section = phys_page_find(address_space_memory.dispatch,
|
||||
addr >> TARGET_PAGE_BITS);
|
||||
if (!(memory_region_is_ram(section->mr)
|
||||
|| (section->mr->rom_device && section->mr->readable))) {
|
||||
|| memory_region_is_romd(section->mr))) {
|
||||
return;
|
||||
}
|
||||
ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
|
||||
|
Loading…
Reference in New Issue
Block a user