qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely


From: Peter Crosthwaite
Subject: [Qemu-devel] [RFC v2 21/34] core: virtualise CPU interfaces completely
Date: Sat, 30 May 2015 23:11:54 -0700

The core code interfaces to translate-all, cpu-tlb and cpu-exec are
virtualised. This prepare support for multi-arch where these modules
are multi-compiled for the different target backends and will need
to co-exist.

The names of functions are not changed. They still have their generic
names and can be linked to the final build as-is. qom/cpu.c will pickup
the one and only default implementation and set the hook in the base
class and everyone is happy.

In multi-arch, the arch-obj components have all symbols localised which
includes all of the function defs for these hooks (despite them still
having generic names and global linkage). So it is up to the target
specific sub-class to install theses hooks. Multiple targets can do this
and then link together. The CPU base class will harmlessly set the
hooks to stubs but in multi-arch these must be overridden.

The tcg_ctx global is tricky. It needs to become part of the cpu state.
This is done via a pointer.

tlb_reset_dirty_all was refactored to just reset_dirty for the one cpu.
The loop over all CPUs is pushed up to common code.

Signed-off-by: Peter Crosthwaite <address@hidden>
---
 cpu-exec.c              | 22 +++++++-------
 cpus.c                  |  4 +--
 cputlb.c                | 40 +++++++++++++-------------
 exec.c                  | 32 +++++++++++----------
 gdbstub.c               |  2 +-
 include/exec/cputlb.h   |  2 --
 include/exec/exec-all.h | 15 ----------
 include/qemu-common.h   |  4 +++
 include/qom/cpu.h       | 62 ++++++++++++++++++++++++++++++++++++++++
 qom/cpu.c               |  1 +
 stubs/Makefile.objs     |  1 +
 stubs/cpu-qom.c         | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-microblaze/cpu.h |  1 -
 tcg/tcg.h               |  5 ++--
 tcg/tci/tcg-target.h    |  3 +-
 tci.c                   |  2 +-
 translate-all.c         |  9 ++----
 translate-all.h         |  2 --
 18 files changed, 203 insertions(+), 80 deletions(-)
 create mode 100644 stubs/cpu-qom.c

diff --git a/cpu-exec.c b/cpu-exec.c
index f255ea9..ae6aff9 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -151,7 +151,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, 
uint8_t *tb_ptr)
 #endif /* DEBUG_DISAS */
 
     cpu->can_do_io = 0;
-    next_tb = tcg_qemu_tb_exec(env, tb_ptr);
+    next_tb = tcg_qemu_tb_exec((TCGContext *)cpu->tcg_ctx, env, tb_ptr);
     cpu->can_do_io = 1;
     trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
                        next_tb & TB_EXIT_MASK);
@@ -217,14 +217,15 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
     unsigned int h;
     tb_page_addr_t phys_pc, phys_page1;
     target_ulong virt_page2;
+    TCGContext *tcg_ctx = (TCGContext *)cpu->tcg_ctx;
 
-    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
+    tcg_ctx->tb_ctx.tb_invalidated_flag = 0;
 
     /* find translated block using physical mappings */
     phys_pc = get_page_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;
     h = tb_phys_hash_func(phys_pc);
-    ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
+    ptb1 = &tcg_ctx->tb_ctx.tb_phys_hash[h];
     for(;;) {
         tb = *ptb1;
         if (!tb)
@@ -256,8 +257,8 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
     /* Move the last found TB to the head of the list */
     if (likely(*ptb1)) {
         *ptb1 = tb->phys_hash_next;
-        tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
-        tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
+        tb->phys_hash_next = tcg_ctx->tb_ctx.tb_phys_hash[h];
+        tcg_ctx->tb_ctx.tb_phys_hash[h] = tb;
     }
     /* we add the TB in the virtual pc hash table */
     cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
@@ -306,6 +307,7 @@ int cpu_exec(CPUState *cpu)
     X86CPU *x86_cpu = X86_CPU(cpu);
     CPUArchState *env = (CPUArchState *)cpu->env_ptr;
 #endif
+    TCGContext *tcg_ctx = (TCGContext *)cpu->tcg_ctx;
     int ret, interrupt_request;
     TranslationBlock *tb;
     uint8_t *tc_ptr;
@@ -431,17 +433,17 @@ int cpu_exec(CPUState *cpu)
                     cpu->exception_index = EXCP_INTERRUPT;
                     cpu_loop_exit(cpu);
                 }
