summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/exec.c b/exec.c
index f4b9ef25f5..896f7b83fc 100644
--- a/exec.c
+++ b/exec.c
@@ -50,6 +50,7 @@
#include "translate-all.h"
#include "exec/memory-internal.h"
+#include "qemu/cache-utils.h"
//#define DEBUG_SUBPAGE
@@ -2010,9 +2011,13 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
address_space_rw(&address_space_memory, addr, buf, len, is_write);
}
-/* used for ROM loading : can write in RAM and ROM */
-void cpu_physical_memory_write_rom(hwaddr addr,
- const uint8_t *buf, int len)
+enum write_rom_type {
+ WRITE_DATA,
+ FLUSH_CACHE,
+};
+
+static inline void cpu_physical_memory_write_rom_internal(
+ hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
{
hwaddr l;
uint8_t *ptr;
@@ -2031,8 +2036,15 @@ void cpu_physical_memory_write_rom(hwaddr addr,
addr1 += memory_region_get_ram_addr(mr);
/* ROM/RAM case */
ptr = qemu_get_ram_ptr(addr1);
- memcpy(ptr, buf, l);
- invalidate_and_set_dirty(addr1, l);
+ switch (type) {
+ case WRITE_DATA:
+ memcpy(ptr, buf, l);
+ invalidate_and_set_dirty(addr1, l);
+ break;
+ case FLUSH_CACHE:
+ flush_icache_range((uintptr_t)ptr, (uintptr_t)ptr + l);
+ break;
+ }
}
len -= l;
buf += l;
@@ -2040,6 +2052,28 @@ void cpu_physical_memory_write_rom(hwaddr addr,
}
}
+/* used for ROM loading : can write in RAM and ROM */
+void cpu_physical_memory_write_rom(hwaddr addr,
+ const uint8_t *buf, int len)
+{
+ cpu_physical_memory_write_rom_internal(addr, buf, len, WRITE_DATA);
+}
+
+void cpu_flush_icache_range(hwaddr start, int len)
+{
+ /*
+ * This function should do the same thing as an icache flush that was
+ * triggered from within the guest. For TCG we are always cache coherent,
+ * so there is no need to flush anything. For KVM / Xen we need to flush
+ * the host's instruction cache at least.
+ */
+ if (tcg_enabled()) {
+ return;
+ }
+
+ cpu_physical_memory_write_rom_internal(start, NULL, len, FLUSH_CACHE);
+}
+
typedef struct {
MemoryRegion *mr;
void *buffer;