qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

internal.h (3774B)


      1 /*
      2  * Internal execution defines for qemu
      3  *
      4  *  Copyright (c) 2003 Fabrice Bellard
      5  *
      6  * SPDX-License-Identifier: LGPL-2.1-or-later
      7  */
      8 
      9 #ifndef ACCEL_TCG_INTERNAL_H
     10 #define ACCEL_TCG_INTERNAL_H
     11 
     12 #include "exec/exec-all.h"
     13 
     14 /*
     15  * Access to the various translations structures need to be serialised
     16  * via locks for consistency.  In user-mode emulation access to the
     17  * memory related structures are protected with mmap_lock.
     18  * In !user-mode we use per-page locks.
     19  */
     20 #ifdef CONFIG_SOFTMMU
     21 #define assert_memory_lock()
     22 #else
     23 #define assert_memory_lock() tcg_debug_assert(have_mmap_lock())
     24 #endif
     25 
     26 typedef struct PageDesc {
     27     /* list of TBs intersecting this ram page */
     28     uintptr_t first_tb;
     29 #ifdef CONFIG_USER_ONLY
     30     unsigned long flags;
     31     void *target_data;
     32 #endif
     33 #ifdef CONFIG_SOFTMMU
     34     QemuSpin lock;
     35 #endif
     36 } PageDesc;
     37 
     38 /* Size of the L2 (and L3, etc) page tables.  */
     39 #define V_L2_BITS 10
     40 #define V_L2_SIZE (1 << V_L2_BITS)
     41 
     42 /*
     43  * L1 Mapping properties
     44  */
     45 extern int v_l1_size;
     46 extern int v_l1_shift;
     47 extern int v_l2_levels;
     48 
     49 /*
     50  * The bottom level has pointers to PageDesc, and is indexed by
     51  * anything from 4 to (V_L2_BITS + 3) bits, depending on target page size.
     52  */
     53 #define V_L1_MIN_BITS 4
     54 #define V_L1_MAX_BITS (V_L2_BITS + 3)
     55 #define V_L1_MAX_SIZE (1 << V_L1_MAX_BITS)
     56 
     57 extern void *l1_map[V_L1_MAX_SIZE];
     58 
     59 PageDesc *page_find_alloc(tb_page_addr_t index, bool alloc);
     60 
     61 static inline PageDesc *page_find(tb_page_addr_t index)
     62 {
     63     return page_find_alloc(index, false);
     64 }
     65 
     66 /* list iterators for lists of tagged pointers in TranslationBlock */
     67 #define TB_FOR_EACH_TAGGED(head, tb, n, field)                          \
     68     for (n = (head) & 1, tb = (TranslationBlock *)((head) & ~1);        \
     69          tb; tb = (TranslationBlock *)tb->field[n], n = (uintptr_t)tb & 1, \
     70              tb = (TranslationBlock *)((uintptr_t)tb & ~1))
     71 
     72 #define PAGE_FOR_EACH_TB(pagedesc, tb, n)                       \
     73     TB_FOR_EACH_TAGGED((pagedesc)->first_tb, tb, n, page_next)
     74 
     75 #define TB_FOR_EACH_JMP(head_tb, tb, n)                                 \
     76     TB_FOR_EACH_TAGGED((head_tb)->jmp_list_head, tb, n, jmp_list_next)
     77 
     78 /* In user-mode page locks aren't used; mmap_lock is enough */
     79 #ifdef CONFIG_USER_ONLY
     80 #define assert_page_locked(pd) tcg_debug_assert(have_mmap_lock())
     81 static inline void page_lock(PageDesc *pd) { }
     82 static inline void page_unlock(PageDesc *pd) { }
     83 #else
     84 #ifdef CONFIG_DEBUG_TCG
     85 void do_assert_page_locked(const PageDesc *pd, const char *file, int line);
     86 #define assert_page_locked(pd) do_assert_page_locked(pd, __FILE__, __LINE__)
     87 #else
     88 #define assert_page_locked(pd)
     89 #endif
     90 void page_lock(PageDesc *pd);
     91 void page_unlock(PageDesc *pd);
     92 #endif
     93 #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_DEBUG_TCG)
     94 void assert_no_pages_locked(void);
     95 #else
     96 static inline void assert_no_pages_locked(void) { }
     97 #endif
     98 
     99 TranslationBlock *tb_gen_code(CPUState *cpu, target_ulong pc,
    100                               target_ulong cs_base, uint32_t flags,
    101                               int cflags);
    102 G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
    103 void page_init(void);
    104 void tb_htable_init(void);
    105 void tb_reset_jump(TranslationBlock *tb, int n);
    106 TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
    107                                tb_page_addr_t phys_page2);
    108 bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
    109 void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
    110                                uintptr_t host_pc);
    111 
    112 /* Return the current PC from CPU, which may be cached in TB. */
    113 static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb)
    114 {
    115 #if TARGET_TB_PCREL
    116     return cpu->cc->get_pc(cpu);
    117 #else
    118     return tb_pc(tb);
    119 #endif
    120 }
    121 
    122 #endif /* ACCEL_TCG_INTERNAL_H */