-                spin_lock(&tcg_ctx.tb_ctx.tb_lock);
+                spin_lock(&tcg_ctx->tb_ctx.tb_lock);
                 have_tb_lock = true;
                 tb = tb_find_fast(cpu);
                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
                    doing it in tb_find_slow */
-                if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
+                if (tcg_ctx->tb_ctx.tb_invalidated_flag) {
                     /* as some TB could have been invalidated because
                        of memory exceptions while generating the code, we
                        must recompute the hash index here */
                     next_tb = 0;
-                    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
+                    tcg_ctx->tb_ctx.tb_invalidated_flag = 0;
                 }
                 if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
                     qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
@@ -455,7 +457,7 @@ int cpu_exec(CPUState *cpu)
                                 next_tb & TB_EXIT_MASK, tb);
                 }
                 have_tb_lock = false;
-                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
+                spin_unlock(&tcg_ctx->tb_ctx.tb_lock);
 
                 /* cpu_interrupt might be called while translating the
                    TB, but before it is linked into a potentially
@@ -524,7 +526,7 @@ int cpu_exec(CPUState *cpu)
             x86_cpu = X86_CPU(cpu);
 #endif
             if (have_tb_lock) {
-                spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
+                spin_unlock(&tcg_ctx->tb_ctx.tb_lock);
                 have_tb_lock = false;
             }
         }
diff --git a/cpus.c b/cpus.c
index 441a026..198a15b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1353,7 +1353,7 @@ static int tcg_cpu_exec(CPUState *cpu)
         cpu->icount_decr.u16.low = decr;
         cpu->icount_extra = count;
     }
-    ret = cpu_exec(cpu);
+    ret = cpu->cpu_exec(cpu);
 #ifdef CONFIG_PROFILER
     tcg_time += profile_getclock() - ti;
 #endif
@@ -1433,7 +1433,7 @@ void cpu_reload_memory_map(CPUState *cpu)
     /* The CPU and TLB are protected by the iothread lock.  */
     d = atomic_rcu_read(&cpu->as->dispatch);
     cpu->memory_dispatch = d;
-    tlb_flush(cpu, 1);
+    cpu->tlb_flush(cpu, 1);
 }
 #endif
 
diff --git a/cputlb.c b/cputlb.c
index 7606548..bb482d3 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -81,7 +81,7 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, 
target_ulong addr)
     }
 }
 
-void tlb_flush_page(CPUState *cpu, target_ulong addr)
+void tlb_flush_page(CPUState *cpu, uint64_t addr)
 {
     CPUArchState *env = cpu->env_ptr;
     int i;
@@ -166,27 +166,24 @@ static inline ram_addr_t 
qemu_ram_addr_from_host_nofail(void *ptr)
     return ram_addr;
 }
 
-void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
 {
-    CPUState *cpu;
     CPUArchState *env;
 
-    CPU_FOREACH(cpu) {
-        int mmu_idx;
+    int mmu_idx;
 
-        env = cpu->env_ptr;
-        for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
-            unsigned int i;
+    env = cpu->env_ptr;
+    for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
+        unsigned int i;
 
-            for (i = 0; i < CPU_TLB_SIZE; i++) {
-                tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
-                                      start1, length);
-            }
+        for (i = 0; i < CPU_TLB_SIZE; i++) {
+            tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
+                                  start1, length);
+        }
 
