mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-03 16:25:39 +00:00
remove uc->cpus
This commit is contained in:
parent
60a7371ec2
commit
cb615fdba7
|
@ -1,13 +0,0 @@
|
||||||
/* By Dang Hoang Vu <dang.hvu -at- gmail.com>, 2015 */
|
|
||||||
|
|
||||||
#ifndef UC_QEMU_MACRO_H
|
|
||||||
#define UC_QEMU_MACRO_H
|
|
||||||
|
|
||||||
#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
|
|
||||||
#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &uc->cpus, node)
|
|
||||||
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
|
|
||||||
QTAILQ_FOREACH_SAFE(cpu, &cpu->uc->cpus, node, next_cpu)
|
|
||||||
#define first_cpu QTAILQ_FIRST(&uc->cpus)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -33,8 +33,6 @@
|
||||||
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
|
#define WRITE_BYTE_L(x, b) (x = (x & ~0xff) | (b & 0xff))
|
||||||
|
|
||||||
|
|
||||||
QTAILQ_HEAD(CPUTailQ, CPUState);
|
|
||||||
|
|
||||||
typedef struct ModuleEntry {
|
typedef struct ModuleEntry {
|
||||||
void (*init)(void);
|
void (*init)(void);
|
||||||
QTAILQ_ENTRY(ModuleEntry) node;
|
QTAILQ_ENTRY(ModuleEntry) node;
|
||||||
|
@ -148,7 +146,6 @@ struct uc_struct {
|
||||||
QemuMutex qemu_global_mutex; // qemu/cpus.c
|
QemuMutex qemu_global_mutex; // qemu/cpus.c
|
||||||
QemuCond qemu_cpu_cond; // qemu/cpus.c
|
QemuCond qemu_cpu_cond; // qemu/cpus.c
|
||||||
QemuCond *tcg_halt_cond; // qemu/cpus.c
|
QemuCond *tcg_halt_cond; // qemu/cpus.c
|
||||||
struct CPUTailQ cpus; // qemu/cpu-exec.c
|
|
||||||
uc_err errnum; // qemu/cpu-exec.c
|
uc_err errnum; // qemu/cpu-exec.c
|
||||||
AddressSpace as;
|
AddressSpace as;
|
||||||
query_t query;
|
query_t query;
|
||||||
|
@ -171,8 +168,8 @@ struct uc_struct {
|
||||||
uc_mem_unmap_t memory_unmap;
|
uc_mem_unmap_t memory_unmap;
|
||||||
uc_readonly_mem_t readonly_mem;
|
uc_readonly_mem_t readonly_mem;
|
||||||
uc_mem_redirect_t mem_redirect;
|
uc_mem_redirect_t mem_redirect;
|
||||||
// list of cpu
|
// TODO: remove current_cpu, as it's a flag for something else ("cpu running"?)
|
||||||
void* cpu;
|
CPUState *cpu, *current_cpu;
|
||||||
|
|
||||||
MemoryRegion *system_memory; // qemu/exec.c
|
MemoryRegion *system_memory; // qemu/exec.c
|
||||||
MemoryRegion io_mem_rom; // qemu/exec.c
|
MemoryRegion io_mem_rom; // qemu/exec.c
|
||||||
|
@ -180,7 +177,6 @@ struct uc_struct {
|
||||||
MemoryRegion io_mem_unassigned; // qemu/exec.c
|
MemoryRegion io_mem_unassigned; // qemu/exec.c
|
||||||
MemoryRegion io_mem_watch; // qemu/exec.c
|
MemoryRegion io_mem_watch; // qemu/exec.c
|
||||||
RAMList ram_list; // qemu/exec.c
|
RAMList ram_list; // qemu/exec.c
|
||||||
CPUState *next_cpu; // qemu/cpus.c
|
|
||||||
BounceBuffer bounce; // qemu/cpu-exec.c
|
BounceBuffer bounce; // qemu/cpu-exec.c
|
||||||
volatile sig_atomic_t exit_request; // qemu/cpu-exec.c
|
volatile sig_atomic_t exit_request; // qemu/cpu-exec.c
|
||||||
spinlock_t x86_global_cpu_lock; // for X86 arch only
|
spinlock_t x86_global_cpu_lock; // for X86 arch only
|
||||||
|
@ -212,7 +208,6 @@ struct uc_struct {
|
||||||
int apic_no;
|
int apic_no;
|
||||||
bool mmio_registered;
|
bool mmio_registered;
|
||||||
bool apic_report_tpr_access;
|
bool apic_report_tpr_access;
|
||||||
CPUState *current_cpu;
|
|
||||||
|
|
||||||
// linked lists containing hooks per type
|
// linked lists containing hooks per type
|
||||||
struct list hook[UC_HOOK_MAX];
|
struct list hook[UC_HOOK_MAX];
|
||||||
|
@ -250,8 +245,6 @@ struct uc_struct {
|
||||||
uint64_t next_pc; // save next PC for some special cases
|
uint64_t next_pc; // save next PC for some special cases
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "qemu_macro.h"
|
|
||||||
|
|
||||||
// check if this address is mapped in (via uc_mem_map())
|
// check if this address is mapped in (via uc_mem_map())
|
||||||
MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address);
|
MemoryRegion *memory_mapping(struct uc_struct* uc, uint64_t address);
|
||||||
|
|
||||||
|
|
56
qemu/cpus.c
56
qemu/cpus.c
|
@ -61,29 +61,18 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
|
||||||
|
|
||||||
int resume_all_vcpus(struct uc_struct *uc)
|
int resume_all_vcpus(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
|
// Fix call multiple time (vu).
|
||||||
{
|
// We have to check whether this is the second time, then reset all CPU.
|
||||||
// Fix call multiple time (vu).
|
if (!cpu->created) {
|
||||||
// We have to check whether this is the second time, then reset all CPU.
|
cpu->created = true;
|
||||||
bool created = false;
|
cpu->halted = 0;
|
||||||
CPU_FOREACH(cpu) {
|
if (qemu_init_vcpu(cpu))
|
||||||
created |= cpu->created;
|
return -1;
|
||||||
}
|
|
||||||
if (!created) {
|
|
||||||
CPU_FOREACH(cpu) {
|
|
||||||
cpu->created = true;
|
|
||||||
cpu->halted = 0;
|
|
||||||
if (qemu_init_vcpu(cpu))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
|
//qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
|
||||||
CPU_FOREACH(cpu) {
|
cpu_resume(cpu);
|
||||||
cpu_resume(cpu);
|
|
||||||
}
|
|
||||||
qemu_tcg_cpu_loop(uc);
|
qemu_tcg_cpu_loop(uc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -104,14 +93,12 @@ int qemu_init_vcpu(CPUState *cpu)
|
||||||
|
|
||||||
static void *qemu_tcg_cpu_loop(struct uc_struct *uc)
|
static void *qemu_tcg_cpu_loop(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
|
|
||||||
//qemu_tcg_init_cpu_signals();
|
//qemu_tcg_init_cpu_signals();
|
||||||
|
|
||||||
qemu_mutex_lock(&uc->qemu_global_mutex);
|
qemu_mutex_lock(&uc->qemu_global_mutex);
|
||||||
CPU_FOREACH(cpu) {
|
cpu->created = true;
|
||||||
cpu->created = true;
|
|
||||||
}
|
|
||||||
qemu_cond_signal(&uc->qemu_cpu_cond);
|
qemu_cond_signal(&uc->qemu_cpu_cond);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -119,15 +106,12 @@ static void *qemu_tcg_cpu_loop(struct uc_struct *uc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPU_FOREACH(cpu) {
|
cpu->created = false;
|
||||||
cpu->created = false;
|
qemu_cond_destroy(cpu->halt_cond);
|
||||||
qemu_cond_destroy(cpu->halt_cond);
|
g_free(cpu->halt_cond);
|
||||||
g_free(cpu->halt_cond);
|
cpu->halt_cond = NULL;
|
||||||
cpu->halt_cond = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
qemu_mutex_unlock(&uc->qemu_global_mutex);
|
qemu_mutex_unlock(&uc->qemu_global_mutex);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,14 +142,8 @@ static bool tcg_exec_all(struct uc_struct* uc)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
bool finish = false;
|
bool finish = false;
|
||||||
CPUState *next_cpu = uc->next_cpu;
|
while (!uc->exit_request) {
|
||||||
|
CPUState *cpu = uc->cpu;
|
||||||
if (next_cpu == NULL) {
|
|
||||||
next_cpu = first_cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; next_cpu != NULL && !uc->exit_request; next_cpu = CPU_NEXT(next_cpu)) {
|
|
||||||
CPUState *cpu = next_cpu;
|
|
||||||
CPUArchState *env = cpu->env_ptr;
|
CPUArchState *env = cpu->env_ptr;
|
||||||
|
|
||||||
//qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
|
//qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
|
||||||
|
|
|
@ -152,25 +152,23 @@ void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
|
||||||
void cpu_tlb_reset_dirty_all(struct uc_struct *uc,
|
void cpu_tlb_reset_dirty_all(struct uc_struct *uc,
|
||||||
ram_addr_t start1, ram_addr_t length)
|
ram_addr_t start1, ram_addr_t length)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
|
|
||||||
CPU_FOREACH(cpu) {
|
int mmu_idx;
|
||||||
int mmu_idx;
|
|
||||||
|
|
||||||
env = cpu->env_ptr;
|
env = cpu->env_ptr;
|
||||||
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
|
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < CPU_TLB_SIZE; i++) {
|
for (i = 0; i < CPU_TLB_SIZE; i++) {
|
||||||
tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
|
tlb_reset_dirty_range(&env->tlb_table[mmu_idx][i],
|
||||||
start1, length);
|
start1, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < CPU_VTLB_SIZE; i++) {
|
for (i = 0; i < CPU_VTLB_SIZE; i++) {
|
||||||
tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
|
tlb_reset_dirty_range(&env->tlb_v_table[mmu_idx][i],
|
||||||
start1, length);
|
start1, length);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
39
qemu/exec.c
39
qemu/exec.c
|
@ -382,14 +382,10 @@ address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
|
||||||
|
|
||||||
CPUState *qemu_get_cpu(struct uc_struct *uc, int index)
|
CPUState *qemu_get_cpu(struct uc_struct *uc, int index)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
|
if (cpu->cpu_index == index) {
|
||||||
CPU_FOREACH(cpu) {
|
return cpu;
|
||||||
if (cpu->cpu_index == index) {
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,31 +409,19 @@ void cpu_exec_init(CPUArchState *env, void *opaque)
|
||||||
{
|
{
|
||||||
struct uc_struct *uc = opaque;
|
struct uc_struct *uc = opaque;
|
||||||
CPUState *cpu = ENV_GET_CPU(env);
|
CPUState *cpu = ENV_GET_CPU(env);
|
||||||
CPUState *some_cpu;
|
|
||||||
int cpu_index;
|
|
||||||
|
|
||||||
cpu->uc = uc;
|
cpu->uc = uc;
|
||||||
env->uc = uc;
|
env->uc = uc;
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
cpu->cpu_index = 0;
|
||||||
cpu_list_lock();
|
|
||||||
#endif
|
|
||||||
cpu_index = 0;
|
|
||||||
CPU_FOREACH(some_cpu) {
|
|
||||||
cpu_index++;
|
|
||||||
}
|
|
||||||
cpu->cpu_index = cpu_index;
|
|
||||||
cpu->numa_node = 0;
|
cpu->numa_node = 0;
|
||||||
QTAILQ_INIT(&cpu->breakpoints);
|
QTAILQ_INIT(&cpu->breakpoints);
|
||||||
QTAILQ_INIT(&cpu->watchpoints);
|
QTAILQ_INIT(&cpu->watchpoints);
|
||||||
|
|
||||||
cpu->as = &uc->as;
|
cpu->as = &uc->as;
|
||||||
|
|
||||||
QTAILQ_INSERT_TAIL(&uc->cpus, cpu, node);
|
// TODO: assert uc does not already have a cpu?
|
||||||
//QTAILQ_INSERT_TAIL(&uc->cpus, cpu, node);
|
uc->cpu = cpu;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
|
||||||
cpu_list_unlock();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_HAS_ICE)
|
#if defined(TARGET_HAS_ICE)
|
||||||
|
@ -1518,19 +1502,10 @@ static void tcg_commit(MemoryListener *listener)
|
||||||
{
|
{
|
||||||
struct uc_struct* uc = listener->address_space_filter->uc;
|
struct uc_struct* uc = listener->address_space_filter->uc;
|
||||||
|
|
||||||
CPUState *cpu;
|
|
||||||
|
|
||||||
/* since each CPU stores ram addresses in its TLB cache, we must
|
/* since each CPU stores ram addresses in its TLB cache, we must
|
||||||
reset the modified entries */
|
reset the modified entries */
|
||||||
/* XXX: slow ! */
|
/* XXX: slow ! */
|
||||||
CPU_FOREACH(cpu) {
|
tlb_flush(uc->cpu, 1);
|
||||||
/* FIXME: Disentangle the cpu.h circular files deps so we can
|
|
||||||
directly get the right CPU from listener. */
|
|
||||||
if (cpu->tcg_as_listener != listener) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tlb_flush(cpu, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void address_space_init_dispatch(AddressSpace *as)
|
void address_space_init_dispatch(AddressSpace *as)
|
||||||
|
|
|
@ -58,7 +58,7 @@ void cpu_smm_update(CPUX86State *env)
|
||||||
{
|
{
|
||||||
struct uc_struct *uc = x86_env_get_cpu(env)->parent_obj.uc;
|
struct uc_struct *uc = x86_env_get_cpu(env)->parent_obj.uc;
|
||||||
|
|
||||||
if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
|
if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == uc->cpu) {
|
||||||
smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
|
smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ void qemu_mutex_lock_iothread(struct uc_struct* uc)
|
||||||
qemu_mutex_lock(&uc->qemu_global_mutex);
|
qemu_mutex_lock(&uc->qemu_global_mutex);
|
||||||
} else {
|
} else {
|
||||||
if (qemu_mutex_trylock(&uc->qemu_global_mutex)) {
|
if (qemu_mutex_trylock(&uc->qemu_global_mutex)) {
|
||||||
qemu_cpu_kick_thread(first_cpu);
|
qemu_cpu_kick_thread(uc->cpu);
|
||||||
qemu_mutex_lock(&uc->qemu_global_mutex);
|
qemu_mutex_lock(&uc->qemu_global_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,38 +197,21 @@ typedef struct GuestPhysListener {
|
||||||
MemoryListener listener;
|
MemoryListener listener;
|
||||||
} GuestPhysListener;
|
} GuestPhysListener;
|
||||||
|
|
||||||
static CPUState *find_paging_enabled_cpu(struct uc_struct* uc)
|
|
||||||
{
|
|
||||||
CPUState *cpu;
|
|
||||||
|
|
||||||
CPU_FOREACH(cpu) {
|
|
||||||
if (cpu_paging_enabled(cpu)) {
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qemu_get_guest_memory_mapping(struct uc_struct *uc,
|
void qemu_get_guest_memory_mapping(struct uc_struct *uc,
|
||||||
MemoryMappingList *list,
|
MemoryMappingList *list,
|
||||||
const GuestPhysBlockList *guest_phys_blocks,
|
const GuestPhysBlockList *guest_phys_blocks,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
CPUState *cpu, *first_paging_enabled_cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
GuestPhysBlock *block;
|
GuestPhysBlock *block;
|
||||||
ram_addr_t offset, length;
|
ram_addr_t offset, length;
|
||||||
|
|
||||||
first_paging_enabled_cpu = find_paging_enabled_cpu(uc);
|
if (cpu_paging_enabled(cpu)) {
|
||||||
if (first_paging_enabled_cpu) {
|
Error *err = NULL;
|
||||||
for (cpu = first_paging_enabled_cpu; cpu != NULL;
|
cpu_get_memory_mapping(cpu, list, &err);
|
||||||
cpu = CPU_NEXT(cpu)) {
|
if (err) {
|
||||||
Error *err = NULL;
|
error_propagate(errp, err);
|
||||||
cpu_get_memory_mapping(cpu, list, &err);
|
return;
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,11 @@
|
||||||
|
|
||||||
bool cpu_exists(struct uc_struct* uc, int64_t id)
|
bool cpu_exists(struct uc_struct* uc, int64_t id)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(uc, cpu);
|
||||||
|
|
||||||
CPU_FOREACH(cpu) {
|
if (cc->get_arch_id(cpu) == id) {
|
||||||
CPUClass *cc = CPU_GET_CLASS(uc, cpu);
|
return true;
|
||||||
|
|
||||||
if (cc->get_arch_id(cpu) == id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,45 +284,33 @@ static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, 1);
|
||||||
tlb_flush(other_cs, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, value == 0);
|
||||||
tlb_flush(other_cs, value == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, value & TARGET_PAGE_MASK);
|
||||||
tlb_flush_page(other_cs, value & TARGET_PAGE_MASK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, value & TARGET_PAGE_MASK);
|
||||||
tlb_flush_page(other_cs, value & TARGET_PAGE_MASK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ARMCPRegInfo cp_reginfo[] = {
|
static const ARMCPRegInfo cp_reginfo[] = {
|
||||||
|
@ -1874,37 +1862,28 @@ static void tlbi_aa64_asid_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
static void tlbi_aa64_va_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbi_aa64_va_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, pageaddr);
|
||||||
tlb_flush_page(other_cs, pageaddr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlbi_aa64_vaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbi_aa64_vaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
uint64_t pageaddr = sextract64(value << 12, 0, 56);
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, pageaddr);
|
||||||
tlb_flush_page(other_cs, pageaddr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tlbi_aa64_asid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
static void tlbi_aa64_asid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
uint64_t value)
|
uint64_t value)
|
||||||
{
|
{
|
||||||
CPUState *other_cs;
|
|
||||||
int asid = extract64(value, 48, 16);
|
int asid = extract64(value, 48, 16);
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
|
// TODO: issue #642
|
||||||
CPU_FOREACH(other_cs) {
|
// tlb_flush(other_cpu, asid == 0);
|
||||||
tlb_flush(other_cs, asid == 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
|
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
|
|
|
@ -34,7 +34,7 @@ void arm64_release(void* ctx)
|
||||||
|
|
||||||
void arm64_reg_reset(struct uc_struct *uc)
|
void arm64_reg_reset(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUArchState *env = uc->cpu->env_ptr;
|
||||||
memset(env->xregs, 0, sizeof(env->xregs));
|
memset(env->xregs, 0, sizeof(env->xregs));
|
||||||
|
|
||||||
env->pc = 0;
|
env->pc = 0;
|
||||||
|
@ -42,7 +42,7 @@ void arm64_reg_reset(struct uc_struct *uc)
|
||||||
|
|
||||||
int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -74,7 +74,7 @@ int arm64_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co
|
||||||
|
|
||||||
int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
|
int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ void arm_reg_reset(struct uc_struct *uc)
|
||||||
(void)uc;
|
(void)uc;
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
|
|
||||||
env = first_cpu->env_ptr;
|
env = uc->cpu->env_ptr;
|
||||||
memset(env->regs, 0, sizeof(env->regs));
|
memset(env->regs, 0, sizeof(env->regs));
|
||||||
|
|
||||||
env->pc = 0;
|
env->pc = 0;
|
||||||
|
@ -49,7 +49,7 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
CPUState *mycpu;
|
CPUState *mycpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mycpu = first_cpu;
|
mycpu = uc->cpu;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
unsigned int regid = regs[i];
|
unsigned int regid = regs[i];
|
||||||
|
@ -84,7 +84,7 @@ int arm_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
|
|
||||||
int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
|
int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -135,7 +135,7 @@ static bool arm_stop_interrupt(int intno)
|
||||||
|
|
||||||
static uc_err arm_query(struct uc_struct *uc, uc_query_type type, size_t *result)
|
static uc_err arm_query(struct uc_struct *uc, uc_query_type type, size_t *result)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
uint32_t mode;
|
uint32_t mode;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
|
|
@ -578,11 +578,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
|
||||||
cpu = x86_env_get_cpu(env);
|
cpu = x86_env_get_cpu(env);
|
||||||
cs = CPU(cpu);
|
cs = CPU(cpu);
|
||||||
/* XXX: not complete but not completely erroneous */
|
/* XXX: not complete but not completely erroneous */
|
||||||
if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
|
do_hlt(cpu);
|
||||||
do_pause(cpu);
|
|
||||||
} else {
|
|
||||||
do_hlt(cpu);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_pause(CPUX86State *env, int next_eip_addend)
|
void helper_pause(CPUX86State *env, int next_eip_addend)
|
||||||
|
|
|
@ -46,7 +46,7 @@ void x86_release(void *ctx)
|
||||||
|
|
||||||
void x86_reg_reset(struct uc_struct *uc)
|
void x86_reg_reset(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUArchState *env = uc->cpu->env_ptr;
|
||||||
|
|
||||||
env->features[FEAT_1_EDX] = CPUID_CX8 | CPUID_CMOV | CPUID_SSE2 | CPUID_FXSR | CPUID_SSE | CPUID_CLFLUSH;
|
env->features[FEAT_1_EDX] = CPUID_CX8 | CPUID_CMOV | CPUID_SSE2 | CPUID_FXSR | CPUID_SSE | CPUID_CLFLUSH;
|
||||||
env->features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_AES;
|
env->features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_AES;
|
||||||
|
@ -139,7 +139,7 @@ void x86_reg_reset(struct uc_struct *uc)
|
||||||
|
|
||||||
int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -636,7 +636,7 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
|
|
||||||
int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ static void m68k_set_pc(struct uc_struct *uc, uint64_t address)
|
||||||
|
|
||||||
void m68k_reg_reset(struct uc_struct *uc)
|
void m68k_reg_reset(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUArchState *env = uc->cpu->env_ptr;
|
||||||
|
|
||||||
memset(env->aregs, 0, sizeof(env->aregs));
|
memset(env->aregs, 0, sizeof(env->aregs));
|
||||||
memset(env->dregs, 0, sizeof(env->dregs));
|
memset(env->dregs, 0, sizeof(env->dregs));
|
||||||
|
@ -27,7 +27,7 @@ void m68k_reg_reset(struct uc_struct *uc)
|
||||||
|
|
||||||
int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -52,7 +52,7 @@ int m68k_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int cou
|
||||||
|
|
||||||
int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -1798,37 +1798,43 @@ target_ulong helper_emt(void)
|
||||||
target_ulong helper_dvpe(CPUMIPSState *env)
|
target_ulong helper_dvpe(CPUMIPSState *env)
|
||||||
{
|
{
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
CPUState *other_cs = first_cpu;
|
CPUState *other_cs = uc->cpu;
|
||||||
target_ulong prev = env->mvp->CP0_MVPControl;
|
target_ulong prev = env->mvp->CP0_MVPControl;
|
||||||
|
|
||||||
|
// TODO: #642 SMP groups
|
||||||
|
/*
|
||||||
CPU_FOREACH(other_cs) {
|
CPU_FOREACH(other_cs) {
|
||||||
MIPSCPU *other_cpu = MIPS_CPU(uc, other_cs);
|
MIPSCPU *other_cpu = MIPS_CPU(uc, other_cs);
|
||||||
/* Turn off all VPEs except the one executing the dvpe. */
|
// Turn off all VPEs except the one executing the dvpe.
|
||||||
if (&other_cpu->env != env) {
|
if (&other_cpu->env != env) {
|
||||||
other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
|
other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
|
||||||
mips_vpe_sleep(other_cpu);
|
mips_vpe_sleep(other_cpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ulong helper_evpe(CPUMIPSState *env)
|
target_ulong helper_evpe(CPUMIPSState *env)
|
||||||
{
|
{
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
CPUState *other_cs = first_cpu;
|
CPUState *other_cs = uc->cpu;
|
||||||
target_ulong prev = env->mvp->CP0_MVPControl;
|
target_ulong prev = env->mvp->CP0_MVPControl;
|
||||||
|
|
||||||
|
// TODO: #642 SMP groups
|
||||||
|
/*
|
||||||
CPU_FOREACH(other_cs) {
|
CPU_FOREACH(other_cs) {
|
||||||
MIPSCPU *other_cpu = MIPS_CPU(uc, other_cs);
|
MIPSCPU *other_cpu = MIPS_CPU(uc, other_cs);
|
||||||
|
|
||||||
if (&other_cpu->env != env
|
if (&other_cpu->env != env
|
||||||
/* If the VPE is WFI, don't disturb its sleep. */
|
// If the VPE is WFI, don't disturb its sleep.
|
||||||
&& !mips_vpe_is_wfi(other_cpu)) {
|
&& !mips_vpe_is_wfi(other_cpu)) {
|
||||||
/* Enable the VPE. */
|
// Enable the VPE.
|
||||||
other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
|
other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
|
||||||
mips_vpe_wake(other_cpu); /* And wake it up. */
|
mips_vpe_wake(other_cpu); // And wake it up.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_USER_ONLY */
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
|
|
@ -61,7 +61,7 @@ void mips_release(void *ctx)
|
||||||
void mips_reg_reset(struct uc_struct *uc)
|
void mips_reg_reset(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
(void)uc;
|
(void)uc;
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUArchState *env = uc->cpu->env_ptr;
|
||||||
memset(env->active_tc.gpr, 0, sizeof(env->active_tc.gpr));
|
memset(env->active_tc.gpr, 0, sizeof(env->active_tc.gpr));
|
||||||
|
|
||||||
env->active_tc.PC = 0;
|
env->active_tc.PC = 0;
|
||||||
|
@ -69,7 +69,7 @@ void mips_reg_reset(struct uc_struct *uc)
|
||||||
|
|
||||||
int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -92,7 +92,7 @@ int mips_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int cou
|
||||||
|
|
||||||
int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ static void sparc_set_pc(struct uc_struct *uc, uint64_t address)
|
||||||
|
|
||||||
void sparc_reg_reset(struct uc_struct *uc)
|
void sparc_reg_reset(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUArchState *env = uc->cpu->env_ptr;
|
||||||
|
|
||||||
memset(env->gregs, 0, sizeof(env->gregs));
|
memset(env->gregs, 0, sizeof(env->gregs));
|
||||||
memset(env->fpr, 0, sizeof(env->fpr));
|
memset(env->fpr, 0, sizeof(env->fpr));
|
||||||
|
@ -41,7 +41,7 @@ void sparc_reg_reset(struct uc_struct *uc)
|
||||||
|
|
||||||
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -70,7 +70,7 @@ int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co
|
||||||
|
|
||||||
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ static void sparc_set_pc(struct uc_struct *uc, uint64_t address)
|
||||||
|
|
||||||
void sparc_reg_reset(struct uc_struct *uc)
|
void sparc_reg_reset(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUArchState *env = uc->cpu->env_ptr;
|
||||||
|
|
||||||
memset(env->gregs, 0, sizeof(env->gregs));
|
memset(env->gregs, 0, sizeof(env->gregs));
|
||||||
memset(env->fpr, 0, sizeof(env->fpr));
|
memset(env->fpr, 0, sizeof(env->fpr));
|
||||||
|
@ -41,7 +41,7 @@ void sparc_reg_reset(struct uc_struct *uc)
|
||||||
|
|
||||||
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
@ -70,7 +70,7 @@ int sparc_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int co
|
||||||
|
|
||||||
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
|
int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals, int count)
|
||||||
{
|
{
|
||||||
CPUState *mycpu = first_cpu;
|
CPUState *mycpu = uc->cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
|
@ -855,9 +855,7 @@ void tb_flush(CPUArchState *env1)
|
||||||
}
|
}
|
||||||
tcg_ctx->tb_ctx.nb_tbs = 0;
|
tcg_ctx->tb_ctx.nb_tbs = 0;
|
||||||
|
|
||||||
CPU_FOREACH(cpu) {
|
memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
|
||||||
memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(tcg_ctx->tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx->tb_ctx.tb_phys_hash));
|
memset(tcg_ctx->tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx->tb_ctx.tb_phys_hash));
|
||||||
page_flush_tb(uc);
|
page_flush_tb(uc);
|
||||||
|
@ -982,7 +980,7 @@ void tb_phys_invalidate(struct uc_struct *uc,
|
||||||
TranslationBlock *tb, tb_page_addr_t page_addr)
|
TranslationBlock *tb, tb_page_addr_t page_addr)
|
||||||
{
|
{
|
||||||
TCGContext *tcg_ctx = uc->tcg_ctx;
|
TCGContext *tcg_ctx = uc->tcg_ctx;
|
||||||
CPUState *cpu;
|
CPUState *cpu = uc->cpu;
|
||||||
PageDesc *p;
|
PageDesc *p;
|
||||||
unsigned int h, n1;
|
unsigned int h, n1;
|
||||||
tb_page_addr_t phys_pc;
|
tb_page_addr_t phys_pc;
|
||||||
|
@ -1009,10 +1007,8 @@ void tb_phys_invalidate(struct uc_struct *uc,
|
||||||
|
|
||||||
/* remove the TB from the hash list */
|
/* remove the TB from the hash list */
|
||||||
h = tb_jmp_cache_hash_func(tb->pc);
|
h = tb_jmp_cache_hash_func(tb->pc);
|
||||||
CPU_FOREACH(cpu) {
|
if (cpu->tb_jmp_cache[h] == tb) {
|
||||||
if (cpu->tb_jmp_cache[h] == tb) {
|
cpu->tb_jmp_cache[h] = NULL;
|
||||||
cpu->tb_jmp_cache[h] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* suppress this TB from the two jump lists */
|
/* suppress this TB from the two jump lists */
|
||||||
|
|
14
uc.c
14
uc.c
|
@ -156,9 +156,6 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
|
||||||
uc->arch = arch;
|
uc->arch = arch;
|
||||||
uc->mode = mode;
|
uc->mode = mode;
|
||||||
|
|
||||||
// uc->cpus = QTAILQ_HEAD_INITIALIZER(uc->cpus);
|
|
||||||
uc->cpus.tqh_first = NULL;
|
|
||||||
uc->cpus.tqh_last = &(uc->cpus.tqh_first);
|
|
||||||
// uc->ram_list = { .blocks = QTAILQ_HEAD_INITIALIZER(ram_list.blocks) };
|
// uc->ram_list = { .blocks = QTAILQ_HEAD_INITIALIZER(ram_list.blocks) };
|
||||||
uc->ram_list.blocks.tqh_first = NULL;
|
uc->ram_list.blocks.tqh_first = NULL;
|
||||||
uc->ram_list.blocks.tqh_last = &(uc->ram_list.blocks.tqh_first);
|
uc->ram_list.blocks.tqh_last = &(uc->ram_list.blocks.tqh_first);
|
||||||
|
@ -289,7 +286,6 @@ uc_err uc_close(uc_engine *uc)
|
||||||
int i;
|
int i;
|
||||||
struct list_item *cur;
|
struct list_item *cur;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
CPUState *cpu;
|
|
||||||
|
|
||||||
// Cleanup internally.
|
// Cleanup internally.
|
||||||
if (uc->release)
|
if (uc->release)
|
||||||
|
@ -297,11 +293,9 @@ uc_err uc_close(uc_engine *uc)
|
||||||
g_free(uc->tcg_ctx);
|
g_free(uc->tcg_ctx);
|
||||||
|
|
||||||
// Cleanup CPU.
|
// Cleanup CPU.
|
||||||
CPU_FOREACH(cpu) {
|
g_free(uc->cpu->tcg_as_listener);
|
||||||
g_free(cpu->tcg_as_listener);
|
g_free(uc->cpu->thread);
|
||||||
g_free(cpu->thread);
|
g_free(uc->cpu->halt_cond);
|
||||||
g_free(cpu->halt_cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup all objects.
|
// Cleanup all objects.
|
||||||
OBJECT(uc->machine_state->accelerator)->ref = 1;
|
OBJECT(uc->machine_state->accelerator)->ref = 1;
|
||||||
|
@ -311,7 +305,6 @@ uc_err uc_close(uc_engine *uc)
|
||||||
|
|
||||||
object_unref(uc, OBJECT(uc->machine_state->accelerator));
|
object_unref(uc, OBJECT(uc->machine_state->accelerator));
|
||||||
object_unref(uc, OBJECT(uc->machine_state));
|
object_unref(uc, OBJECT(uc->machine_state));
|
||||||
object_unref(uc, uc->cpu);
|
|
||||||
object_unref(uc, OBJECT(&uc->io_mem_notdirty));
|
object_unref(uc, OBJECT(&uc->io_mem_notdirty));
|
||||||
object_unref(uc, OBJECT(&uc->io_mem_unassigned));
|
object_unref(uc, OBJECT(&uc->io_mem_unassigned));
|
||||||
object_unref(uc, OBJECT(&uc->io_mem_rom));
|
object_unref(uc, OBJECT(&uc->io_mem_rom));
|
||||||
|
@ -634,6 +627,7 @@ uc_err uc_emu_stop(uc_engine *uc)
|
||||||
return UC_ERR_OK;
|
return UC_ERR_OK;
|
||||||
|
|
||||||
uc->stop_request = true;
|
uc->stop_request = true;
|
||||||
|
// TODO: make this atomic somehow?
|
||||||
if (uc->current_cpu) {
|
if (uc->current_cpu) {
|
||||||
// exit the current TB
|
// exit the current TB
|
||||||
cpu_exit(uc->current_cpu);
|
cpu_exit(uc->current_cpu);
|
||||||
|
|
Loading…
Reference in a new issue