memory: add MemoryRegionOps::valid.accepts
MemoryRegionOps::valid tries to declaratively specify which transactions are accepted by the device/bus, however it is not completely generic. Add a callback for special cases. Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
5a31cd68ba
commit
897fa7cff2
12
memory.c
12
memory.c
@ -831,8 +831,14 @@ void memory_region_init(MemoryRegion *mr,
|
|||||||
|
|
||||||
static bool memory_region_access_valid(MemoryRegion *mr,
|
static bool memory_region_access_valid(MemoryRegion *mr,
|
||||||
target_phys_addr_t addr,
|
target_phys_addr_t addr,
|
||||||
unsigned size)
|
unsigned size,
|
||||||
|
bool is_write)
|
||||||
{
|
{
|
||||||
|
if (mr->ops->valid.accepts
|
||||||
|
&& !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -856,7 +862,7 @@ static uint32_t memory_region_read_thunk_n(void *_mr,
|
|||||||
MemoryRegion *mr = _mr;
|
MemoryRegion *mr = _mr;
|
||||||
uint64_t data = 0;
|
uint64_t data = 0;
|
||||||
|
|
||||||
if (!memory_region_access_valid(mr, addr, size)) {
|
if (!memory_region_access_valid(mr, addr, size, false)) {
|
||||||
return -1U; /* FIXME: better signalling */
|
return -1U; /* FIXME: better signalling */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,7 +886,7 @@ static void memory_region_write_thunk_n(void *_mr,
|
|||||||
{
|
{
|
||||||
MemoryRegion *mr = _mr;
|
MemoryRegion *mr = _mr;
|
||||||
|
|
||||||
if (!memory_region_access_valid(mr, addr, size)) {
|
if (!memory_region_access_valid(mr, addr, size, true)) {
|
||||||
return; /* FIXME: better signalling */
|
return; /* FIXME: better signalling */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
memory.h
7
memory.h
@ -71,6 +71,13 @@ struct MemoryRegionOps {
|
|||||||
* accesses throw machine checks.
|
* accesses throw machine checks.
|
||||||
*/
|
*/
|
||||||
bool unaligned;
|
bool unaligned;
|
||||||
|
/*
|
||||||
|
* If present, and returns #false, the transaction is not accepted
|
||||||
|
* by the device (and results in machine dependent behaviour such
|
||||||
|
* as a machine check exception).
|
||||||
|
*/
|
||||||
|
bool (*accepts)(void *opaque, target_phys_addr_t addr,
|
||||||
|
unsigned size, bool is_write);
|
||||||
} valid;
|
} valid;
|
||||||
/* Internal implementation constraints: */
|
/* Internal implementation constraints: */
|
||||||
struct {
|
struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user