uint8_t dirty_log_mask;
bool romd_mode;
bool readonly;
+ bool nonvolatile;
};
#define FOR_EACH_FLAT_RANGE(var, view) \
.size = fr->addr.size,
.offset_within_address_space = int128_get64(fr->addr.start),
.readonly = fr->readonly,
+ .nonvolatile = fr->nonvolatile,
};
}
&& addrrange_equal(a->addr, b->addr)
&& a->offset_in_region == b->offset_in_region
&& a->romd_mode == b->romd_mode
- && a->readonly == b->readonly;
+ && a->readonly == b->readonly
+ && a->nonvolatile == b->nonvolatile;
}
static FlatView *flatview_new(MemoryRegion *mr_root)
int128_make64(r2->offset_in_region))
&& r1->dirty_log_mask == r2->dirty_log_mask
&& r1->romd_mode == r2->romd_mode
- && r1->readonly == r2->readonly;
+ && r1->readonly == r2->readonly
+ && r1->nonvolatile == r2->nonvolatile;
}
/* Attempt to simplify a view by merging adjacent ranges */
}
}
+static inline void memory_region_shift_read_access(uint64_t *value,
+ signed shift,
+ uint64_t mask,
+ uint64_t tmp)
+{
+ if (shift >= 0) {
+ *value |= (tmp & mask) << shift;
+ } else {
+ *value |= (tmp & mask) >> -shift;
+ }
+}
+
+static inline uint64_t memory_region_shift_write_access(uint64_t *value,
+ signed shift,
+ uint64_t mask)
+{
+ uint64_t tmp;
+
+ if (shift >= 0) {
+ tmp = (*value >> shift) & mask;
+ } else {
+ tmp = (*value << -shift) & mask;
+ }
+
+ return tmp;
+}
+
static hwaddr memory_region_to_absolute_addr(MemoryRegion *mr, hwaddr offset)
{
MemoryRegion *root;
return -1;
}
-static MemTxResult memory_region_oldmmio_read_accessor(MemoryRegion *mr,
- hwaddr addr,
- uint64_t *value,
- unsigned size,
- unsigned shift,
- uint64_t mask,
- MemTxAttrs attrs)
-{
- uint64_t tmp;
-
- tmp = mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr);
- if (mr->subpage) {
- trace_memory_region_subpage_read(get_cpu_index(), mr, addr, tmp, size);
- } else if (mr == &io_mem_notdirty) {
- /* Accesses to code which has previously been translated into a TB show
- * up in the MMIO path, as accesses to the io_mem_notdirty
- * MemoryRegion. */
- trace_memory_region_tb_read(get_cpu_index(), addr, tmp, size);
- } else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) {
- hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
- trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size);
- }
- *value |= (tmp & mask) << shift;
- return MEMTX_OK;
-}
-
static MemTxResult memory_region_read_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size);
}
- *value |= (tmp & mask) << shift;
+ memory_region_shift_read_access(value, shift, mask, tmp);
return MEMTX_OK;
}
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size);
}
- *value |= (tmp & mask) << shift;
+ memory_region_shift_read_access(value, shift, mask, tmp);
return r;
}
-static MemTxResult memory_region_oldmmio_write_accessor(MemoryRegion *mr,
- hwaddr addr,
- uint64_t *value,
- unsigned size,
- unsigned shift,
- uint64_t mask,
- MemTxAttrs attrs)
-{
- uint64_t tmp;
-
- tmp = (*value >> shift) & mask;
- if (mr->subpage) {
- trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, size);
- } else if (mr == &io_mem_notdirty) {
- /* Accesses to code which has previously been translated into a TB show
- * up in the MMIO path, as accesses to the io_mem_notdirty
- * MemoryRegion. */
- trace_memory_region_tb_write(get_cpu_index(), addr, tmp, size);
- } else if (TRACE_MEMORY_REGION_OPS_WRITE_ENABLED) {
- hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
- trace_memory_region_ops_write(get_cpu_index(), mr, abs_addr, tmp, size);
- }
- mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, tmp);
- return MEMTX_OK;
-}
-
static MemTxResult memory_region_write_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
- uint64_t tmp;
+ uint64_t tmp = memory_region_shift_write_access(value, shift, mask);
- tmp = (*value >> shift) & mask;
if (mr->subpage) {
trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, size);
} else if (mr == &io_mem_notdirty) {
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
- uint64_t tmp;
+ uint64_t tmp = memory_region_shift_write_access(value, shift, mask);
- tmp = (*value >> shift) & mask;
if (mr->subpage) {
trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, size);
} else if (mr == &io_mem_notdirty) {
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs),
MemoryRegion *mr,
MemoryRegion *mr,
Int128 base,
AddrRange clip,
- bool readonly)
+ bool readonly,
+ bool nonvolatile)
{
MemoryRegion *subregion;
unsigned i;
int128_addto(&base, int128_make64(mr->addr));
readonly |= mr->readonly;
+ nonvolatile |= mr->nonvolatile;
tmp = addrrange_make(base, mr->size);
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) {
fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr);
fr.romd_mode = mr->romd_mode;
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) {
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);
mr->ops->impl.max_access_size,
memory_region_read_accessor,
mr, attrs);
- } else if (mr->ops->read_with_attrs) {
+ } else {
return access_with_adjusted_size(addr, pval, size,
mr->ops->impl.min_access_size,
mr->ops->impl.max_access_size,
memory_region_read_with_attrs_accessor,
mr, attrs);
- } else {
- return access_with_adjusted_size(addr, pval, size, 1, 4,
- memory_region_oldmmio_read_accessor,
- mr, attrs);
}
}
mr->ops->impl.max_access_size,
memory_region_write_accessor, mr,
attrs);
- } else if (mr->ops->write_with_attrs) {
+ } else {
return
access_with_adjusted_size(addr, &data, size,
mr->ops->impl.min_access_size,
mr->ops->impl.max_access_size,
memory_region_write_with_attrs_accessor,
mr, attrs);
- } else {
- return access_with_adjusted_size(addr, &data, size, 1, 4,
- memory_region_oldmmio_write_accessor,
- mr, attrs);
}
}
}
}
+void memory_region_set_nonvolatile(MemoryRegion *mr, bool nonvolatile)
+{
+ if (mr->nonvolatile != nonvolatile) {
+ memory_region_transaction_begin();
+ mr->nonvolatile = nonvolatile;
+ memory_region_update_pending |= mr->enabled;
+ memory_region_transaction_commit();
+ }
+}
+
void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode)
{
if (mr->romd_mode != romd_mode) {
.size = fr->addr.size,
};
- MEMORY_LISTENER_CALL(as, coalesced_mmio_del, Reverse, §ion,
+ MEMORY_LISTENER_CALL(as, coalesced_io_del, Reverse, §ion,
int128_get64(fr->addr.start),
int128_get64(fr->addr.size));
QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
continue;
}
tmp = addrrange_intersection(tmp, fr->addr);
- MEMORY_LISTENER_CALL(as, coalesced_mmio_add, Forward, §ion,
+ MEMORY_LISTENER_CALL(as, coalesced_io_add, Forward, §ion,
int128_get64(tmp.start),
int128_get64(tmp.size));
}
ret.size = range.size;
ret.offset_within_address_space = int128_get64(range.start);
ret.readonly = fr->readonly;
+ ret.nonvolatile = fr->nonvolatile;
return ret;
}
QTAILQ_INSERT_TAIL(alias_print_queue, ml, mrqueue);
}
mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx
- " (prio %d, %s): alias %s @%s " TARGET_FMT_plx
+ " (prio %d, %s%s): alias %s @%s " TARGET_FMT_plx
"-" TARGET_FMT_plx "%s",
cur_start, cur_end,
mr->priority,
+ mr->nonvolatile ? "nv-" : "",
memory_region_type((MemoryRegion *)mr),
memory_region_name(mr),
memory_region_name(mr->alias),
}
} else {
mon_printf(f,
- TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %s): %s%s",
+ TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %s%s): %s%s",
cur_start, cur_end,
mr->priority,
+ mr->nonvolatile ? "nv-" : "",
memory_region_type((MemoryRegion *)mr),
memory_region_name(mr),
mr->enabled ? "" : " [disabled]");
mr = range->mr;
if (range->offset_in_region) {
p(f, MTREE_INDENT TARGET_FMT_plx "-"
- TARGET_FMT_plx " (prio %d, %s): %s @" TARGET_FMT_plx,
+ TARGET_FMT_plx " (prio %d, %s%s): %s @" TARGET_FMT_plx,
int128_get64(range->addr.start),
int128_get64(range->addr.start) + MR_SIZE(range->addr.size),
mr->priority,
+ range->nonvolatile ? "nv-" : "",
range->readonly ? "rom" : memory_region_type(mr),
memory_region_name(mr),
range->offset_in_region);
} else {
p(f, MTREE_INDENT TARGET_FMT_plx "-"
- TARGET_FMT_plx " (prio %d, %s): %s",
+ TARGET_FMT_plx " (prio %d, %s%s): %s",
int128_get64(range->addr.start),
int128_get64(range->addr.start) + MR_SIZE(range->addr.size),
mr->priority,
+ range->nonvolatile ? "nv-" : "",
range->readonly ? "rom" : memory_region_type(mr),
memory_region_name(mr));
}