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
* minor patches here and there * MTTCG: lock-free TB lookup * SCSI: bugfixes for MPTSAS, MegaSAS, LSI53c, vmw_pvscsi * buffer_is_zero rewrite (except for one patch) * chardev: qemu_chr_fe_write checks * checkpatch improvement for markdown preformatted text * default-configs cleanups * atomics cleanups # gpg: Signature made Tue 13 Sep 2016 18:14:30 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (58 commits) cutils: Add generic prefetch cutils: Add SSE4 version cutils: Add test for buffer_is_zero cutils: Remove ppc buffer zero checking cutils: Remove aarch64 buffer zero checking cutils: Rearrange buffer_is_zero acceleration cutils: Export only buffer_is_zero cutils: Remove SPLAT macro cutils: Move buffer_is_zero and subroutines to a new file ppc: do not redefine CPUPPCState x86/lapic: Load LAPIC state at post_load optionrom: do not rely on compiler's bswap optimization checkpatch: Fix whitespace checks for documentation code blocks atomics: Use __atomic_*_n() variant primitives atomics: Remove redundant barrier()'s kvm-all: drop kvm_setup_guest_memory i8257: Make device "i8257" unavailable with -device Revert "megasas: remove useless check for cmd->frame" char: convert qemu_chr_fe_write to qemu_chr_fe_write_all hw: replace most use of qemu_chr_fe_write with qemu_chr_fe_write_all ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Conflicts: cpus.c tests/Makefile.include
This commit is contained in:
+10
-1
@@ -715,6 +715,10 @@ F: hw/misc/pc-testdev.c
|
||||
F: hw/timer/hpet*
|
||||
F: hw/timer/i8254*
|
||||
F: hw/timer/mc146818rtc*
|
||||
F: include/hw/i2c/pm_smbus.h
|
||||
F: include/hw/timer/hpet.h
|
||||
F: include/hw/timer/i8254*
|
||||
F: include/hw/timer/mc146818rtc*
|
||||
|
||||
Machine core
|
||||
M: Eduardo Habkost <ehabkost@redhat.com>
|
||||
@@ -831,7 +835,7 @@ T: git git://github.com/jasowang/qemu.git net
|
||||
SCSI
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Supported
|
||||
F: include/hw/scsi*
|
||||
F: include/hw/scsi/*
|
||||
F: hw/scsi/*
|
||||
T: git git://github.com/bonzini/qemu.git scsi-next
|
||||
|
||||
@@ -1257,6 +1261,11 @@ F: net/slirp.c
|
||||
F: include/net/slirp.h
|
||||
T: git git://git.kiszka.org/qemu.git queues/slirp
|
||||
|
||||
Stubs
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Maintained
|
||||
F: stubs/
|
||||
|
||||
Tracing
|
||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
S: Maintained
|
||||
|
||||
+3
-1
@@ -41,7 +41,9 @@ static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
|
||||
header[0] = 0x02;
|
||||
header[1] = len;
|
||||
|
||||
qemu_chr_fe_write(s->chr, header, sizeof(header));
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, header, sizeof(header));
|
||||
|
||||
size -= len;
|
||||
}
|
||||
|
||||
+1
-1
@@ -3907,7 +3907,7 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!blk && !bs->monitor_list.tqe_prev) {
|
||||
if (!blk && !QTAILQ_IN_USE(bs, monitor_list)) {
|
||||
error_setg(errp, "Node %s is not owned by the monitor",
|
||||
bs->node_name);
|
||||
goto out;
|
||||
|
||||
@@ -1804,28 +1804,19 @@ fi
|
||||
##########################################
|
||||
# avx2 optimization requirement check
|
||||
|
||||
|
||||
if test "$static" = "no" ; then
|
||||
cat > $TMPC << EOF
|
||||
cat > $TMPC << EOF
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("avx2")
|
||||
#include <cpuid.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
static int bar(void *a) {
|
||||
return _mm256_movemask_epi8(_mm256_cmpeq_epi8(*(__m256i *)a, (__m256i){0}));
|
||||
__m256i x = *(__m256i *)a;
|
||||
return _mm256_testz_si256(x, x);
|
||||
}
|
||||
static void *bar_ifunc(void) {return (void*) bar;}
|
||||
int foo(void *a) __attribute__((ifunc("bar_ifunc")));
|
||||
int main(int argc, char *argv[]) { return foo(argv[0]);}
|
||||
int main(int argc, char *argv[]) { return bar(argv[0]); }
|
||||
EOF
|
||||
if compile_object "" ; then
|
||||
if has readelf; then
|
||||
if readelf --syms $TMPO 2>/dev/null |grep -q "IFUNC.*foo"; then
|
||||
avx2_opt="yes"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if compile_object "" ; then
|
||||
avx2_opt="yes"
|
||||
fi
|
||||
|
||||
#########################################
|
||||
|
||||
+51
-64
@@ -241,7 +241,8 @@ static bool tb_cmp(const void *p, const void *d)
|
||||
if (tb->pc == desc->pc &&
|
||||
tb->page_addr[0] == desc->phys_page1 &&
|
||||
tb->cs_base == desc->cs_base &&
|
||||
tb->flags == desc->flags) {
|
||||
tb->flags == desc->flags &&
|
||||
!atomic_read(&tb->invalid)) {
|
||||
/* check next page if needed */
|
||||
if (tb->page_addr[1] == -1) {
|
||||
return true;
|
||||
@@ -259,7 +260,7 @@ static bool tb_cmp(const void *p, const void *d)
|
||||
return false;
|
||||
}
|
||||
|
||||
static TranslationBlock *tb_find_physical(CPUState *cpu,
|
||||
static TranslationBlock *tb_htable_lookup(CPUState *cpu,
|
||||
target_ulong pc,
|
||||
target_ulong cs_base,
|
||||
uint32_t flags)
|
||||
@@ -278,72 +279,48 @@ static TranslationBlock *tb_find_physical(CPUState *cpu,
|
||||
return qht_lookup(&tcg_ctx.tb_ctx.htable, tb_cmp, &desc, h);
|
||||
}
|
||||
|
||||
static TranslationBlock *tb_find_slow(CPUState *cpu,
|
||||
target_ulong pc,
|
||||
target_ulong cs_base,
|
||||
uint32_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);
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
static inline TranslationBlock *tb_find_fast(CPUState *cpu,
|
||||
TranslationBlock **last_tb,
|
||||
int tb_exit)
|
||||
static inline TranslationBlock *tb_find(CPUState *cpu,
|
||||
TranslationBlock *last_tb,
|
||||
int tb_exit)
|
||||
{
|
||||
CPUArchState *env = (CPUArchState *)cpu->env_ptr;
|
||||
TranslationBlock *tb;
|
||||
target_ulong cs_base, pc;
|
||||
uint32_t flags;
|
||||
bool have_tb_lock = false;
|
||||
|
||||
/* we record a subset of the CPU state. It will
|
||||
always be the same before a given translated block
|
||||
is executed. */
|
||||
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
|
||||
tb_lock();
|
||||
tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
|
||||
tb = atomic_rcu_read(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]);
|
||||
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
|
||||
tb->flags != flags)) {
|
||||
tb = tb_find_slow(cpu, pc, cs_base, flags);
|
||||
}
|
||||
if (cpu->tb_flushed) {
|
||||
/* Ensure that no TB jump will be modified as the
|
||||
* translation buffer has been flushed.
|
||||
*/
|
||||
*last_tb = NULL;
|
||||
cpu->tb_flushed = false;
|
||||
tb = tb_htable_lookup(cpu, pc, cs_base, flags);
|
||||
if (!tb) {
|
||||
|
||||
/* mmap_lock is needed by tb_gen_code, and mmap_lock must be
|
||||
* taken outside tb_lock. As system emulation is currently
|
||||
* single threaded the locks are NOPs.
|
||||
*/
|
||||
mmap_lock();
|
||||
tb_lock();
|
||||
have_tb_lock = true;
|
||||
|
||||
/* There's a chance that our desired tb has been translated while
|
||||
* taking the locks so we check again inside the lock.
|
||||
*/
|
||||
tb = tb_htable_lookup(cpu, pc, cs_base, flags);
|
||||
if (!tb) {
|
||||
/* if no translated code available, then translate it now */
|
||||
tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
|
||||
}
|
||||
|
||||
mmap_unlock();
|
||||
}
|
||||
|
||||
/* We add the TB in the virtual pc hash table for the fast lookup */
|
||||
atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb);
|
||||
}
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* We don't take care of direct jumps when address mapping changes in
|
||||
@@ -351,14 +328,25 @@ static inline TranslationBlock *tb_find_fast(CPUState *cpu,
|
||||
* spanning two pages because the mapping for the second page can change.
|
||||
*/
|
||||
if (tb->page_addr[1] != -1) {
|
||||
*last_tb = NULL;
|
||||
last_tb = NULL;
|
||||
}
|
||||
#endif
|
||||
/* See if we can patch the calling TB. */
|
||||
if (*last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
|
||||
tb_add_jump(*last_tb, tb_exit, tb);
|
||||
if (last_tb && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
|
||||
if (!have_tb_lock) {
|
||||
tb_lock();
|
||||
have_tb_lock = true;
|
||||
}
|
||||
/* Check if translation buffer has been flushed */
|
||||
if (cpu->tb_flushed) {
|
||||
cpu->tb_flushed = false;
|
||||
} else if (!tb->invalid) {
|
||||
tb_add_jump(last_tb, tb_exit, tb);
|
||||
}
|
||||
}
|
||||
if (have_tb_lock) {
|
||||
tb_unlock();
|
||||
}
|
||||
tb_unlock();
|
||||
return tb;
|
||||
}
|
||||
|
||||
@@ -437,8 +425,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
|
||||
} else if (replay_has_exception()
|
||||
&& cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
|
||||
/* try to cause an exception pending in the log */
|
||||
TranslationBlock *last_tb = NULL; /* Avoid chaining TBs */
|
||||
cpu_exec_nocache(cpu, 1, tb_find_fast(cpu, &last_tb, 0), true);
|
||||
cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0), true);
|
||||
*ret = -1;
|
||||
return true;
|
||||
#endif
|
||||
@@ -618,10 +605,10 @@ int cpu_exec(CPUState *cpu)
|
||||
break;
|
||||
}
|
||||
|
||||
cpu->tb_flushed = false; /* reset before first TB lookup */
|
||||
atomic_mb_set(&cpu->tb_flushed, false); /* reset before first TB lookup */
|
||||
for(;;) {
|
||||
cpu_handle_interrupt(cpu, &last_tb);
|
||||
tb = tb_find_fast(cpu, &last_tb, tb_exit);
|
||||
tb = tb_find(cpu, last_tb, tb_exit);
|
||||
cpu_loop_exec_tb(cpu, tb, &last_tb, &tb_exit, &sc);
|
||||
/* Try to align the host and virtual clocks
|
||||
if the guest is in advance */
|
||||
|
||||
@@ -191,8 +191,12 @@ int64_t cpu_icount_to_ns(int64_t icount)
|
||||
return icount << icount_time_shift;
|
||||
}
|
||||
|
||||
/* return the host CPU cycle counter and handle stop/restart */
|
||||
/* Caller must hold the BQL */
|
||||
/* return the time elapsed in VM between vm_start and vm_stop. Unless
|
||||
* icount is active, cpu_get_ticks() uses units of the host CPU cycle
|
||||
* counter.
|
||||
*
|
||||
* Caller must hold the BQL
|
||||
*/
|
||||
int64_t cpu_get_ticks(void)
|
||||
{
|
||||
int64_t ticks;
|
||||
@@ -219,17 +223,19 @@ int64_t cpu_get_ticks(void)
|
||||
|
||||
static int64_t cpu_get_clock_locked(void)
|
||||
{
|
||||
int64_t ticks;
|
||||
int64_t time;
|
||||
|
||||
ticks = timers_state.cpu_clock_offset;
|
||||
time = timers_state.cpu_clock_offset;
|
||||
if (timers_state.cpu_ticks_enabled) {
|
||||
ticks += get_clock();
|
||||
time += get_clock();
|
||||
}
|
||||
|
||||
return ticks;
|
||||
return time;
|
||||
}
|
||||
|
||||
/* return the host CPU monotonic time */
|
||||
/* Return the monotonic time elapsed in VM, i.e.,
|
||||
* the time between vm_start and vm_stop
|
||||
*/
|
||||
int64_t cpu_get_clock(void)
|
||||
{
|
||||
int64_t ti;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
include pci.mak
|
||||
include usb.mak
|
||||
CONFIG_VGA=y
|
||||
CONFIG_ISA_MMIO=y
|
||||
CONFIG_NAND=y
|
||||
CONFIG_ECC=y
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
@@ -30,14 +30,12 @@ CONFIG_I8257=y
|
||||
CONFIG_IDE_ISA=y
|
||||
CONFIG_IDE_PIIX=y
|
||||
CONFIG_NE2000_ISA=y
|
||||
CONFIG_PIIX_PCI=y
|
||||
CONFIG_HPET=y
|
||||
CONFIG_APPLESMC=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_TPM_TIS=$(CONFIG_TPM)
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_PAM=y
|
||||
CONFIG_PCI_PIIX=y
|
||||
CONFIG_WDT_IB700=y
|
||||
CONFIG_XEN_I386=$(CONFIG_XEN)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
include pci.mak
|
||||
include sound.mak
|
||||
include usb.mak
|
||||
CONFIG_ISA_MMIO=y
|
||||
CONFIG_ESCC=y
|
||||
CONFIG_M48T59=y
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
@@ -4,7 +4,6 @@ include pci.mak
|
||||
include sound.mak
|
||||
include usb.mak
|
||||
CONFIG_VIRTIO_VGA=y
|
||||
CONFIG_ISA_MMIO=y
|
||||
CONFIG_ESCC=y
|
||||
CONFIG_M48T59=y
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
include pci.mak
|
||||
include usb.mak
|
||||
CONFIG_ISA_MMIO=y
|
||||
CONFIG_M48T59=y
|
||||
CONFIG_PTIMER=y
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
@@ -30,14 +30,12 @@ CONFIG_I8257=y
|
||||
CONFIG_IDE_ISA=y
|
||||
CONFIG_IDE_PIIX=y
|
||||
CONFIG_NE2000_ISA=y
|
||||
CONFIG_PIIX_PCI=y
|
||||
CONFIG_HPET=y
|
||||
CONFIG_APPLESMC=y
|
||||
CONFIG_I8259=y
|
||||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_TPM_TIS=$(CONFIG_TPM)
|
||||
CONFIG_MC146818RTC=y
|
||||
CONFIG_PAM=y
|
||||
CONFIG_PCI_PIIX=y
|
||||
CONFIG_WDT_IB700=y
|
||||
CONFIG_XEN_I386=$(CONFIG_XEN)
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ do not matter; as soon as all previous critical sections have finished,
|
||||
there cannot be any readers who hold references to the data structure,
|
||||
and these can now be safely reclaimed (e.g., freed or unref'ed).
|
||||
|
||||
Here is a picutre:
|
||||
Here is a picture:
|
||||
|
||||
thread 1 thread 2 thread 3
|
||||
------------------- ------------------------ -------------------
|
||||
|
||||
@@ -617,7 +617,7 @@ void cpu_exec_exit(CPUState *cpu)
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
cpu_list_lock();
|
||||
if (cpu->node.tqe_prev == NULL) {
|
||||
if (!QTAILQ_IN_USE(cpu, node)) {
|
||||
/* there is nothing to undo since cpu_exec_init() hasn't been called */
|
||||
cpu_list_unlock();
|
||||
return;
|
||||
@@ -626,7 +626,6 @@ void cpu_exec_exit(CPUState *cpu)
|
||||
assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus, CPUTailQ)));
|
||||
|
||||
QTAILQ_REMOVE(&cpus, cpu, node);
|
||||
cpu->node.tqe_prev = NULL;
|
||||
cpu->cpu_index = UNASSIGNED_CPU_INDEX;
|
||||
cpu_list_unlock();
|
||||
|
||||
@@ -1622,10 +1621,8 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)
|
||||
if (new_block->host) {
|
||||
qemu_ram_setup_dump(new_block->host, new_block->max_length);
|
||||
qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE);
|
||||
/* MADV_DONTFORK is also needed by KVM in absence of synchronous MMU */
|
||||
qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK);
|
||||
if (kvm_enabled()) {
|
||||
kvm_setup_guest_memory(new_block->host, new_block->max_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -402,7 +402,9 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len)
|
||||
}
|
||||
}
|
||||
#else
|
||||
qemu_chr_fe_write(s->chr, buf, len);
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, buf, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -769,14 +769,16 @@ static void omap_sti_fifo_write(void *opaque, hwaddr addr,
|
||||
|
||||
if (ch == STI_TRACE_CONTROL_CHANNEL) {
|
||||
/* Flush channel <i>value</i>. */
|
||||
qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1);
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, (const uint8_t *) "\r", 1);
|
||||
} else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
|
||||
if (value == 0xc0 || value == 0xc3) {
|
||||
/* Open channel <i>ch</i>. */
|
||||
} else if (value == 0x00)
|
||||
qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1);
|
||||
qemu_chr_fe_write_all(s->chr, (const uint8_t *) "\n", 1);
|
||||
else
|
||||
qemu_chr_fe_write(s->chr, &byte, 1);
|
||||
qemu_chr_fe_write_all(s->chr, &byte, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -1903,7 +1903,9 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
|
||||
else
|
||||
ch = ~value;
|
||||
if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */
|
||||
qemu_chr_fe_write(s->chr, &ch, 1);
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, &ch, 1);
|
||||
break;
|
||||
case ICSR0:
|
||||
s->status[0] &= ~(value & 0x66);
|
||||
|
||||
+3
-1
@@ -1108,7 +1108,9 @@ static void strongarm_uart_tx(void *opaque)
|
||||
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
|
||||
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
|
||||
} else if (s->chr) {
|
||||
qemu_chr_fe_write(s->chr, &s->tx_fifo[s->tx_start], 1);
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, &s->tx_fifo[s->tx_start], 1);
|
||||
}
|
||||
|
||||
s->tx_start = (s->tx_start + 1) % 8;
|
||||
|
||||
@@ -169,7 +169,9 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
/* "DLAB bit set means access baudrate register" is NYI */
|
||||
ch = value;
|
||||
if (s->chr) {
|
||||
qemu_chr_fe_write(s->chr, &ch, 1);
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, &ch, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+3
-1
@@ -60,7 +60,9 @@ static void debugcon_ioport_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
printf(" [debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02" PRIx64 "]\n", addr, val);
|
||||
#endif
|
||||
|
||||
qemu_chr_fe_write(s->chr, &ch, 1);
|
||||
/* XXX this blocks entire thread. Rewrite to use
|
||||
* qemu_chr_fe_write and background I/O callbacks */
|
||||
qemu_chr_fe_write_all(s->chr, &ch, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user