2021-01-21 07:15:06 +01:00
|
|
|
/*
|
2023-09-14 20:57:14 +02:00
|
|
|
* Internal execution defines for qemu (target specific)
|
2021-01-21 07:15:06 +01:00
|
|
|
*
|
|
|
|
* Copyright (c) 2003 Fabrice Bellard
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
*/
|
|
|
|
|
2023-09-14 20:57:14 +02:00
|
|
|
#ifndef ACCEL_TCG_INTERNAL_TARGET_H
|
|
|
|
#define ACCEL_TCG_INTERNAL_TARGET_H
|
2021-01-21 07:15:06 +01:00
|
|
|
|
|
|
|
#include "exec/exec-all.h"
|
2023-07-06 18:55:48 +02:00
|
|
|
#include "exec/translate-all.h"
|
2021-01-21 07:15:06 +01:00
|
|
|
|
2022-09-19 12:28:15 +02:00
|
|
|
/*
|
|
|
|
* Access to the various translations structures need to be serialised
|
|
|
|
* via locks for consistency. In user-mode emulation access to the
|
|
|
|
* memory related structures are protected with mmap_lock.
|
|
|
|
* In !user-mode we use per-page locks.
|
|
|
|
*/
|
2023-06-13 15:33:44 +02:00
|
|
|
#ifdef CONFIG_USER_ONLY
|
2022-09-19 12:28:15 +02:00
|
|
|
#define assert_memory_lock() tcg_debug_assert(have_mmap_lock())
|
2023-06-13 15:33:44 +02:00
|
|
|
#else
|
|
|
|
#define assert_memory_lock()
|
2022-09-19 12:28:15 +02:00
|
|
|
#endif
|
|
|
|
|
2022-10-06 03:06:29 +02:00
|
|
|
#if defined(CONFIG_SOFTMMU) && defined(CONFIG_DEBUG_TCG)
|
|
|
|
void assert_no_pages_locked(void);
|
2022-10-06 02:22:42 +02:00
|
|
|
#else
|
2022-10-06 03:06:29 +02:00
|
|
|
static inline void assert_no_pages_locked(void) { }
|
2022-10-06 02:22:42 +02:00
|
|
|
#endif
|
|
|
|
|
2022-09-20 07:17:44 +02:00
|
|
|
#ifdef CONFIG_USER_ONLY
|
2022-10-06 03:06:29 +02:00
|
|
|
static inline void page_table_config_init(void) { }
|
2022-09-20 07:17:44 +02:00
|
|
|
#else
|
2022-10-06 03:06:29 +02:00
|
|
|
void page_table_config_init(void);
|
2022-09-20 07:17:44 +02:00
|
|
|
#endif
|
2022-10-01 22:36:33 +02:00
|
|
|
|
2023-07-06 18:55:48 +02:00
|
|
|
#ifdef CONFIG_USER_ONLY
|
|
|
|
/*
|
|
|
|
* For user-only, page_protect sets the page read-only.
|
|
|
|
* Since most execution is already on read-only pages, and we'd need to
|
|
|
|
* account for other TBs on the same page, defer undoing any page protection
|
|
|
|
* until we receive the write fault.
|
|
|
|
*/
|
|
|
|
static inline void tb_lock_page0(tb_page_addr_t p0)
|
|
|
|
{
|
|
|
|
page_protect(p0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void tb_lock_page1(tb_page_addr_t p0, tb_page_addr_t p1)
|
|
|
|
{
|
|
|
|
page_protect(p1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void tb_unlock_page1(tb_page_addr_t p0, tb_page_addr_t p1) { }
|
|
|
|
static inline void tb_unlock_pages(TranslationBlock *tb) { }
|
|
|
|
#else
|
|
|
|
void tb_lock_page0(tb_page_addr_t);
|
|
|
|
void tb_lock_page1(tb_page_addr_t, tb_page_addr_t);
|
|
|
|
void tb_unlock_page1(tb_page_addr_t, tb_page_addr_t);
|
|
|
|
void tb_unlock_pages(TranslationBlock *);
|
|
|
|
#endif
|
|
|
|
|
2022-10-06 03:06:29 +02:00
|
|
|
#ifdef CONFIG_SOFTMMU
|
2022-12-09 10:36:48 +01:00
|
|
|
void tb_invalidate_phys_range_fast(ram_addr_t ram_addr,
|
|
|
|
unsigned size,
|
|
|
|
uintptr_t retaddr);
|
2022-12-09 10:36:45 +01:00
|
|
|
G_NORETURN void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
|
2022-10-06 03:06:29 +02:00
|
|
|
#endif /* CONFIG_SOFTMMU */
|
2022-09-20 07:17:44 +02:00
|
|
|
|
2023-06-21 15:56:23 +02:00
|
|
|
TranslationBlock *tb_gen_code(CPUState *cpu, vaddr pc,
|
|
|
|
uint64_t cs_base, uint32_t flags,
|
2021-01-21 07:15:06 +01:00
|
|
|
int cflags);
|
2021-03-10 00:42:16 +01:00
|
|
|
void page_init(void);
|
|
|
|
void tb_htable_init(void);
|
2022-09-20 07:17:44 +02:00
|
|
|
void tb_reset_jump(TranslationBlock *tb, int n);
|
2023-07-06 18:55:48 +02:00
|
|
|
TranslationBlock *tb_link_page(TranslationBlock *tb);
|
2022-10-05 18:18:39 +02:00
|
|
|
bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc);
|
2022-10-24 14:15:04 +02:00
|
|
|
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
2022-10-24 15:12:56 +02:00
|
|
|
uintptr_t host_pc);
|
2021-01-17 17:48:12 +01:00
|
|
|
|
2023-10-03 14:30:25 +02:00
|
|
|
bool tcg_exec_realizefn(CPUState *cpu, Error **errp);
|
|
|
|
void tcg_exec_unrealizefn(CPUState *cpu);
|
|
|
|
|
2022-08-15 22:16:06 +02:00
|
|
|
/* Return the current PC from CPU, which may be cached in TB. */
|
2023-06-21 15:56:23 +02:00
|
|
|
static inline vaddr log_pc(CPUState *cpu, const TranslationBlock *tb)
|
2022-08-15 22:16:06 +02:00
|
|
|
{
|
2023-02-27 14:51:39 +01:00
|
|
|
if (tb_cflags(tb) & CF_PCREL) {
|
|
|
|
return cpu->cc->get_pc(cpu);
|
|
|
|
} else {
|
2023-02-27 14:51:47 +01:00
|
|
|
return tb->pc;
|
2023-02-27 14:51:39 +01:00
|
|
|
}
|
2022-08-15 22:16:06 +02:00
|
|
|
}
|
|
|
|
|
2023-04-17 18:40:34 +02:00
|
|
|
extern bool one_insn_per_tb;
|
|
|
|
|
2022-03-03 16:57:10 +01:00
|
|
|
/**
|
|
|
|
* tcg_req_mo:
|
|
|
|
* @type: TCGBar
|
|
|
|
*
|
|
|
|
* Filter @type to the barrier that is required for the guest
|
|
|
|
* memory ordering vs the host memory ordering. A non-zero
|
|
|
|
* result indicates that some barrier is required.
|
|
|
|
*
|
|
|
|
* If TCG_GUEST_DEFAULT_MO is not defined, assume that the
|
|
|
|
* guest requires strict ordering.
|
|
|
|
*
|
|
|
|
* This is a macro so that it's constant even without optimization.
|
|
|
|
*/
|
|
|
|
#ifdef TCG_GUEST_DEFAULT_MO
|
|
|
|
# define tcg_req_mo(type) \
|
|
|
|
((type) & TCG_GUEST_DEFAULT_MO & ~TCG_TARGET_DEFAULT_MO)
|
|
|
|
#else
|
|
|
|
# define tcg_req_mo(type) ((type) & ~TCG_TARGET_DEFAULT_MO)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_req_mo:
|
|
|
|
* @type: TCGBar
|
|
|
|
*
|
|
|
|
* If tcg_req_mo indicates a barrier for @type is required
|
|
|
|
* for the guest memory model, issue a host memory barrier.
|
|
|
|
*/
|
|
|
|
#define cpu_req_mo(type) \
|
|
|
|
do { \
|
|
|
|
if (tcg_req_mo(type)) { \
|
|
|
|
smp_mb(); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2021-01-21 07:15:06 +01:00
|
|
|
#endif /* ACCEL_TCG_INTERNAL_H */
|