-            for (i = 0; i < CPU_VTLB_SIZE; i++) {
-                tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
-                                      start1, length);
-            }
+        for (i = 0; i < CPU_VTLB_SIZE; i++) {
+            tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
+                                  start1, length);
         }
     }
 }
@@ -200,21 +197,22 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, 
target_ulong vaddr)
 
 /* update the TLB corresponding to virtual page vaddr
    so that it is no longer dirty */
-void tlb_set_dirty(CPUArchState *env, target_ulong vaddr)
+void tlb_set_dirty(CPUState *cpu, vaddr addr)
 {
+    CPUArchState *env = cpu->env_ptr;
     int i;
     int mmu_idx;
 
-    vaddr &= TARGET_PAGE_MASK;
-    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    addr &= TARGET_PAGE_MASK;
+    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
-        tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr);
+        tlb_set_dirty1(&env->tlb_table[mmu_idx][i], addr);
     }
 
     for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
         int k;
         for (k = 0; k < CPU_VTLB_SIZE; k++) {
-            tlb_set_dirty1(&env->tlb_v_table[mmu_idx][k], vaddr);
+            tlb_set_dirty1(&env->tlb_v_table[mmu_idx][k], addr);
         }
     }
 }
diff --git a/exec.c b/exec.c
index 200d18b..05b0a68 100644
--- a/exec.c
+++ b/exec.c
@@ -434,7 +434,7 @@ static int cpu_common_post_load(void *opaque, int 
version_id)
     /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
        version_id is increased. */
     cpu->interrupt_request &= ~0x01;
-    tlb_flush(cpu, 1);
+    cpu->tlb_flush(cpu, 1);
 
     return 0;
 }
@@ -561,15 +561,15 @@ void cpu_exec_init(CPUState *cpu)
 #if defined(CONFIG_USER_ONLY)
 static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
-    tb_invalidate_phys_page_range(pc, pc + 1, 0);
+    cpu->tb_invalidate_phys_page_range(pc, pc + 1, 0);
 }
 #else
 static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
 {
     hwaddr phys = cpu_get_phys_page_debug(cpu, pc);
     if (phys != -1) {
-        tb_invalidate_phys_addr(cpu->as,
-                                phys | (pc & ~TARGET_PAGE_MASK));
+        cpu->tb_invalidate_phys_addr(cpu->as,
+                                     phys | (pc & ~TARGET_PAGE_MASK));
     }
 }
 #endif
@@ -621,7 +621,7 @@ int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr 
len,
         QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
     }
 
-    tlb_flush_page(cpu, addr);
+    cpu->tlb_flush_page(cpu, addr);
 
     if (watchpoint)
         *watchpoint = wp;
@@ -649,7 +649,7 @@ void cpu_watchpoint_remove_by_ref(CPUState *cpu, 
CPUWatchpoint *watchpoint)
 {
     QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
 
-    tlb_flush_page(cpu, watchpoint->vaddr);
+    cpu->tlb_flush_page(cpu, watchpoint->vaddr);
 
     g_free(watchpoint);
 }
@@ -761,7 +761,7 @@ void cpu_single_step(CPUState *cpu, int enabled)
         } else {
             /* must flush all the translated code to avoid inconsistencies */
             /* XXX: only flush what is necessary */
-            tb_flush(cpu);
+            cpu->tb_flush(cpu);
         }
     }
 }
@@ -840,6 +840,7 @@ found:
 
 static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length)
 {
+    CPUState *cpu;
     ram_addr_t start1;
     RAMBlock *block;
     ram_addr_t end;
@@ -851,7 +852,9 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, 
ram_addr_t length)
     block = qemu_get_ram_block(start);
     assert(block == qemu_get_ram_block(end - 1));
     start1 = (uintptr_t)ramblock_ptr(block, start - block->offset);
-    cpu_tlb_reset_dirty_all(start1, length);
+    CPU_FOREACH(cpu) {
+        cpu->tlb_reset_dirty(cpu, start1, length);
+    }
     rcu_read_unlock();
 }
 
