mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Support for jemalloc * qemu_mutex_lock_iothread "No such process" fix * cutils: qemu_strto* wrappers * iohandler.c simplification * Many other fixes and misc patches. And some MTTCG work (with Emilio's fixes squashed): * Signal-free TCG kick * Removing spinlock in favor of QemuMutex * User-mode emulation multi-threading fixes/docs # gpg: Signature made Thu 10 Sep 2015 09:03:07 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream: (44 commits) cutils: work around platform differences in strto{l,ul,ll,ull} cpu-exec: fix lock hierarchy for user-mode emulation exec: make mmap_lock/mmap_unlock globally available tcg: comment on which functions have to be called with mmap_lock held tcg: add memory barriers in page_find_alloc accesses remove unused spinlock. replace spinlock by QemuMutex. cpus: remove tcg_halt_cond and tcg_cpu_thread globals cpus: protect work list with work_mutex scripts/dump-guest-memory.py: fix after RAMBlock change configure: Add support for jemalloc add macro file for coccinelle configure: factor out adding disas configure vhost-scsi: fix wrong vhost-scsi firmware path checkpatch: remove tests that are not relevant outside the kernel checkpatch: adapt some tests to QEMU CODING_STYLE: update mixed declaration rules qmp: Add example usage of strto*l() qemu wrapper cutils: Add qemu_strtoull() wrapper cutils: Add qemu_strtoll() wrapper ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+9
-4
@@ -87,10 +87,15 @@ Furthermore, it is the QEMU coding style.
|
||||
|
||||
5. Declarations
|
||||
|
||||
Mixed declarations (interleaving statements and declarations within blocks)
|
||||
are not allowed; declarations should be at the beginning of blocks. In other
|
||||
words, the code should not generate warnings if using GCC's
|
||||
-Wdeclaration-after-statement option.
|
||||
Mixed declarations (interleaving statements and declarations within
|
||||
blocks) are generally not allowed; declarations should be at the beginning
|
||||
of blocks.
|
||||
|
||||
Every now and then, an exception is made for declarations inside a
|
||||
#ifdef or #ifndef block: if the code looks nicer, such declarations can
|
||||
be placed at the top of the block even if there are statements above.
|
||||
On the other hand, however, it's often best to move that #ifdef/#ifndef
|
||||
block to a separate function altogether.
|
||||
|
||||
6. Conditional statements
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ include config-target.mak
|
||||
include config-devices.mak
|
||||
include $(SRC_PATH)/rules.mak
|
||||
|
||||
$(call set-vpath, $(SRC_PATH))
|
||||
$(call set-vpath, $(SRC_PATH):$(BUILD_DIR))
|
||||
ifdef CONFIG_LINUX
|
||||
QEMU_CFLAGS += -I../linux-headers
|
||||
endif
|
||||
|
||||
@@ -1214,6 +1214,10 @@ static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp)
|
||||
|
||||
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
||||
error_setg(errp, "iSCSI: failed to send readcapacity10 command.");
|
||||
} else if (!iscsilun->block_size ||
|
||||
iscsilun->block_size % BDRV_SECTOR_SIZE) {
|
||||
error_setg(errp, "iSCSI: the target returned an invalid "
|
||||
"block size of %d.", iscsilun->block_size);
|
||||
}
|
||||
if (task) {
|
||||
scsi_free_scsi_task(task);
|
||||
|
||||
@@ -211,8 +211,6 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
|
||||
abi_ulong new_addr);
|
||||
int target_msync(abi_ulong start, abi_ulong len, int flags);
|
||||
extern unsigned long last_brk;
|
||||
void mmap_lock(void);
|
||||
void mmap_unlock(void);
|
||||
void cpu_list_lock(void);
|
||||
void cpu_list_unlock(void);
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
|
||||
@@ -337,6 +337,7 @@ libssh2=""
|
||||
vhdx=""
|
||||
numa=""
|
||||
tcmalloc="no"
|
||||
jemalloc="no"
|
||||
|
||||
# parse CC options first
|
||||
for opt do
|
||||
@@ -1143,6 +1144,10 @@ for opt do
|
||||
;;
|
||||
--enable-tcmalloc) tcmalloc="yes"
|
||||
;;
|
||||
--disable-jemalloc) jemalloc="no"
|
||||
;;
|
||||
--enable-jemalloc) jemalloc="yes"
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown option $opt"
|
||||
echo "Try '$0 --help' for more information"
|
||||
@@ -1367,6 +1372,7 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
vhdx support for the Microsoft VHDX image format
|
||||
numa libnuma support
|
||||
tcmalloc tcmalloc support
|
||||
jemalloc jemalloc support
|
||||
|
||||
NOTE: The object files are built at the place where configure is launched
|
||||
EOF
|
||||
@@ -3395,6 +3401,11 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$tcmalloc" = "yes" && test "$jemalloc" = "yes" ; then
|
||||
echo "ERROR: tcmalloc && jemalloc can't be used at the same time"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# tcmalloc probe
|
||||
|
||||
@@ -3411,6 +3422,22 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# jemalloc probe
|
||||
|
||||
if test "$jemalloc" = "yes" ; then
|
||||
cat > $TMPC << EOF
|
||||
#include <stdlib.h>
|
||||
int main(void) { malloc(1); return 0; }
|
||||
EOF
|
||||
|
||||
if compile_prog "" "-ljemalloc" ; then
|
||||
LIBS="-ljemalloc $LIBS"
|
||||
else
|
||||
feature_not_found "jemalloc" "install jemalloc devel"
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# signalfd probe
|
||||
signalfd="no"
|
||||
@@ -4629,6 +4656,7 @@ echo "snappy support $snappy"
|
||||
echo "bzip2 support $bzip2"
|
||||
echo "NUMA host support $numa"
|
||||
echo "tcmalloc support $tcmalloc"
|
||||
echo "jemalloc support $jemalloc"
|
||||
|
||||
if test "$sdl_too_old" = "yes"; then
|
||||
echo "-> Your SDL version is too old - please upgrade to have SDL support"
|
||||
@@ -5519,91 +5547,76 @@ fi
|
||||
cflags=""
|
||||
ldflags=""
|
||||
|
||||
disas_config() {
|
||||
echo "CONFIG_${1}_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_${1}_DIS=y" >> config-all-disas.mak
|
||||
}
|
||||
|
||||
for i in $ARCH $TARGET_BASE_ARCH ; do
|
||||
case "$i" in
|
||||
alpha)
|
||||
echo "CONFIG_ALPHA_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_ALPHA_DIS=y" >> config-all-disas.mak
|
||||
disas_config "ALPHA"
|
||||
;;
|
||||
aarch64)
|
||||
if test -n "${cxx}"; then
|
||||
echo "CONFIG_ARM_A64_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_ARM_A64_DIS=y" >> config-all-disas.mak
|
||||
disas_config "ARM_A64"
|
||||
fi
|
||||
;;
|
||||
arm)
|
||||
echo "CONFIG_ARM_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak
|
||||
disas_config "ARM"
|
||||
if test -n "${cxx}"; then
|
||||
echo "CONFIG_ARM_A64_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_ARM_A64_DIS=y" >> config-all-disas.mak
|
||||
disas_config "ARM_A64"
|
||||
fi
|
||||
;;
|
||||
cris)
|
||||
echo "CONFIG_CRIS_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_CRIS_DIS=y" >> config-all-disas.mak
|
||||
disas_config "CRIS"
|
||||
;;
|
||||
hppa)
|
||||
echo "CONFIG_HPPA_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_HPPA_DIS=y" >> config-all-disas.mak
|
||||
disas_config "HPPA"
|
||||
;;
|
||||
i386|x86_64|x32)
|
||||
echo "CONFIG_I386_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_I386_DIS=y" >> config-all-disas.mak
|
||||
disas_config "I386"
|
||||
;;
|
||||
ia64*)
|
||||
echo "CONFIG_IA64_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_IA64_DIS=y" >> config-all-disas.mak
|
||||
disas_config "IA64"
|
||||
;;
|
||||
lm32)
|
||||
echo "CONFIG_LM32_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_LM32_DIS=y" >> config-all-disas.mak
|
||||
disas_config "LM32"
|
||||
;;
|
||||
m68k)
|
||||
echo "CONFIG_M68K_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_M68K_DIS=y" >> config-all-disas.mak
|
||||
disas_config "M68K"
|
||||
;;
|
||||
microblaze*)
|
||||
echo "CONFIG_MICROBLAZE_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_MICROBLAZE_DIS=y" >> config-all-disas.mak
|
||||
disas_config "MICROBLAZE"
|
||||
;;
|
||||
mips*)
|
||||
echo "CONFIG_MIPS_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_MIPS_DIS=y" >> config-all-disas.mak
|
||||
disas_config "MIPS"
|
||||
;;
|
||||
moxie*)
|
||||
echo "CONFIG_MOXIE_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_MOXIE_DIS=y" >> config-all-disas.mak
|
||||
disas_config "MOXIE"
|
||||
;;
|
||||
or32)
|
||||
echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_OPENRISC_DIS=y" >> config-all-disas.mak
|
||||
disas_config "OPENRISC"
|
||||
;;
|
||||
ppc*)
|
||||
echo "CONFIG_PPC_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_PPC_DIS=y" >> config-all-disas.mak
|
||||
disas_config "PPC"
|
||||
;;
|
||||
s390*)
|
||||
echo "CONFIG_S390_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_S390_DIS=y" >> config-all-disas.mak
|
||||
disas_config "S390"
|
||||
;;
|
||||
sh4)
|
||||
echo "CONFIG_SH4_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_SH4_DIS=y" >> config-all-disas.mak
|
||||
disas_config "SH4"
|
||||
;;
|
||||
sparc*)
|
||||
echo "CONFIG_SPARC_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_SPARC_DIS=y" >> config-all-disas.mak
|
||||
disas_config "SPARC"
|
||||
;;
|
||||
xtensa*)
|
||||
echo "CONFIG_XTENSA_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_XTENSA_DIS=y" >> config-all-disas.mak
|
||||
disas_config "XTENSA"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if test "$tcg_interpreter" = "yes" ; then
|
||||
echo "CONFIG_TCI_DIS=y" >> $config_target_mak
|
||||
echo "CONFIG_TCI_DIS=y" >> config-all-disas.mak
|
||||
disas_config "TCI"
|
||||
fi
|
||||
|
||||
case "$ARCH" in
|
||||
|
||||
+70
-49
@@ -258,10 +258,10 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
|
||||
tb_free(tb);
|
||||
}
|
||||
|
||||
static TranslationBlock *tb_find_slow(CPUState *cpu,
|
||||
target_ulong pc,
|
||||
target_ulong cs_base,
|
||||
uint64_t flags)
|
||||
static TranslationBlock *tb_find_physical(CPUState *cpu,
|
||||
target_ulong pc,
|
||||
target_ulong cs_base,
|
||||
uint64_t flags)
|
||||
{
|
||||
CPUArchState *env = (CPUArchState *)cpu->env_ptr;
|
||||
TranslationBlock *tb, **ptb1;
|
||||
@@ -278,8 +278,9 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
|
||||
ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
|
||||
for(;;) {
|
||||
tb = *ptb1;
|
||||
if (!tb)
|
||||
goto not_found;
|
||||
if (!tb) {
|
||||
return NULL;
|
||||
}
|
||||
if (tb->pc == pc &&
|
||||
tb->page_addr[0] == phys_page1 &&
|
||||
tb->cs_base == cs_base &&
|
||||
@@ -291,25 +292,59 @@ static TranslationBlock *tb_find_slow(CPUState *cpu,
|
||||
virt_page2 = (pc & TARGET_PAGE_MASK) +
|
||||
TARGET_PAGE_SIZE;
|
||||
phys_page2 = get_page_addr_code(env, virt_page2);
|
||||
if (tb->page_addr[1] == phys_page2)
|
||||
goto found;
|
||||
if (tb->page_addr[1] == phys_page2) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
goto found;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptb1 = &tb->phys_hash_next;
|
||||
}
|
||||
not_found:
|
||||
/* if no translated code available, then translate it now */
|
||||
|
||||
/* Move the TB to the head of the list */
|
||||
*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;
|
||||
return tb;
|
||||
}
|
||||
|
||||
static TranslationBlock *tb_find_slow(CPUState *cpu,
|
||||
target_ulong pc,
|
||||
target_ulong cs_base,
|
||||
uint64_t flags)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
|
||||
tb = tb_find_physical(cpu, pc, cs_base, flags);
|
||||
if (tb) {
|
||||
goto found;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* mmap_lock is needed by tb_gen_code, and mmap_lock must be
|
||||
* taken outside tb_lock. Since we're momentarily dropping
|
||||
* tb_lock, there's a chance that our desired tb has been
|
||||
* translated.
|
||||
*/
|
||||
tb_unlock();
|
||||
mmap_lock();
|
||||
tb_lock();
|
||||
tb = tb_find_physical(cpu, pc, cs_base, flags);
|
||||
if (tb) {
|
||||
mmap_unlock();
|
||||
goto found;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if no translated code available, then translate it now */
|
||||
tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
|
||||
|
||||
found:
|
||||
/* 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;
|
||||
}
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
mmap_unlock();
|
||||
#endif
|
||||
|
||||
found:
|
||||
/* we add the TB in the virtual pc hash table */
|
||||
cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
|
||||
return tb;
|
||||
@@ -350,7 +385,8 @@ static void cpu_handle_debug_exception(CPUState *cpu)
|
||||
|
||||
/* main execution loop */
|
||||
|
||||
volatile sig_atomic_t exit_request;
|
||||
bool exit_request;
|
||||
CPUState *tcg_current_cpu;
|
||||
|
||||
int cpu_exec(CPUState *cpu)
|
||||
{
|
||||
@@ -365,9 +401,6 @@ int cpu_exec(CPUState *cpu)
|
||||
uintptr_t next_tb;
|
||||
SyncClocks sc;
|
||||
|
||||
/* This must be volatile so it is not trashed by longjmp() */
|
||||
volatile bool have_tb_lock = false;
|
||||
|
||||
if (cpu->halted) {
|
||||
if (!cpu_has_work(cpu)) {
|
||||
return EXCP_HALTED;
|
||||
@@ -377,18 +410,10 @@ int cpu_exec(CPUState *cpu)
|
||||
}
|
||||
|
||||
current_cpu = cpu;
|
||||
|
||||
/* As long as current_cpu is null, up to the assignment just above,
|
||||
* requests by other threads to exit the execution loop are expected to
|
||||
* be issued using the exit_request global. We must make sure that our
|
||||
* evaluation of the global value is performed past the current_cpu
|
||||
* value transition point, which requires a memory barrier as well as
|
||||
* an instruction scheduling constraint on modern architectures. */
|
||||
smp_mb();
|
||||
|
||||
atomic_mb_set(&tcg_current_cpu, cpu);
|
||||
rcu_read_lock();
|
||||
|
||||
if (unlikely(exit_request)) {
|
||||
if (unlikely(atomic_mb_read(&exit_request))) {
|
||||
cpu->exit_request = 1;
|
||||
}
|
||||
|
||||
@@ -484,8 +509,7 @@ int cpu_exec(CPUState *cpu)
|
||||
cpu->exception_index = EXCP_INTERRUPT;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
spin_lock(&tcg_ctx.tb_ctx.tb_lock);
|
||||
have_tb_lock = true;
|
||||
tb_lock();
|
||||
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 */
|
||||
@@ -507,20 +531,14 @@ int cpu_exec(CPUState *cpu)
|
||||
tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
|
||||
next_tb & TB_EXIT_MASK, tb);
|
||||
}
|
||||
have_tb_lock = false;
|
||||
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
|
||||
infinite loop and becomes env->current_tb. Avoid
|
||||
starting execution if there is a pending interrupt. */
|
||||
cpu->current_tb = tb;
|
||||
barrier();
|
||||
tb_unlock();
|
||||
if (likely(!cpu->exit_request)) {
|
||||
trace_exec_tb(tb, tb->pc);
|
||||
tc_ptr = tb->tc_ptr;
|
||||
/* execute the generated code */
|
||||
cpu->current_tb = tb;
|
||||
next_tb = cpu_tb_exec(cpu, tc_ptr);
|
||||
cpu->current_tb = NULL;
|
||||
switch (next_tb & TB_EXIT_MASK) {
|
||||
case TB_EXIT_REQUESTED:
|
||||
/* Something asked us to stop executing
|
||||
@@ -528,8 +546,12 @@ int cpu_exec(CPUState *cpu)
|
||||
* loop. Whatever requested the exit will also
|
||||
* have set something else (eg exit_request or
|
||||
* interrupt_request) which we will handle
|
||||
* next time around the loop.
|
||||
* next time around the loop. But we need to
|
||||
* ensure the tcg_exit_req read in generated code
|
||||
* comes before the next read of cpu->exit_request
|
||||
* or cpu->interrupt_request.
|
||||
*/
|
||||
smp_rmb();
|
||||
next_tb = 0;
|
||||
break;
|
||||
case TB_EXIT_ICOUNT_EXPIRED:
|
||||
@@ -559,7 +581,6 @@ int cpu_exec(CPUState *cpu)
|
||||
break;
|
||||
}
|
||||
}
|
||||
cpu->current_tb = NULL;
|
||||
/* Try to align the host and virtual clocks
|
||||
if the guest is in advance */
|
||||
align_clocks(&sc, cpu);
|
||||
@@ -576,10 +597,7 @@ int cpu_exec(CPUState *cpu)
|
||||
x86_cpu = X86_CPU(cpu);
|
||||
env = &x86_cpu->env;
|
||||
#endif
|
||||
if (have_tb_lock) {
|
||||
spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
|
||||
have_tb_lock = false;
|
||||
}
|
||||
tb_lock_reset();
|
||||
}
|
||||
} /* for(;;) */
|
||||
|
||||
@@ -588,5 +606,8 @@ int cpu_exec(CPUState *cpu)
|
||||
|
||||
/* fail safe : never use current_cpu outside cpu_exec() */
|
||||
current_cpu = NULL;
|
||||
|
||||
/* Does not need atomic_mb_set because a spurious wakeup is okay. */
|
||||
atomic_set(&tcg_current_cpu, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -661,14 +661,6 @@ static void cpu_handle_guest_debug(CPUState *cpu)
|
||||
cpu->stopped = true;
|
||||
}
|
||||
|
||||
static void cpu_signal(int sig)
|
||||
{
|
||||
if (current_cpu) {
|
||||
cpu_exit(current_cpu);
|
||||
}
|
||||
exit_request = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LINUX
|
||||
static void sigbus_reraise(void)
|
||||
{
|
||||
@@ -781,29 +773,11 @@ static void qemu_kvm_init_cpu_signals(CPUState *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
static void qemu_tcg_init_cpu_signals(void)
|
||||
{
|
||||
sigset_t set;
|
||||
struct sigaction sigact;
|
||||
|
||||
memset(&sigact, 0, sizeof(sigact));
|
||||
sigact.sa_handler = cpu_signal;
|
||||
sigaction(SIG_IPI, &sigact, NULL);
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIG_IPI);
|
||||
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
|
||||
}
|
||||
|
||||
#else /* _WIN32 */
|
||||
static void qemu_kvm_init_cpu_signals(CPUState *cpu)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
static void qemu_tcg_init_cpu_signals(void)
|
||||
{
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
static QemuMutex qemu_global_mutex;
|
||||
@@ -812,9 +786,6 @@ static unsigned iothread_requesting_mutex;
|
||||
|
||||
static QemuThread io_thread;
|
||||
|
||||
static QemuThread *tcg_cpu_thread;
|
||||
static QemuCond *tcg_halt_cond;
|
||||
|
||||
/* cpu creation */
|
||||
static QemuCond qemu_cpu_cond;
|
||||
/* system init */
|
||||
@@ -845,6 +816,8 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
|
||||
wi.func = func;
|
||||
wi.data = data;
|
||||
wi.free = false;
|
||||
|
||||
qemu_mutex_lock(&cpu->work_mutex);
|
||||
if (cpu->queued_work_first == NULL) {
|
||||
cpu->queued_work_first = &wi;
|
||||
} else {
|
||||
@@ -853,9 +826,10 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
|
||||
cpu->queued_work_last = &wi;
|
||||
wi.next = NULL;
|
||||
wi.done = false;
|
||||
qemu_mutex_unlock(&cpu->work_mutex);
|
||||
|
||||
qemu_cpu_kick(cpu);
|
||||
while (!wi.done) {
|
||||
while (!atomic_mb_read(&wi.done)) {
|
||||
CPUState *self_cpu = current_cpu;
|
||||
|
||||
qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
|
||||
@@ -876,6 +850,8 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
|
||||
wi->func = func;
|
||||
wi->data = data;
|
||||
wi->free = true;
|
||||
|
||||
qemu_mutex_lock(&cpu->work_mutex);
|
||||
if (cpu->queued_work_first == NULL) {
|
||||
cpu->queued_work_first = wi;
|
||||
} else {
|
||||
@@ -884,6 +860,7 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
|
||||
cpu->queued_work_last = wi;
|
||||
wi->next = NULL;
|
||||
wi->done = false;
|
||||
qemu_mutex_unlock(&cpu->work_mutex);
|
||||
|
||||
qemu_cpu_kick(cpu);
|
||||
}
|
||||
@@ -896,15 +873,23 @@ static void flush_queued_work(CPUState *cpu)
|
||||
return;
|
||||
}
|
||||
|
||||
while ((wi = cpu->queued_work_first)) {
|
||||
qemu_mutex_lock(&cpu->work_mutex);
|
||||
while (cpu->queued_work_first != NULL) {
|
||||
wi = cpu->queued_work_first;
|
||||
cpu->queued_work_first = wi->next;
|
||||
if (!cpu->queued_work_first) {
|
||||
cpu->queued_work_last = NULL;
|
||||
}
|
||||
qemu_mutex_unlock(&cpu->work_mutex);
|
||||
wi->func(wi->data);
|
||||
wi->done = true;
|
||||
qemu_mutex_lock(&cpu->work_mutex);
|
||||
if (wi->free) {
|
||||
g_free(wi);
|
||||
} else {
|
||||
atomic_mb_set(&wi->done, true);
|
||||
}
|
||||
}
|
||||
cpu->queued_work_last = NULL;
|
||||
qemu_mutex_unlock(&cpu->work_mutex);
|
||||
qemu_cond_broadcast(&qemu_work_cond);
|
||||
}
|
||||
|
||||
@@ -919,15 +904,13 @@ static void qemu_wait_io_event_common(CPUState *cpu)
|
||||
cpu->thread_kicked = false;
|
||||
}
|
||||
|
||||
static void qemu_tcg_wait_io_event(void)
|
||||
static void qemu_tcg_wait_io_event(CPUState *cpu)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
while (all_cpu_threads_idle()) {
|
||||
/* Start accounting real time to the virtual clock if the CPUs
|
||||
are idle. */
|
||||
qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
|
||||
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
|
||||
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
|
||||
}
|
||||
|
||||
while (iothread_requesting_mutex) {
|
||||
@@ -1041,7 +1024,6 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
||||
rcu_register_thread();
|
||||
|
||||
qemu_mutex_lock_iothread();
|
||||
qemu_tcg_init_cpu_signals();
|
||||
qemu_thread_get_self(cpu->thread);
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
@@ -1053,7 +1035,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
||||
|
||||
/* wait for initial kick-off after machine start */
|
||||
while (first_cpu->stopped) {
|
||||
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
|
||||
qemu_cond_wait(first_cpu->halt_cond, &qemu_global_mutex);
|
||||
|
||||
/* process any pending work */
|
||||
CPU_FOREACH(cpu) {
|
||||
@@ -1062,7 +1044,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
||||
}
|
||||
|
||||
/* process any pending work */
|
||||
exit_request = 1;
|
||||
atomic_mb_set(&exit_request, 1);
|
||||
|
||||
while (1) {
|
||||
tcg_exec_all();
|
||||
@@ -1074,7 +1056,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
|
||||
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
||||
}
|
||||
}
|
||||
qemu_tcg_wait_io_event();
|
||||
qemu_tcg_wait_io_event(QTAILQ_FIRST(&cpus));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1085,61 +1067,47 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
|
||||
#ifndef _WIN32
|
||||
int err;
|
||||
|
||||
if (cpu->thread_kicked) {
|
||||
return;
|
||||
}
|
||||
cpu->thread_kicked = true;
|
||||
err = pthread_kill(cpu->thread->thread, SIG_IPI);
|
||||
if (err) {
|
||||
fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
|
||||
exit(1);
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
if (!qemu_cpu_is_self(cpu)) {
|
||||
CONTEXT tcgContext;
|
||||
|
||||
if (SuspendThread(cpu->hThread) == (DWORD)-1) {
|
||||
fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
|
||||
GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* On multi-core systems, we are not sure that the thread is actually
|
||||
* suspended until we can get the context.
|
||||
*/
|
||||
tcgContext.ContextFlags = CONTEXT_CONTROL;
|
||||
while (GetThreadContext(cpu->hThread, &tcgContext) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cpu_signal(0);
|
||||
|
||||
if (ResumeThread(cpu->hThread) == (DWORD)-1) {
|
||||
fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
|
||||
GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void qemu_cpu_kick_no_halt(void)
|
||||
{
|
||||
CPUState *cpu;
|
||||
/* Ensure whatever caused the exit has reached the CPU threads before
|
||||
* writing exit_request.
|
||||
*/
|
||||
atomic_mb_set(&exit_request, 1);
|
||||
cpu = atomic_mb_read(&tcg_current_cpu);
|
||||
if (cpu) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_cpu_kick(CPUState *cpu)
|
||||
{
|
||||
qemu_cond_broadcast(cpu->halt_cond);
|
||||
if (!tcg_enabled() && !cpu->thread_kicked) {
|
||||
if (tcg_enabled()) {
|
||||
qemu_cpu_kick_no_halt();
|
||||
} else {
|
||||
qemu_cpu_kick_thread(cpu);
|
||||
cpu->thread_kicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_cpu_kick_self(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
assert(current_cpu);
|
||||
|
||||
if (!current_cpu->thread_kicked) {
|
||||
qemu_cpu_kick_thread(current_cpu);
|
||||
current_cpu->thread_kicked = true;
|
||||
}
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
qemu_cpu_kick_thread(current_cpu);
|
||||
}
|
||||
|
||||
bool qemu_cpu_is_self(CPUState *cpu)
|
||||
@@ -1166,12 +1134,12 @@ void qemu_mutex_lock_iothread(void)
|
||||
* TCG code execution.
|
||||
*/
|
||||
if (!tcg_enabled() || qemu_in_vcpu_thread() ||
|
||||
!first_cpu || !first_cpu->thread) {
|
||||
!first_cpu || !first_cpu->created) {
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
atomic_dec(&iothread_requesting_mutex);
|
||||
} else {
|
||||
if (qemu_mutex_trylock(&qemu_global_mutex)) {
|
||||
qemu_cpu_kick_thread(first_cpu);
|
||||
qemu_cpu_kick_no_halt();
|
||||
qemu_mutex_lock(&qemu_global_mutex);
|
||||
}
|
||||
atomic_dec(&iothread_requesting_mutex);
|
||||
@@ -1251,6 +1219,8 @@ void resume_all_vcpus(void)
|
||||
static void qemu_tcg_init_vcpu(CPUState *cpu)
|
||||
{
|
||||
char thread_name[VCPU_THREAD_NAME_SIZE];
|
||||
static QemuCond *tcg_halt_cond;
|
||||
static QemuThread *tcg_cpu_thread;
|
||||
|
||||
tcg_cpu_address_space_init(cpu, cpu->as);
|
||||
|
||||
@@ -1440,7 +1410,9 @@ static void tcg_exec_all(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit_request = 0;
|
||||
|
||||
/* Pairs with smp_wmb in qemu_cpu_kick. */
|
||||
atomic_mb_set(&exit_request, 0);
|
||||
}
|
||||
|
||||
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
|
||||
|
||||
@@ -90,7 +90,7 @@ static MemoryRegion io_mem_unassigned;
|
||||
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
|
||||
/* current CPU in the current thread. It is only valid inside
|
||||
cpu_exec() */
|
||||
DEFINE_TLS(CPUState *, current_cpu);
|
||||
__thread CPUState *current_cpu;
|
||||
/* 0 = Do not count executed instructions.
|
||||
1 = Precise instruction counting.
|
||||
2 = Adaptive rate instruction counting. */
|
||||
|
||||
@@ -1359,7 +1359,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
|
||||
is still in the running state, which can cause packets to be dropped
|
||||
and state transition 'T' packets to be sent while the syscall is still
|
||||
being processed. */
|
||||
cpu_exit(s->c_cpu);
|
||||
qemu_cpu_kick(s->c_cpu);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1417,7 +1417,7 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
|
||||
* recall us...
|
||||
*/
|
||||
DMA_hold_DREQ(fdctrl->dma_chann);
|
||||
DMA_schedule(fdctrl->dma_chann);
|
||||
DMA_schedule();
|
||||
} else {
|
||||
/* Start transfer */
|
||||
fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
|
||||
|
||||
+1
-4
@@ -38,7 +38,6 @@ do { fprintf(stderr, "i82374 ERROR: " fmt , ## __VA_ARGS__); } while (0)
|
||||
|
||||
typedef struct I82374State {
|
||||
uint8_t commands[8];
|
||||
qemu_irq out;
|
||||
PortioList port_list;
|
||||
} I82374State;
|
||||
|
||||
@@ -101,7 +100,7 @@ static uint32_t i82374_read_descriptor(void *opaque, uint32_t nport)
|
||||
|
||||
static void i82374_realize(I82374State *s, Error **errp)
|
||||
{
|
||||
DMA_init(1, &s->out);
|
||||
DMA_init(1);
|
||||
memset(s->commands, 0, sizeof(s->commands));
|
||||
}
|
||||
|
||||
@@ -145,8 +144,6 @@ static void i82374_isa_realize(DeviceState *dev, Error **errp)
|
||||
isa->iobase);
|
||||
|
||||
i82374_realize(s, errp);
|
||||
|
||||
qdev_init_gpio_out(dev, &s->out, 1);
|
||||
}
|
||||
|
||||
static Property i82374_properties[] = {
|
||||
|
||||
+16
-15
@@ -59,7 +59,6 @@ static struct dma_cont {
|
||||
uint8_t flip_flop;
|
||||
int dshift;
|
||||
struct dma_regs regs[4];
|
||||
qemu_irq *cpu_request_exit;
|
||||
MemoryRegion channel_io;
|
||||
MemoryRegion cont_io;
|
||||
} dma_controllers[2];
|
||||
@@ -358,6 +357,7 @@ static void channel_run (int ncont, int ichan)
|
||||
}
|
||||
|
||||
static QEMUBH *dma_bh;
|
||||
static bool dma_bh_scheduled;
|
||||
|
||||
static void DMA_run (void)
|
||||
{
|
||||
@@ -390,12 +390,15 @@ static void DMA_run (void)
|
||||
|
||||
running = 0;
|
||||
out:
|
||||
if (rearm)
|
||||
if (rearm) {
|
||||
qemu_bh_schedule_idle(dma_bh);
|
||||
dma_bh_scheduled = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void DMA_run_bh(void *unused)
|
||||
{
|
||||
dma_bh_scheduled = false;
|
||||
DMA_run();
|
||||
}
|
||||
|
||||
@@ -458,12 +461,14 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len)
|
||||
return len;
|
||||
}
|
||||
|
||||
/* request the emulator to transfer a new DMA memory block ASAP */
|
||||
void DMA_schedule(int nchan)
|
||||
/* request the emulator to transfer a new DMA memory block ASAP (even
|
||||
* if the idle bottom half would not have exited the iothread yet).
|
||||
*/
|
||||
void DMA_schedule(void)
|
||||
{
|
||||
struct dma_cont *d = &dma_controllers[nchan > 3];
|
||||
|
||||
qemu_irq_pulse(*d->cpu_request_exit);
|
||||
if (dma_bh_scheduled) {
|
||||
qemu_notify_event();
|
||||
}
|
||||
}
|
||||
|
||||
static void dma_reset(void *opaque)
|
||||
@@ -515,13 +520,11 @@ static const MemoryRegionOps cont_io_ops = {
|
||||
|
||||
/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
|
||||
static void dma_init2(struct dma_cont *d, int base, int dshift,
|
||||
int page_base, int pageh_base,
|
||||
qemu_irq *cpu_request_exit)
|
||||
int page_base, int pageh_base)
|
||||
{
|
||||
int i;
|
||||
|
||||
d->dshift = dshift;
|
||||
d->cpu_request_exit = cpu_request_exit;
|
||||
|
||||
memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d,
|
||||
"dma-chan", 8 << d->dshift);
|
||||
@@ -585,12 +588,10 @@ static const VMStateDescription vmstate_dma = {
|
||||
}
|
||||
};
|
||||
|
||||
void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit)
|
||||
void DMA_init(int high_page_enable)
|
||||
{
|
||||
dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
|
||||
high_page_enable ? 0x480 : -1, cpu_request_exit);
|
||||
dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
|
||||
high_page_enable ? 0x488 : -1, cpu_request_exit);
|
||||
dma_init2(&dma_controllers[0], 0x00, 0, 0x80, high_page_enable ? 0x480 : -1);
|
||||
dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, high_page_enable ? 0x488 : -1);
|
||||
vmstate_register (NULL, 0, &vmstate_dma, &dma_controllers[0]);
|
||||
vmstate_register (NULL, 1, &vmstate_dma, &dma_controllers[1]);
|
||||
|
||||
|
||||
+1
-12
@@ -1452,15 +1452,6 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void cpu_request_exit(void *opaque, int irq, int level)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
|
||||
if (cpu && level) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps ioport80_io_ops = {
|
||||
.write = ioport80_write,
|
||||
.read = ioport80_read,
|
||||
@@ -1495,7 +1486,6 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
|
||||
qemu_irq rtc_irq = NULL;
|
||||
qemu_irq *a20_line;
|
||||
ISADevice *i8042, *port92, *vmmouse, *pit = NULL;
|
||||
qemu_irq *cpu_exit_irq;
|
||||
MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);
|
||||
|
||||
@@ -1572,8 +1562,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
|
||||
port92 = isa_create_simple(isa_bus, "port92");
|
||||
port92_init(port92, &a20_line[1]);
|
||||
|
||||
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
|
||||
DMA_init(0, cpu_exit_irq);
|
||||
DMA_init(0);
|
||||
|
||||
for(i = 0; i < MAX_FD; i++) {
|
||||
fd[i] = drive_get(IF_FLOPPY, 0, i);
|
||||
|
||||
+1
-2
@@ -100,7 +100,6 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
|
||||
|
||||
/* 2 82C37 (dma) */
|
||||
isa = isa_create_simple(isabus, "i82374");
|
||||
qdev_connect_gpio_out(DEVICE(isa), 0, s->out[1]);
|
||||
|
||||
/* timer */
|
||||
isa_create_simple(isabus, "mc146818rtc");
|
||||
@@ -111,7 +110,7 @@ static void i82378_init(Object *obj)
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
I82378State *s = I82378(obj);
|
||||
|
||||
qdev_init_gpio_out(dev, s->out, 2);
|
||||
qdev_init_gpio_out(dev, s->out, 1);
|
||||
qdev_init_gpio_in(dev, i82378_request_pic_irq, 16);
|
||||
}
|
||||
|
||||
|
||||
+1
-12
@@ -251,15 +251,6 @@ static void network_init (PCIBus *pci_bus)
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_request_exit(void *opaque, int irq, int level)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
|
||||
if (cpu && level) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static void mips_fulong2e_init(MachineState *machine)
|
||||
{
|
||||
ram_addr_t ram_size = machine->ram_size;
|
||||
@@ -274,7 +265,6 @@ static void mips_fulong2e_init(MachineState *machine)
|
||||
long bios_size;
|
||||
int64_t kernel_entry;
|
||||
qemu_irq *i8259;
|
||||
qemu_irq *cpu_exit_irq;
|
||||
PCIBus *pci_bus;
|
||||
ISABus *isa_bus;
|
||||
I2CBus *smbus;
|
||||
@@ -375,8 +365,7 @@ static void mips_fulong2e_init(MachineState *machine)
|
||||
|
||||
/* init other devices */
|
||||
pit = pit_init(isa_bus, 0x40, 0, NULL);
|
||||
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
|
||||
DMA_init(0, cpu_exit_irq);
|
||||
DMA_init(0);
|
||||
|
||||
/* Super I/O */
|
||||
isa_create_simple(isa_bus, "i8042");
|
||||
|
||||
+1
-12
@@ -104,15 +104,6 @@ static const MemoryRegionOps dma_dummy_ops = {
|
||||
#define MAGNUM_BIOS_SIZE_MAX 0x7e000
|
||||
#define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
|
||||
|
||||
static void cpu_request_exit(void *opaque, int irq, int level)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
|
||||
if (cpu && level) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static CPUUnassignedAccess real_do_unassigned_access;
|
||||
static void mips_jazz_do_unassigned_access(CPUState *cpu, hwaddr addr,
|
||||
bool is_write, bool is_exec,
|
||||
@@ -150,7 +141,6 @@ static void mips_jazz_init(MachineState *machine,
|
||||
ISADevice *pit;
|
||||
DriveInfo *fds[MAX_FD];
|
||||
qemu_irq esp_reset, dma_enable;
|
||||
qemu_irq *cpu_exit_irq;
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *bios = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *bios2 = g_new(MemoryRegion, 1);
|
||||
@@ -234,8 +224,7 @@ static void mips_jazz_init(MachineState *machine,
|
||||
/* ISA devices */
|
||||
i8259 = i8259_init(isa_bus, env->irq[4]);
|
||||
isa_bus_irqs(isa_bus, i8259);
|
||||
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
|
||||
DMA_init(0, cpu_exit_irq);
|
||||
DMA_init(0);
|
||||
pit = pit_init(isa_bus, 0x40, 0, NULL);
|
||||
pcspk_init(isa_bus, pit);
|
||||
|
||||
|
||||
+1
-12
@@ -905,15 +905,6 @@ static void main_cpu_reset(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
static void cpu_request_exit(void *opaque, int irq, int level)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
|
||||
if (cpu && level) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void mips_malta_init(MachineState *machine)
|
||||
{
|
||||
@@ -939,7 +930,6 @@ void mips_malta_init(MachineState *machine)
|
||||
MIPSCPU *cpu;
|
||||
CPUMIPSState *env;
|
||||
qemu_irq *isa_irq;
|
||||
qemu_irq *cpu_exit_irq;
|
||||
int piix4_devfn;
|
||||
I2CBus *smbus;
|
||||
int i;
|
||||
@@ -1175,8 +1165,7 @@ void mips_malta_init(MachineState *machine)
|
||||
smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
|
||||
g_free(smbus_eeprom_buf);
|
||||
pit = pit_init(isa_bus, 0x40, 0, NULL);
|
||||
cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
|
||||
DMA_init(0, cpu_exit_irq);
|
||||
DMA_init(0);
|
||||
|
||||
/* Super I/O */
|
||||
isa_create_simple(isa_bus, "i8042");
|
||||
|
||||
+1
-2
@@ -41,8 +41,7 @@ static void handle_event(int event)
|
||||
}
|
||||
|
||||
if (event & PVPANIC_PANICKED) {
|
||||
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
|
||||
vm_stop(RUN_STATE_GUEST_PANICKED);
|
||||
qemu_system_guest_panicked();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,15 +336,6 @@ static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
|
||||
|
||||
#define NVRAM_SIZE 0x2000
|
||||
|
||||
static void cpu_request_exit(void *opaque, int irq, int level)
|
||||
{
|
||||
CPUState *cpu = current_cpu;
|
||||
|
||||
if (cpu && level) {
|
||||
cpu_exit(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static void ppc_prep_reset(void *opaque)
|
||||
{
|
||||
PowerPCCPU *cpu = opaque;
|
||||
@@ -626,8 +617,6 @@ static void ppc_prep_init(MachineState *machine)
|
||||
cpu = POWERPC_CPU(first_cpu);
|
||||
qdev_connect_gpio_out(&pci->qdev, 0,
|
||||
cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
|
||||
qdev_connect_gpio_out(&pci->qdev, 1,
|
||||
qemu_allocate_irq(cpu_request_exit, NULL, 0));
|
||||
sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9));
|
||||
sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));
|
||||
sysbus_connect_irq(&pcihost->busdev, 2, qdev_get_gpio_in(&pci->qdev, 9));
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
cs->halted = 1;
|
||||
cpu_exit(cs);
|
||||
qemu_cpu_kick(cs);
|
||||
/*
|
||||
* While stopping a CPU, the guest calls H_CPPR which
|
||||
* effectively disables interrupts on XICS level.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user