summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-11-13 13:05:27 +0200
committerAvi Kivity <avi@redhat.com>2011-11-24 18:32:00 +0200
commit897fa7cff21a98b260a5b3e73eae39273fa60272 (patch)
treed9d13d7bf2e3cc4f98b57c7008efaa680b9e1847
parent5a31cd68bad16103beb6d3d4e65d5c401d8e5ff9 (diff)
downloadfocaccia-qemu-897fa7cff21a98b260a5b3e73eae39273fa60272.tar.gz
focaccia-qemu-897fa7cff21a98b260a5b3e73eae39273fa60272.zip
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>
-rw-r--r--memory.c12
-rw-r--r--memory.h7
2 files changed, 16 insertions, 3 deletions
diff --git a/memory.c b/memory.c
index 7c20a0703f..adfdf1470c 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 7fb36d16ec..53bf261792 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 {