@@ -1807,7 +1810,7 @@ static void notdirty_mem_write(void *opaque, hwaddr 
ram_addr,
                                uint64_t val, unsigned size)
 {
     if (!cpu_physical_memory_get_dirty_flag(ram_addr, DIRTY_MEMORY_CODE)) {
-        tb_invalidate_phys_page_fast(ram_addr, size);
+        current_cpu->tb_invalidate_phys_page_fast(ram_addr, size);
     }
     switch (size) {
     case 1:
@@ -1826,8 +1829,7 @@ static void notdirty_mem_write(void *opaque, hwaddr 
ram_addr,
     /* we remove the notdirty callback only if the code has been
        flushed */
     if (!cpu_physical_memory_is_clean(ram_addr)) {
-        CPUArchState *env = current_cpu->env_ptr;
-        tlb_set_dirty(env, current_cpu->mem_io_vaddr);
+        current_cpu->tlb_set_dirty(current_cpu, current_cpu->mem_io_vaddr);
     }
 }
 
@@ -1877,7 +1879,7 @@ static void check_watchpoint(int offset, int len, 
MemTxAttrs attrs, int flags)
             wp->hitattrs = attrs;
             if (!cpu->watchpoint_hit) {
                 cpu->watchpoint_hit = wp;
-                tb_check_watchpoint(cpu);
+                cpu->tb_check_watchpoint(cpu);
                 if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                     cpu->exception_index = EXCP_DEBUG;
                     cpu_loop_exit(cpu);
@@ -1885,7 +1887,7 @@ static void check_watchpoint(int offset, int len, 
MemTxAttrs attrs, int flags)
 #if 0
 /* FIXME: Virtualise cpu_get_tb_cpu_state */
                     cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
-                    tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
+                    cpu->tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
 #endif
                     cpu_resume_from_signal(cpu, NULL);
                 }
@@ -2288,7 +2290,7 @@ static void invalidate_and_set_dirty(hwaddr addr,
                                      hwaddr length)
 {
     if (cpu_physical_memory_range_includes_clean(addr, length)) {
-        tb_invalidate_phys_range(addr, addr + length, 0);
+        current_cpu->tb_invalidate_phys_range(addr, addr + length, 0);
         cpu_physical_memory_set_dirty_range_nocode(addr, length);
     }
     xen_modified_memory(addr, length);
@@ -3041,7 +3043,7 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr 
addr, uint32_t val,
         if (unlikely(in_migration)) {
             if (cpu_physical_memory_is_clean(addr1)) {
                 /* invalidate code */
-                tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
+                current_cpu->tb_invalidate_phys_page_range(addr1, addr1 + 4, 
0);
                 /* set dirty bit */
                 cpu_physical_memory_set_dirty_range_nocode(addr1, 4);
             }
diff --git a/gdbstub.c b/gdbstub.c
index d37943a..e252b85 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1244,7 +1244,7 @@ static void gdb_vm_state_change(void *opaque, int 
running, RunState state)
             cpu->watchpoint_hit = NULL;
             goto send_packet;
         }
-        tb_flush(cpu);
+        cpu->tb_flush(cpu);
         ret = GDB_SIGNAL_TRAP;
         break;
     case RUN_STATE_PAUSED:
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
index 9167ff6..6fc78c9 100644
--- a/include/exec/cputlb.h
+++ b/include/exec/cputlb.h
@@ -26,8 +26,6 @@ void tlb_unprotect_code_phys(CPUState *cpu, ram_addr_t 
ram_addr,
                              target_ulong vaddr);
 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
                            uintptr_t length);
-void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
-void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
 extern int tlb_flush_count;
 
 #endif
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 745cb4a..2314cd6 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -83,35 +83,21 @@ void page_size_init(void);
 
 void QEMU_NORETURN cpu_resume_from_signal(CPUState *cpu, void *puc);
 void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
-TranslationBlock *tb_gen_code(CPUState *cpu,
-                              target_ulong pc, target_ulong cs_base, int flags,
-                              int cflags);
 void cpu_exec_init(CPUState *env);
 void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
 int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
-void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
-                                   int is_cpu_write_access);
-void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
-                              int is_cpu_write_access);
 #if !defined(CONFIG_USER_ONLY)
 bool qemu_in_vcpu_thread(void);
 void cpu_reload_memory_map(CPUState *cpu);
 void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
 /* cputlb.c */
