diff --git a/qemu/aarch64.h b/qemu/aarch64.h index da10ce74..303cc6eb 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_aarch64 #define memory_region_set_alias_offset memory_region_set_alias_offset_aarch64 #define memory_region_set_enabled memory_region_set_enabled_aarch64 +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_aarch64 #define memory_region_set_readonly memory_region_set_readonly_aarch64 #define memory_region_set_size memory_region_set_size_aarch64 #define memory_region_size memory_region_size_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index fb4022b3..4f33a2e5 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_aarch64eb #define memory_region_set_alias_offset memory_region_set_alias_offset_aarch64eb #define memory_region_set_enabled memory_region_set_enabled_aarch64eb +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_aarch64eb #define memory_region_set_readonly memory_region_set_readonly_aarch64eb #define memory_region_set_size memory_region_set_size_aarch64eb #define memory_region_size memory_region_size_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index 08c749fe..e57a3cdb 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_arm #define memory_region_set_alias_offset memory_region_set_alias_offset_arm #define memory_region_set_enabled memory_region_set_enabled_arm +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_arm #define memory_region_set_readonly memory_region_set_readonly_arm #define memory_region_set_size memory_region_set_size_arm #define memory_region_size memory_region_size_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 9adc5d70..44a45b87 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_armeb #define memory_region_set_alias_offset memory_region_set_alias_offset_armeb #define memory_region_set_enabled memory_region_set_enabled_armeb +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_armeb #define memory_region_set_readonly memory_region_set_readonly_armeb #define memory_region_set_size memory_region_set_size_armeb #define memory_region_size memory_region_size_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index c7b9fc0f..31e66ae2 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2013,6 +2013,7 @@ symbols = ( 'memory_region_set_address', 'memory_region_set_alias_offset', 'memory_region_set_enabled', + 'memory_region_set_nonvolatile', 'memory_region_set_readonly', 'memory_region_set_size', 'memory_region_size', diff --git a/qemu/include/exec/memory.h b/qemu/include/exec/memory.h index 9b534da2..cc27a28e 100644 --- a/qemu/include/exec/memory.h +++ b/qemu/include/exec/memory.h @@ -174,6 +174,7 @@ struct MemoryRegion { bool ram; bool subpage; bool readonly; /* For RAM regions */ + bool nonvolatile; bool rom_device; bool flush_coalesced_mmio; bool global_locking; @@ -259,6 +260,7 @@ FlatView *address_space_to_flatview(AddressSpace *as); * @offset_within_address_space: the address of the first byte of the section * relative to the region's address space * @readonly: writes to this section are ignored + * @nonvolatile: this section is non-volatile */ struct MemoryRegionSection { MemoryRegion *mr; @@ -267,6 +269,7 @@ struct MemoryRegionSection { Int128 size; hwaddr offset_within_address_space; bool readonly; + bool nonvolatile; }; static inline MemoryRegionSection MemoryRegionSection_make(MemoryRegion *mr, FlatView *fv, @@ -676,6 +679,18 @@ static inline bool memory_region_is_rom(MemoryRegion *mr) return mr->ram && mr->readonly; } +/** + * memory_region_is_nonvolatile: check whether a memory region is non-volatile + * + * Returns %true is a memory region is non-volatile memory. + * + * @mr: the memory region being queried + */ +static inline bool memory_region_is_nonvolatile(MemoryRegion *mr) +{ + return mr->nonvolatile; +} + /** * memory_region_get_fd: Get a file descriptor backing a RAM memory region. * @@ -726,6 +741,17 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr); */ void memory_region_set_readonly(MemoryRegion *mr, bool readonly); +/** + * memory_region_set_nonvolatile: Turn a memory region non-volatile + * + * Allows a memory region to be marked as non-volatile. + * only useful on RAM regions. + * + * @mr: the region being updated. + * @nonvolatile: whether rhe region is to be non-volatile. + */ +void memory_region_set_nonvolatile(MemoryRegion *mr, bool nonvolatile); + /** * memory_region_clear_global_locking: Declares that access processing does * not depend on the QEMU global lock. diff --git a/qemu/m68k.h b/qemu/m68k.h index 77bd1dcb..c6115bff 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_m68k #define memory_region_set_alias_offset memory_region_set_alias_offset_m68k #define memory_region_set_enabled memory_region_set_enabled_m68k +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_m68k #define memory_region_set_readonly memory_region_set_readonly_m68k #define memory_region_set_size memory_region_set_size_m68k #define memory_region_size memory_region_size_m68k diff --git a/qemu/memory.c b/qemu/memory.c index 4e682563..2abf015a 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -252,6 +252,7 @@ struct FlatRange { AddrRange addr; uint8_t dirty_log_mask; bool readonly; + bool nonvolatile; }; /* Flattened global view of current active memory hierarchy. Kept in sorted @@ -281,6 +282,7 @@ section_from_flat_range(FlatRange *fr, FlatView *fv) s.size = fr->addr.size; s.offset_within_address_space = int128_get64(fr->addr.start); s.readonly = fr->readonly; + s.nonvolatile = fr->nonvolatile; return s; } @@ -289,7 +291,8 @@ 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->readonly == b->readonly; + && a->readonly == b->readonly + && a->nonvolatile == b->nonvolatile; } static FlatView *flatview_new(MemoryRegion *mr_root) @@ -381,7 +384,8 @@ 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->readonly == r2->readonly; + && r1->readonly == r2->readonly + && r1->nonvolatile == r2->nonvolatile; } /* Attempt to simplify a view by merging adjacent ranges */ @@ -609,7 +613,8 @@ static void render_memory_region(FlatView *view, MemoryRegion *mr, Int128 base, AddrRange clip, - bool readonly) + bool readonly, + bool nonvolatile) { MemoryRegion *subregion; unsigned i; @@ -625,6 +630,7 @@ static void render_memory_region(FlatView *view, int128_addto(&base, int128_make64(mr->addr)); readonly |= mr->readonly; + nonvolatile |= mr->nonvolatile; tmp = addrrange_make(base, mr->size); @@ -637,13 +643,15 @@ static void render_memory_region(FlatView *view, if (mr->alias) { int128_subfrom(&base, int128_make64(mr->alias->addr)); int128_subfrom(&base, int128_make64(mr->alias_offset)); - render_memory_region(view, mr->alias, base, clip, readonly); + render_memory_region(view, mr->alias, base, clip, + readonly, nonvolatile); return; } /* Render subregions in priority order. */ QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) { - render_memory_region(view, subregion, base, clip, readonly); + render_memory_region(view, subregion, base, clip, + readonly, nonvolatile); } if (!mr->terminates) { @@ -657,6 +665,7 @@ static void render_memory_region(FlatView *view, fr.mr = mr; fr.dirty_log_mask = mr->dirty_log_mask; fr.readonly = readonly; + fr.nonvolatile = nonvolatile; /* Render the region itself into any gaps left by the current view. */ for (i = 0; i < view->nr && int128_nz(remain); ++i) { @@ -739,7 +748,8 @@ static FlatView *generate_memory_topology(struct uc_struct *uc, MemoryRegion *mr if (mr) { render_memory_region(view, mr, int128_zero(), - addrrange_make(int128_zero(), int128_2_64()), false); + addrrange_make(int128_zero(), int128_2_64()), + false, false); } flatview_simplify(view); @@ -1574,6 +1584,16 @@ void memory_region_clear_global_locking(MemoryRegion *mr) mr->global_locking = false; } +void memory_region_set_nonvolatile(MemoryRegion *mr, bool nonvolatile) +{ + if (mr->nonvolatile != nonvolatile) { + memory_region_transaction_begin(mr->uc); + mr->nonvolatile = nonvolatile; + mr->uc->memory_region_update_pending |= mr->enabled; + memory_region_transaction_commit(mr->uc); + } +} + void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode) { if (mr->romd_mode != romd_mode) { @@ -1833,6 +1853,7 @@ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr, ret.size = range.size; ret.offset_within_address_space = int128_get64(range.start); ret.readonly = fr->readonly; + ret.nonvolatile = fr->nonvolatile; return ret; } diff --git a/qemu/mips.h b/qemu/mips.h index e8a9dcce..a685f27b 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_mips #define memory_region_set_alias_offset memory_region_set_alias_offset_mips #define memory_region_set_enabled memory_region_set_enabled_mips +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_mips #define memory_region_set_readonly memory_region_set_readonly_mips #define memory_region_set_size memory_region_set_size_mips #define memory_region_size memory_region_size_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index d8e12d35..ea8e85bf 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_mips64 #define memory_region_set_alias_offset memory_region_set_alias_offset_mips64 #define memory_region_set_enabled memory_region_set_enabled_mips64 +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_mips64 #define memory_region_set_readonly memory_region_set_readonly_mips64 #define memory_region_set_size memory_region_set_size_mips64 #define memory_region_size memory_region_size_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 7acba030..7bff5341 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_mips64el #define memory_region_set_alias_offset memory_region_set_alias_offset_mips64el #define memory_region_set_enabled memory_region_set_enabled_mips64el +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_mips64el #define memory_region_set_readonly memory_region_set_readonly_mips64el #define memory_region_set_size memory_region_set_size_mips64el #define memory_region_size memory_region_size_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index ec1b7af9..a1061380 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_mipsel #define memory_region_set_alias_offset memory_region_set_alias_offset_mipsel #define memory_region_set_enabled memory_region_set_enabled_mipsel +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_mipsel #define memory_region_set_readonly memory_region_set_readonly_mipsel #define memory_region_set_size memory_region_set_size_mipsel #define memory_region_size memory_region_size_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index e1d74e07..6c3d391a 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_powerpc #define memory_region_set_alias_offset memory_region_set_alias_offset_powerpc #define memory_region_set_enabled memory_region_set_enabled_powerpc +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_powerpc #define memory_region_set_readonly memory_region_set_readonly_powerpc #define memory_region_set_size memory_region_set_size_powerpc #define memory_region_size memory_region_size_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index cc85b0f2..fb1ff336 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_sparc #define memory_region_set_alias_offset memory_region_set_alias_offset_sparc #define memory_region_set_enabled memory_region_set_enabled_sparc +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_sparc #define memory_region_set_readonly memory_region_set_readonly_sparc #define memory_region_set_size memory_region_set_size_sparc #define memory_region_size memory_region_size_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 803d3877..8d61dfdf 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_sparc64 #define memory_region_set_alias_offset memory_region_set_alias_offset_sparc64 #define memory_region_set_enabled memory_region_set_enabled_sparc64 +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_sparc64 #define memory_region_set_readonly memory_region_set_readonly_sparc64 #define memory_region_set_size memory_region_set_size_sparc64 #define memory_region_size memory_region_size_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 9b10e25b..4204cb15 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2007,6 +2007,7 @@ #define memory_region_set_address memory_region_set_address_x86_64 #define memory_region_set_alias_offset memory_region_set_alias_offset_x86_64 #define memory_region_set_enabled memory_region_set_enabled_x86_64 +#define memory_region_set_nonvolatile memory_region_set_nonvolatile_x86_64 #define memory_region_set_readonly memory_region_set_readonly_x86_64 #define memory_region_set_size memory_region_set_size_x86_64 #define memory_region_size memory_region_size_x86_64