]> git.proxmox.com Git - qemu.git/commitdiff
memory: add MemoryRegionOps::valid.accepts
authorAvi Kivity <avi@redhat.com>
Sun, 13 Nov 2011 11:05:27 +0000 (13:05 +0200)
committerAvi Kivity <avi@redhat.com>
Thu, 24 Nov 2011 16:32:00 +0000 (18:32 +0200)
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>
memory.c
memory.h

index 7c20a0703f8d0156708df8107ceaba85673595d5..adfdf1470c737a90afcc17463d4a70df0a283d41 100644 (file)
--- 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 */
     }
 
index 7fb36d16ec288a8524e2fed06fe61cf73fe77d02..53bf261792fc51776d3b4f8e471652d2e1f752d6 100644 (file)
--- 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 {