-void tlb_flush_page(CPUState *cpu, target_ulong addr);
-void tlb_flush(CPUState *cpu, int flush_global);
 void tlb_set_page(CPUState *cpu, target_ulong vaddr,
                   hwaddr paddr, int prot,
                   int mmu_idx, target_ulong size);
 void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
                              hwaddr paddr, MemTxAttrs attrs,
                              int prot, int mmu_idx, target_ulong size);
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
 #else
-static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
-{
-}
-
 static inline void tlb_flush(CPUState *cpu, int flush_global)
 {
 }
@@ -196,7 +182,6 @@ struct TBContext {
 };
 
 void tb_free(TranslationBlock *tb);
-void tb_flush(CPUState *cpu);
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
 
 #if defined(USE_DIRECT_JUMP)
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 88fbcfa..79b548a 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -265,7 +265,11 @@ typedef struct PCIHostDeviceAddress {
 
 void tcg_exec_init_add(void (*fn)(unsigned long));
 void tcg_exec_init(unsigned long tb_size);
+
+#if 0
 bool tcg_enabled(void);
+#endif
+#define tcg_enabled() true
 
 void cpu_exec_init_all(void);
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 9863db8..a579c18 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -73,6 +73,9 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr 
addr,
 
 struct TranslationBlock;
 
+struct TCGContext;
+extern struct TCGContext *tcg_ctx_ptr;
+
 /**
  * CPUClass:
  * @class_by_name: Callback to map -cpu command line model name to an
@@ -320,8 +323,67 @@ struct CPUState {
        (absolute value) offset as small as possible.  This reduces code
        size, especially for hosts without large memory offsets.  */
     volatile sig_atomic_t tcg_exit_req;
+
+    struct TCGContext *tcg_ctx;
+
+    void (*tlb_flush)(CPUState *cpu, int flush_global);
+    void (*tlb_flush_page)(CPUState *cpu, uint64_t addr);
+    void (*tlb_set_dirty)(CPUState *cpu, vaddr addr);
+    void (*tlb_reset_dirty)(CPUState *cpu, ram_addr_t start, ram_addr_t 
length);
+
+    void (*tb_check_watchpoint)(CPUState *cpu);
+    void (*tb_flush)(CPUState *cpu);
+    struct TranslationBlock *(*tb_gen_code)(CPUState *cpu, vaddr pc,
+                                            vaddr cs_base,
+                                            int flags, int cflags);
+    void (*tb_invalidate_phys_addr)(AddressSpace *as, hwaddr addr);
+    void (*tb_invalidate_phys_page_range)(tb_page_addr_t start,
+                                          tb_page_addr_t end,
+                                          int is_cpu_write_access);
+    void (*tb_invalidate_phys_page_fast)(tb_page_addr_t start, int len);
+    void (*tb_invalidate_phys_range)(tb_page_addr_t start, tb_page_addr_t end,
+                                     int is_cpu_write_access);
+
+    int (*cpu_exec)(CPUState *cpu);
 };
 
