mirror of https://github.com/xqemu/xqemu.git
memory: introduce memory_region_set_enabled()
This allows users to disable a memory region without removing it from the hierarchy, simplifying the implementation of memory routers. Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
f44336c594
commit
6bba19ba4e
40
memory.c
40
memory.c
|
@ -528,6 +528,10 @@ static void render_memory_region(FlatView *view,
|
||||||
FlatRange fr;
|
FlatRange fr;
|
||||||
AddrRange tmp;
|
AddrRange tmp;
|
||||||
|
|
||||||
|
if (!mr->enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int128_addto(&base, int128_make64(mr->addr));
|
int128_addto(&base, int128_make64(mr->addr));
|
||||||
readonly |= mr->readonly;
|
readonly |= mr->readonly;
|
||||||
|
|
||||||
|
@ -750,12 +754,16 @@ static void address_space_update_topology(AddressSpace *as)
|
||||||
address_space_update_ioeventfds(as);
|
address_space_update_ioeventfds(as);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memory_region_update_topology(void)
|
static void memory_region_update_topology(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
if (memory_region_transaction_depth) {
|
if (memory_region_transaction_depth) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mr && !mr->enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (address_space_memory.root) {
|
if (address_space_memory.root) {
|
||||||
address_space_update_topology(&address_space_memory);
|
address_space_update_topology(&address_space_memory);
|
||||||
}
|
}
|
||||||
|
@ -773,7 +781,7 @@ void memory_region_transaction_commit(void)
|
||||||
{
|
{
|
||||||
assert(memory_region_transaction_depth);
|
assert(memory_region_transaction_depth);
|
||||||
--memory_region_transaction_depth;
|
--memory_region_transaction_depth;
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memory_region_destructor_none(MemoryRegion *mr)
|
static void memory_region_destructor_none(MemoryRegion *mr)
|
||||||
|
@ -813,6 +821,7 @@ void memory_region_init(MemoryRegion *mr,
|
||||||
}
|
}
|
||||||
mr->addr = 0;
|
mr->addr = 0;
|
||||||
mr->offset = 0;
|
mr->offset = 0;
|
||||||
|
mr->enabled = true;
|
||||||
mr->terminates = false;
|
mr->terminates = false;
|
||||||
mr->readable = true;
|
mr->readable = true;
|
||||||
mr->readonly = false;
|
mr->readonly = false;
|
||||||
|
@ -1058,7 +1067,7 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
|
||||||
uint8_t mask = 1 << client;
|
uint8_t mask = 1 << client;
|
||||||
|
|
||||||
mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
|
mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
|
bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
|
||||||
|
@ -1090,7 +1099,7 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
|
||||||
{
|
{
|
||||||
if (mr->readonly != readonly) {
|
if (mr->readonly != readonly) {
|
||||||
mr->readonly = readonly;
|
mr->readonly = readonly;
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,7 +1107,7 @@ void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
|
||||||
{
|
{
|
||||||
if (mr->readable != readable) {
|
if (mr->readable != readable) {
|
||||||
mr->readable = readable;
|
mr->readable = readable;
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1203,7 +1212,7 @@ void memory_region_add_eventfd(MemoryRegion *mr,
|
||||||
memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
|
memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
|
||||||
sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
|
sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
|
||||||
mr->ioeventfds[i] = mrfd;
|
mr->ioeventfds[i] = mrfd;
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_region_del_eventfd(MemoryRegion *mr,
|
void memory_region_del_eventfd(MemoryRegion *mr,
|
||||||
|
@ -1233,7 +1242,7 @@ void memory_region_del_eventfd(MemoryRegion *mr,
|
||||||
--mr->ioeventfd_nb;
|
--mr->ioeventfd_nb;
|
||||||
mr->ioeventfds = g_realloc(mr->ioeventfds,
|
mr->ioeventfds = g_realloc(mr->ioeventfds,
|
||||||
sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
|
sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memory_region_add_subregion_common(MemoryRegion *mr,
|
static void memory_region_add_subregion_common(MemoryRegion *mr,
|
||||||
|
@ -1274,7 +1283,7 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
|
||||||
}
|
}
|
||||||
QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
|
QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
|
||||||
done:
|
done:
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1303,19 +1312,28 @@ void memory_region_del_subregion(MemoryRegion *mr,
|
||||||
assert(subregion->parent == mr);
|
assert(subregion->parent == mr);
|
||||||
subregion->parent = NULL;
|
subregion->parent = NULL;
|
||||||
QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
|
QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled == mr->enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mr->enabled = enabled;
|
||||||
|
memory_region_update_topology(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_system_memory_map(MemoryRegion *mr)
|
void set_system_memory_map(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
address_space_memory.root = mr;
|
address_space_memory.root = mr;
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_system_io_map(MemoryRegion *mr)
|
void set_system_io_map(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
address_space_io.root = mr;
|
address_space_io.root = mr;
|
||||||
memory_region_update_topology();
|
memory_region_update_topology(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MemoryRegionList MemoryRegionList;
|
typedef struct MemoryRegionList MemoryRegionList;
|
||||||
|
|
17
memory.h
17
memory.h
|
@ -123,6 +123,7 @@ struct MemoryRegion {
|
||||||
bool terminates;
|
bool terminates;
|
||||||
bool readable;
|
bool readable;
|
||||||
bool readonly; /* For RAM regions */
|
bool readonly; /* For RAM regions */
|
||||||
|
bool enabled;
|
||||||
MemoryRegion *alias;
|
MemoryRegion *alias;
|
||||||
target_phys_addr_t alias_offset;
|
target_phys_addr_t alias_offset;
|
||||||
unsigned priority;
|
unsigned priority;
|
||||||
|
@ -501,6 +502,22 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
|
||||||
void memory_region_del_subregion(MemoryRegion *mr,
|
void memory_region_del_subregion(MemoryRegion *mr,
|
||||||
MemoryRegion *subregion);
|
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);
|
||||||
|
|
||||||
/* Start a transaction; changes will be accumulated and made visible only
|
/* Start a transaction; changes will be accumulated and made visible only
|
||||||
* when the transaction ends.
|
* when the transaction ends.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue