Replace the ldn_he_p/stn_he_p() calls by their explicit endianness
variants. Duplicate the MemoryRegionOps, using one entry for BIG
and another for LITTLE endianness. Select the proper MemoryRegionOps
in memory_region_init_ram_device_ptr().

Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
 system/memory.c | 68 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 48 insertions(+), 20 deletions(-)

diff --git a/system/memory.c b/system/memory.c
index 8b84661ae36..5bcdeaf0bee 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -1361,41 +1361,69 @@ const MemoryRegionOps unassigned_mem_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static uint64_t memory_region_ram_device_read(void *opaque,
-                                              hwaddr addr, unsigned size)
+static uint64_t memory_region_ram_device_read_le(void *opaque,
+                                                 hwaddr addr, unsigned size)
 {
     MemoryRegion *mr = opaque;
-    uint64_t data = ldn_he_p(mr->ram_block->host + addr, size);
+    uint64_t data = ldn_le_p(mr->ram_block->host + addr, size);
 
     trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size);
 
     return data;
 }
 
-static void memory_region_ram_device_write(void *opaque, hwaddr addr,
-                                           uint64_t data, unsigned size)
+static uint64_t memory_region_ram_device_read_be(void *opaque,
+                                                 hwaddr addr, unsigned size)
+{
+    MemoryRegion *mr = opaque;
+    uint64_t data = ldn_be_p(mr->ram_block->host + addr, size);
+
+    trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size);
+
+    return data;
+}
+
+static void memory_region_ram_device_write_le(void *opaque, hwaddr addr,
+                                              uint64_t data, unsigned size)
 {
     MemoryRegion *mr = opaque;
 
     trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, 
size);
 
-    stn_he_p(mr->ram_block->host + addr, size, data);
+    stn_le_p(mr->ram_block->host + addr, size, data);
 }
 
-static const MemoryRegionOps ram_device_mem_ops = {
-    .read = memory_region_ram_device_read,
-    .write = memory_region_ram_device_write,
-    .endianness = HOST_BIG_ENDIAN ? DEVICE_BIG_ENDIAN : DEVICE_LITTLE_ENDIAN,
-    .valid = {
-        .min_access_size = 1,
-        .max_access_size = 8,
-        .unaligned = true,
-    },
-    .impl = {
-        .min_access_size = 1,
-        .max_access_size = 8,
-        .unaligned = true,
+static void memory_region_ram_device_write_be(void *opaque, hwaddr addr,
+                                              uint64_t data, unsigned size)
+{
+    MemoryRegion *mr = opaque;
+
+    trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, 
size);
+
+    stn_be_p(mr->ram_block->host + addr, size, data);
+}
+
+static const MemoryRegionOps ram_device_mem_ops[2] = {
+    [0 ... 1] = {
+        .valid = {
+            .min_access_size = 1,
+            .max_access_size = 8,
+            .unaligned = true,
+        },
+        .impl = {
+            .min_access_size = 1,
+            .max_access_size = 8,
+            .unaligned = true,
+        },
     },
+
+    [0].endianness = DEVICE_LITTLE_ENDIAN,
+    [0].read = memory_region_ram_device_read_le,
+    [0].write = memory_region_ram_device_write_le,
+
+    [1].endianness = DEVICE_BIG_ENDIAN,
+    [1].read = memory_region_ram_device_read_be,
+    [1].write = memory_region_ram_device_write_be,
 };
 
 bool memory_region_access_valid(MemoryRegion *mr,
@@ -1712,7 +1740,7 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
     mr->ram = true;
     mr->terminates = true;
     mr->ram_device = true;
-    mr->ops = &ram_device_mem_ops;
+    mr->ops = &ram_device_mem_ops[HOST_BIG_ENDIAN];
     mr->opaque = mr;
     mr->destructor = memory_region_destructor_ram;
 
-- 
2.52.0


Reply via email to