+void tlb_flush(CPUState *cpu, int flush_global);
+void tlb_flush_page(CPUState *cpu, uint64_t addr);
+void tlb_set_dirty(CPUState *cpu, vaddr addr);
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start, ram_addr_t length);
+
+void tb_check_watchpoint(CPUState *cpu);
+void tb_flush(CPUState *cpu);
+struct TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc, vaddr cs_base,
+                                     int flags, int cflags);
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
+void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
+                                   int is_cpu_write_access);
+void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
+void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
+                              int is_cpu_write_access);
+
+int cpu_exec(CPUState *cpu);
+
+#define CPU_SET_QOM_HOOKS(cpu) do {                                         \
+    cpu->tcg_ctx                        = tcg_ctx_ptr;                      \
+                                                                            \
+    cpu->tlb_flush                      = tlb_flush;                        \
+    cpu->tlb_flush_page                 = tlb_flush_page;                   \
+    cpu->tlb_set_dirty                  = tlb_set_dirty;                    \
+    cpu->tlb_reset_dirty                = tlb_reset_dirty;                  \
+                                                                            \
+    cpu->tb_check_watchpoint            = tb_check_watchpoint;              \
+    cpu->tb_flush                       = tb_flush;                         \
+    cpu->tb_gen_code                    = tb_gen_code;                      \
+    cpu->tb_invalidate_phys_addr        = tb_invalidate_phys_addr;          \
+    cpu->tb_invalidate_phys_page_range  = tb_invalidate_phys_page_range;    \
+    cpu->tb_invalidate_phys_page_fast   = tb_invalidate_phys_page_fast;     \
+    cpu->tb_invalidate_phys_range       = tb_invalidate_phys_range;         \
+                                                                            \
+    cpu->cpu_exec                       = cpu_exec;                         \
+} while (0);
+
 QTAILQ_HEAD(CPUTailQ, CPUState);
 extern struct CPUTailQ cpus;
 #define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
diff --git a/qom/cpu.c b/qom/cpu.c
index 108bfa2..605e69c 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -312,6 +312,7 @@ static void cpu_common_initfn(Object *obj)
     CPUState *cpu = CPU(obj);
     CPUClass *cc = CPU_GET_CLASS(obj);
 
+    CPU_SET_QOM_HOOKS(cpu);
     cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
 }
 
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 8beff4c..f01d577 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -6,6 +6,7 @@ stub-obj-y += chr-testdev.o
 stub-obj-y += clock-warp.o
 stub-obj-y += cpu-get-clock.o
 stub-obj-y += cpu-get-icount.o
+stub-obj-y += cpu-qom.o
 stub-obj-y += dump.o
 stub-obj-y += fdset-add-fd.o
 stub-obj-y += fdset-find-fd.o
diff --git a/stubs/cpu-qom.c b/stubs/cpu-qom.c
new file mode 100644
index 0000000..e994f5b
--- /dev/null
+++ b/stubs/cpu-qom.c
@@ -0,0 +1,76 @@
+#include "qom/cpu.h"
+
+static void qom_hook_error(const char *fn_name)
+{
+    fprintf(stderr, "Function %s called from core code. Stub implemention"
+            " called. This function should be called via the CPU qom hook.\n",
+            fn_name);
+    abort();
+}
+
+struct TCGContext *tcg_ctx_ptr;
+
+void tlb_flush(CPUState *cpu, int flush_global)
+{
+    qom_hook_error(__func__);
+}
+
+void tlb_flush_page(CPUState *cpu, uint64_t addr)
+{
+    qom_hook_error(__func__);
+}
+
+void tlb_set_dirty(CPUState *cpu, vaddr addr)
+{
+    qom_hook_error(__func__);
+}
+
+void tlb_reset_dirty(CPUState *cpu, ram_addr_t start, ram_addr_t length)
+{
+    qom_hook_error(__func__);
+}
+
+void tb_check_watchpoint(CPUState *cpu)
+{
+    qom_hook_error(__func__);
+}
+
+void tb_flush(CPUState *cpu)
+{
+    qom_hook_error(__func__);
+}
+
+struct TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc, vaddr cs_base,
+                                     int flags, int cflags)
+{
+    qom_hook_error(__func__);
+    return NULL;
+}
+
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
+{
+    qom_hook_error(__func__);
+}
+
+void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
+                                   int is_cpu_write_access)
+{
+    qom_hook_error(__func__);
+}
+
+void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
+{
+    qom_hook_error(__func__);
+}
+
+void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
+                              int is_cpu_write_access)
+{
+    qom_hook_error(__func__);
+}
+
+int cpu_exec(CPUState *cpu)
+{
+    qom_hook_error(__func__);
+    return 0;
+}
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index d2dfeb4..9068272 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -292,7 +292,6 @@ int cpu_mb_signal_handler(int host_signum, void *pinfo,
 
 #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model))
 
-#define cpu_exec cpu_mb_exec
 #define cpu_gen_code cpu_mb_gen_code
 #define cpu_signal_handler cpu_mb_signal_handler
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 8b0b696..64c451d 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -930,8 +930,9 @@ static inline unsigned get_mmuidx(TCGMemOpIdx oi)
 #define TB_EXIT_REQUESTED 3
 
 #if !defined(tcg_qemu_tb_exec)
-# define tcg_qemu_tb_exec(env, tb_ptr) \
-    ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
+# define tcg_qemu_tb_exec(tcg_ctx, env, tb_ptr) \
+    ((uintptr_t (*)(void *, void *)) \
+        (tcg_ctx)->code_gen_prologue)((env), (tb_ptr))
 #endif
 
 void tcg_register_jit(void *buf, size_t buf_size);
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index bd1e974..0987ff3 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -175,7 +175,8 @@ typedef enum {
 
 void tci_disas(uint8_t opc);
 
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
+uintptr_t tcg_qemu_tb_exec(TCGContext *tcg_ctx, CPUArchState *env,
+                           uint8_t *tb_ptr);
 #define tcg_qemu_tb_exec tcg_qemu_tb_exec
 
 static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
diff --git a/tci.c b/tci.c
index a14717d..ffd5f91 100644
--- a/tci.c
+++ b/tci.c
@@ -466,7 +466,7 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond 
condition)
 #endif
 
 /* Interpret pseudo code in tb. */
-uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
+uintptr_t tcg_qemu_tb_exec(TCGContext *tcg_ctx, CPUArchState *env, uint8_t 
*tb_ptr)
 {
     long tcg_temps[CPU_TEMP_BUF_NLONGS];
     uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
diff --git a/translate-all.c b/translate-all.c
index 4854828..d0ec080 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -123,6 +123,7 @@ static void *l1_map[V_L1_SIZE];
 
 /* code generation context */
 TCGContext tcg_ctx;
+TCGContext *tcg_ctx_ptr = &tcg_ctx;
 
 static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
                          tb_page_addr_t phys_page2);
@@ -693,11 +694,6 @@ static __attribute__((constructor)) void 
register_tcg_exec_init(void)
     tcg_exec_init_add(do_tcg_exec_init);
 }
 
-bool tcg_enabled(void)
-{
-    return tcg_ctx.code_gen_buffer != NULL;
-}
-
 /* Allocate a new translation block. Flush the translation buffer if
    too many translation blocks or too much generated code. */
 static TranslationBlock *tb_alloc(target_ulong pc)
@@ -994,8 +990,7 @@ static void build_page_bitmap(PageDesc *p)
     }
 }
 
-TranslationBlock *tb_gen_code(CPUState *cpu,
-                              target_ulong pc, target_ulong cs_base,
+TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc, vaddr cs_base,
                               int flags, int cflags)
 {
     CPUArchState *env = cpu->env_ptr;
diff --git a/translate-all.h b/translate-all.h
index 02832b2..7c079fd 100644
--- a/translate-all.h
+++ b/translate-all.h
@@ -20,8 +20,6 @@
 #define TRANSLATE_ALL_H
 
 /* translate-all.c */
-void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len);
 void cpu_unlink_tb(CPUState *cpu);
-void tb_check_watchpoint(CPUState *cpu);
 
 #endif /* TRANSLATE_ALL_H */
-- 
1.9.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]