From 897fa7cff21a98b260a5b3e73eae39273fa60272 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 13 Nov 2011 13:05:27 +0200 Subject: [PATCH] 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 --- memory.c | 12 +++++++++--- memory.h | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/memory.c b/memory.c index 7c20a07..adfdf14 100644 --- a/memory.c +++ b/memory.c @@ -831,8 +831,14 @@ void memory_region_init(MemoryRegion *mr, static bool memory_region_access_valid(MemoryRegion *mr, 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))) { return false; } @@ -856,7 +862,7 @@ static uint32_t memory_region_read_thunk_n(void *_mr, MemoryRegion *mr = _mr; 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 */ } @@ -880,7 +886,7 @@ static void memory_region_write_thunk_n(void *_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 */ } diff --git a/memory.h b/memory.h index 7fb36d1..53bf261 100644 --- a/memory.h +++ b/memory.h @@ -71,6 +71,13 @@ struct MemoryRegionOps { * accesses throw machine checks. */ 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; /* Internal implementation constraints: */ struct { -- 2.7.4